Merge pull request #30087 from dims/remove-pkill-dependency

Automatic merge from submit-queue

Remove kubelet pkill dependency

Issue #26093 identified pkill as one of the dependencies of kublet
which could be worked around.  Build on the code introduced for pidof
and regexp for the process(es) we need to send a signal to.

Related to #26093
pull/6/head
Kubernetes Submit Queue 2016-08-12 18:38:38 -07:00 committed by GitHub
commit 96655d7578
4 changed files with 69 additions and 5 deletions

View File

@ -527,7 +527,7 @@ func getPidsForProcess(name, pidFile string) ([]int, error) {
runtime.HandleError(err)
}
}
return procfs.PidOf(name), nil
return procfs.PidOf(name)
}
// Ensures that the Docker daemon is in the desired container.

View File

@ -27,6 +27,8 @@ import (
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/iptables"
"k8s.io/kubernetes/pkg/util/procfs"
"syscall"
)
var cidrRegexp = regexp.MustCompile(`inet ([0-9a-fA-F.:]*/[0-9]*)`)
@ -54,7 +56,7 @@ func createCBR0(wantCIDR *net.IPNet, babysitDaemons bool) error {
// For now just log the error. The containerRuntime check will catch docker failures.
// TODO (dawnchen) figure out what we should do for rkt here.
if babysitDaemons {
if err := exec.Command("pkill", "-KILL", "docker").Run(); err != nil {
if err := procfs.PKill("docker", syscall.SIGKILL); err != nil {
glog.Error(err)
}
} else if util.UsingSystemdInitSystem() {

View File

@ -23,11 +23,14 @@ import (
"os"
"path"
"path/filepath"
"regexp"
"strconv"
"strings"
"syscall"
"unicode"
"github.com/golang/glog"
utilerrors "k8s.io/kubernetes/pkg/util/errors"
)
type ProcFS struct{}
@ -62,7 +65,43 @@ func (pfs *ProcFS) GetFullContainerName(pid int) (string, error) {
return containerNameFromProcCgroup(string(content))
}
func PidOf(name string) []int {
// Find process(es) using a regular expression and send a specified
// signal to each process
func PKill(name string, sig syscall.Signal) error {
if len(name) == 0 {
return fmt.Errorf("name should not be empty")
}
re, err := regexp.Compile(name)
if err != nil {
return err
}
pids := getPids(re)
if len(pids) == 0 {
return fmt.Errorf("unable to fetch pids for process name : %q", name)
}
errList := []error{}
for _, pid := range pids {
if err = syscall.Kill(pid, sig); err != nil {
errList = append(errList, err)
}
}
return utilerrors.NewAggregate(errList)
}
// Find process(es) with a specified name (exact match)
// and return their pid(s)
func PidOf(name string) ([]int, error) {
if len(name) == 0 {
return []int{}, fmt.Errorf("name should not be empty")
}
re, err := regexp.Compile("(^|/)" + name + "$")
if err != nil {
return []int{}, err
}
return getPids(re), nil
}
func getPids(re *regexp.Regexp) []int {
pids := []int{}
filepath.Walk("/proc", func(path string, info os.FileInfo, err error) error {
if err != nil {
@ -98,7 +137,7 @@ func PidOf(name string) []int {
return nil
}
// Check if the name of the executable is what we are looking for
if filepath.Base(exe[0]) == name {
if re.MatchString(exe[0]) {
dirname := filepath.Base(filepath.Dir(path))
// Grab the PID from the directory path
pid, _ := strconv.Atoi(dirname)

View File

@ -19,9 +19,12 @@ package procfs
import (
"io/ioutil"
"os"
"os/signal"
"path/filepath"
"runtime"
"syscall"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
@ -66,7 +69,27 @@ 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]))
pids, err := PidOf(filepath.Base(os.Args[0]))
assert.Empty(t, err)
assert.NotZero(t, pids)
assert.Contains(t, pids, os.Getpid())
}
func TestPKill(t *testing.T) {
if runtime.GOOS == "darwin" || runtime.GOOS == "windows" {
t.Skipf("not supported on GOOS=%s", runtime.GOOS)
}
sig := syscall.SIGCONT
c := make(chan os.Signal, 1)
signal.Notify(c, sig)
defer signal.Stop(c)
PKill(os.Args[0], sig)
select {
case s := <-c:
if s != sig {
t.Fatalf("signal was %v, want %v", s, sig)
}
case <-time.After(1 * time.Second):
t.Fatalf("timeout waiting for %v", sig)
}
}