...

Source file src/github.com/chaos-mesh/chaos-mesh/pkg/pidfile/pidfile.go

Documentation: github.com/chaos-mesh/chaos-mesh/pkg/pidfile

     1  // Copyright 2021 Chaos Mesh Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  // http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  
    16  // Package pidfile provides structure and helper functions to create and remove
    17  // PID file. A PID file is usually a file used to store the process ID of a
    18  // running process.
    19  //
    20  // Copyright Moby
    21  // Licensed under the Apache License, Version 2.0 (the "License")
    22  package pidfile
    23  
    24  import (
    25  	"fmt"
    26  	"os"
    27  	"path/filepath"
    28  	"strconv"
    29  	"strings"
    30  
    31  	"github.com/pkg/errors"
    32  )
    33  
    34  // PIDFile is a file used to store the process ID of a running process.
    35  type PIDFile struct {
    36  	path string
    37  }
    38  
    39  func processExists(pid int) bool {
    40  	if _, err := os.Stat(filepath.Join("/proc", strconv.Itoa(pid))); err == nil {
    41  		return true
    42  	}
    43  	return false
    44  }
    45  
    46  func checkPIDFileAlreadyExists(path string) error {
    47  	if pidByte, err := os.ReadFile(path); err == nil {
    48  		pidString := strings.TrimSpace(string(pidByte))
    49  		if pid, err := strconv.Atoi(pidString); err == nil {
    50  			if processExists(pid) {
    51  				return errors.Errorf("pid file found, ensure docker is not running or delete %s", path)
    52  			}
    53  		}
    54  	}
    55  	return nil
    56  }
    57  
    58  // New creates a PIDfile using the specified path.
    59  func New(path string) (*PIDFile, error) {
    60  	if err := checkPIDFileAlreadyExists(path); err != nil {
    61  		return nil, err
    62  	}
    63  	// Note MkdirAll returns nil if a directory already exists
    64  	if err := os.MkdirAll(filepath.Dir(path), os.FileMode(0755)); err != nil {
    65  		return nil, err
    66  	}
    67  	if err := os.WriteFile(path, []byte(fmt.Sprintf("%d", os.Getpid())), 0644); err != nil {
    68  		return nil, err
    69  	}
    70  
    71  	return &PIDFile{path: path}, nil
    72  }
    73  
    74  // Remove removes the PIDFile.
    75  func (file PIDFile) Remove() error {
    76  	return os.Remove(file.path)
    77  }
    78