...

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  	"io/ioutil"
    27  	"os"
    28  	"path/filepath"
    29  	"strconv"
    30  	"strings"
    31  )
    32  
    33  // PIDFile is a file used to store the process ID of a running process.
    34  type PIDFile struct {
    35  	path string
    36  }
    37  
    38  func processExists(pid int) bool {
    39  	if _, err := os.Stat(filepath.Join("/proc", strconv.Itoa(pid))); err == nil {
    40  		return true
    41  	}
    42  	return false
    43  }
    44  
    45  func checkPIDFileAlreadyExists(path string) error {
    46  	if pidByte, err := ioutil.ReadFile(path); err == nil {
    47  		pidString := strings.TrimSpace(string(pidByte))
    48  		if pid, err := strconv.Atoi(pidString); err == nil {
    49  			if processExists(pid) {
    50  				return fmt.Errorf("pid file found, ensure docker is not running or delete %s", path)
    51  			}
    52  		}
    53  	}
    54  	return nil
    55  }
    56  
    57  // New creates a PIDfile using the specified path.
    58  func New(path string) (*PIDFile, error) {
    59  	if err := checkPIDFileAlreadyExists(path); err != nil {
    60  		return nil, err
    61  	}
    62  	// Note MkdirAll returns nil if a directory already exists
    63  	if err := os.MkdirAll(filepath.Dir(path), os.FileMode(0755)); err != nil {
    64  		return nil, err
    65  	}
    66  	if err := ioutil.WriteFile(path, []byte(fmt.Sprintf("%d", os.Getpid())), 0644); err != nil {
    67  		return nil, err
    68  	}
    69  
    70  	return &PIDFile{path: path}, nil
    71  }
    72  
    73  // Remove removes the PIDFile.
    74  func (file PIDFile) Remove() error {
    75  	return os.Remove(file.path)
    76  }
    77