...

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

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

     1  // Copyright 2019 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  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  // Package pidfile provides structure and helper functions to create and remove
    15  // PID file. A PID file is usually a file used to store the process ID of a
    16  // running process.
    17  //
    18  // Copyright Moby
    19  // Licensed under the Apache License, Version 2.0 (the "License")
    20  package pidfile
    21  
    22  import (
    23  	"fmt"
    24  	"io/ioutil"
    25  	"os"
    26  	"path/filepath"
    27  	"strconv"
    28  	"strings"
    29  )
    30  
    31  // PIDFile is a file used to store the process ID of a running process.
    32  type PIDFile struct {
    33  	path string
    34  }
    35  
    36  func processExists(pid int) bool {
    37  	if _, err := os.Stat(filepath.Join("/proc", strconv.Itoa(pid))); err == nil {
    38  		return true
    39  	}
    40  	return false
    41  }
    42  
    43  func checkPIDFileAlreadyExists(path string) error {
    44  	if pidByte, err := ioutil.ReadFile(path); err == nil {
    45  		pidString := strings.TrimSpace(string(pidByte))
    46  		if pid, err := strconv.Atoi(pidString); err == nil {
    47  			if processExists(pid) {
    48  				return fmt.Errorf("pid file found, ensure docker is not running or delete %s", path)
    49  			}
    50  		}
    51  	}
    52  	return nil
    53  }
    54  
    55  // New creates a PIDfile using the specified path.
    56  func New(path string) (*PIDFile, error) {
    57  	if err := checkPIDFileAlreadyExists(path); err != nil {
    58  		return nil, err
    59  	}
    60  	// Note MkdirAll returns nil if a directory already exists
    61  	if err := os.MkdirAll(filepath.Dir(path), os.FileMode(0755)); err != nil {
    62  		return nil, err
    63  	}
    64  	if err := ioutil.WriteFile(path, []byte(fmt.Sprintf("%d", os.Getpid())), 0644); err != nil {
    65  		return nil, err
    66  	}
    67  
    68  	return &PIDFile{path: path}, nil
    69  }
    70  
    71  // Remove removes the PIDFile.
    72  func (file PIDFile) Remove() error {
    73  	return os.Remove(file.path)
    74  }
    75