Remove kubelet dependency on pidof
Issue #26093 identified pidof as one of the dependencies of kublet which could be worked around. In this PR, we just look at /proc to construct the list of pids we need for a specified process instead of running "pidof" executable Related to #26093
This commit is contained in:
@@ -17,12 +17,17 @@ limitations under the License.
|
||||
package procfs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
type ProcFS struct{}
|
||||
@@ -56,3 +61,46 @@ func (pfs *ProcFS) GetFullContainerName(pid int) (string, error) {
|
||||
}
|
||||
return containerNameFromProcCgroup(string(content))
|
||||
}
|
||||
|
||||
func PidOf(name string) []int {
|
||||
pids := []int{}
|
||||
filepath.Walk("/proc", func(path string, info os.FileInfo, err error) error {
|
||||
base := filepath.Base(path)
|
||||
// Traverse only the directories we are interested in
|
||||
if info.IsDir() && path != "/proc" {
|
||||
// If the directory is not a number (i.e. not a PID), skip it
|
||||
if _, err := strconv.Atoi(base); err != nil {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
}
|
||||
if base != "cmdline" {
|
||||
return nil
|
||||
}
|
||||
cmdline, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
glog.V(4).Infof("Error reading file %s: %+v", path, err)
|
||||
return nil
|
||||
}
|
||||
// The bytes we read have '\0' as a separator for the command line
|
||||
parts := bytes.SplitN(cmdline, []byte{0}, 2)
|
||||
if len(parts) == 0 {
|
||||
return nil
|
||||
}
|
||||
// Split the command line itself we are interested in just the first part
|
||||
exe := strings.FieldsFunc(string(parts[0]), func(c rune) bool {
|
||||
return unicode.IsSpace(c) || c == ':'
|
||||
})
|
||||
if len(exe) == 0 {
|
||||
return nil
|
||||
}
|
||||
// Check if the name of the executable is what we are looking for
|
||||
if filepath.Base(exe[0]) == name {
|
||||
dirname := filepath.Base(filepath.Dir(path))
|
||||
// Grab the PID from the directory path
|
||||
pid, _ := strconv.Atoi(dirname)
|
||||
pids = append(pids, pid)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return pids
|
||||
}
|
||||
|
@@ -18,7 +18,12 @@ package procfs
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func verifyContainerName(procCgroupText, expectedName string, expectedErr bool, t *testing.T) {
|
||||
@@ -56,3 +61,12 @@ func TestContainerNameFromProcCgroup(t *testing.T) {
|
||||
procCgroupInvalid := "devices:docker/kubelet\ncpuacct:pkg/kubectl"
|
||||
verifyContainerName(procCgroupInvalid, "", true, t)
|
||||
}
|
||||
|
||||
func TestPidOf(t *testing.T) {
|
||||
if runtime.GOOS == "darwin" || runtime.GOOS == "windows" {
|
||||
t.Skipf("not supported on GOOS=%s", runtime.GOOS)
|
||||
}
|
||||
pids := PidOf(filepath.Base(os.Args[0]))
|
||||
assert.NotZero(t, pids)
|
||||
assert.Contains(t, pids, os.Getpid())
|
||||
}
|
||||
|
Reference in New Issue
Block a user