Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kubeadm: fix crictl command for reset #55717

Merged
merged 1 commit into from Nov 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 24 additions & 4 deletions cmd/kubeadm/app/cmd/reset.go
Expand Up @@ -22,6 +22,7 @@ import (
"os"
"os/exec"
"path/filepath"
"strings"

"github.com/spf13/cobra"

Expand All @@ -34,7 +35,9 @@ import (
)

var (
crictlParamsFormat = "%s -r %s sandboxes --quiet | xargs -r %s -r %s rms"
crictlSandboxesParamsFormat = "%s -r %s sandboxes --quiet | xargs -r"
crictlStopParamsFormat = "%s -r %s stops %s"
crictlRemoveParamsFormat = "%s -r %s rms %s"
)

// NewCmdReset returns the "kubeadm reset" command
Expand Down Expand Up @@ -172,10 +175,27 @@ func resetWithDocker(execer utilsexec.Interface, dockerCheck preflight.Checker)
func resetWithCrictl(execer utilsexec.Interface, dockerCheck preflight.Checker, criSocketPath, crictlPath string) {
if criSocketPath != "" {
fmt.Printf("[reset] Cleaning up running containers using crictl with socket %s\n", criSocketPath)
cmd := fmt.Sprintf(crictlParamsFormat, crictlPath, criSocketPath, crictlPath, criSocketPath)
if err := execer.Command("sh", "-c", cmd).Run(); err != nil {
fmt.Println("[reset] Failed to stop the running containers using crictl. Trying using docker instead.")
listcmd := fmt.Sprintf(crictlSandboxesParamsFormat, crictlPath, criSocketPath)
output, err := execer.Command("sh", "-c", listcmd).CombinedOutput()
if err != nil {
fmt.Println("[reset] Failed to list running pods using crictl. Trying using docker instead.")
resetWithDocker(execer, dockerCheck)
return
}
sandboxes := strings.Split(string(output), " ")
for _, s := range sandboxes {
stopcmd := fmt.Sprintf(crictlStopParamsFormat, crictlPath, criSocketPath, s)
if err := execer.Command("sh", "-c", stopcmd).Run(); err != nil {
fmt.Println("[reset] Failed to stop the running containers using crictl. Trying using docker instead.")
resetWithDocker(execer, dockerCheck)
return
}
removecmd := fmt.Sprintf(crictlRemoveParamsFormat, crictlPath, criSocketPath, s)
if err := execer.Command("sh", "-c", removecmd).Run(); err != nil {
fmt.Println("[reset] Failed to remove the running containers using crictl. Trying using docker instead.")
resetWithDocker(execer, dockerCheck)
return
}
}
} else {
fmt.Println("[reset] CRI socket path not provided for crictl. Trying docker instead.")
Expand Down
50 changes: 39 additions & 11 deletions cmd/kubeadm/app/cmd/reset_test.go
Expand Up @@ -230,10 +230,21 @@ func TestResetWithDocker(t *testing.T) {

func TestResetWithCrictl(t *testing.T) {
fcmd := fakeexec.FakeCmd{
CombinedOutputScript: []fakeexec.FakeCombinedOutputAction{
// 2: socket path provided, not runnning with crictl (1x CombinedOutput, 2x Run)
func() ([]byte, error) { return []byte("1"), nil },
// 3: socket path provided, crictl fails, reset with docker (1x CombinedOuput fail, 1x Run)
func() ([]byte, error) { return nil, errors.New("crictl list err") },
},
RunScript: []fakeexec.FakeRunAction{
// 1: socket path not provided, running with docker
func() ([]byte, []byte, error) { return nil, nil, nil },
// 2: socket path provided, now runnning with crictl (1x CombinedOutput, 2x Run)
func() ([]byte, []byte, error) { return nil, nil, nil },
func() ([]byte, []byte, error) { return nil, nil, nil },
func() ([]byte, []byte, error) { return nil, nil, errors.New("crictl error") },
// 3: socket path provided, crictl fails, reset with docker (1x CombinedOuput, 1x Run)
func() ([]byte, []byte, error) { return nil, nil, nil },
// 4: running with no socket and docker fails (1x Run)
func() ([]byte, []byte, error) { return nil, nil, nil },
},
}
Expand All @@ -243,9 +254,13 @@ func TestResetWithCrictl(t *testing.T) {
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
},
}

// 1: socket path not provided, running with docker
resetWithCrictl(&fexec, newFakeDockerChecker(nil, nil), "", "crictl")
if fcmd.RunCalls != 1 {
t.Errorf("expected 1 call to Run, got %d", fcmd.RunCalls)
Expand All @@ -254,25 +269,28 @@ func TestResetWithCrictl(t *testing.T) {
t.Errorf("expected a call to docker, got %v", fcmd.RunLog[0])
}

// 2: socket path provided, now runnning with crictl (1x CombinedOutput, 2x Run)
resetWithCrictl(&fexec, newFakeDockerChecker(nil, nil), "/test.sock", "crictl")
if fcmd.RunCalls != 2 {
t.Errorf("expected 2 calls to Run, got %d", fcmd.RunCalls)
if fcmd.RunCalls != 3 {
t.Errorf("expected 3 calls to Run, got %d", fcmd.RunCalls)
}
if !strings.Contains(fcmd.RunLog[1][2], "crictl") {
t.Errorf("expected a call to crictl, got %v", fcmd.RunLog[0])
}
if !strings.Contains(fcmd.RunLog[2][2], "crictl") {
t.Errorf("expected a call to crictl, got %v", fcmd.RunLog[0])
}

// 3: socket path provided, crictl fails, reset with docker
resetWithCrictl(&fexec, newFakeDockerChecker(nil, nil), "/test.sock", "crictl")
if fcmd.RunCalls != 4 {
t.Errorf("expected 4 calls to Run, got %d", fcmd.RunCalls)
}
if !strings.Contains(fcmd.RunLog[2][2], "crictl") {
t.Errorf("expected a call to crictl, got %v", fcmd.RunLog[0])
}
if !strings.Contains(fcmd.RunLog[3][2], "docker") {
t.Errorf("expected a call to docker, got %v", fcmd.RunLog[0])
}

// 4: running with no socket and docker fails (1x Run)
resetWithCrictl(&fexec, newFakeDockerChecker(nil, []error{errors.New("test error")}), "", "crictl")
if fcmd.RunCalls != 4 {
t.Errorf("expected 4 calls to Run, got %d", fcmd.RunCalls)
Expand All @@ -281,33 +299,43 @@ func TestResetWithCrictl(t *testing.T) {

func TestReset(t *testing.T) {
fcmd := fakeexec.FakeCmd{
CombinedOutputScript: []fakeexec.FakeCombinedOutputAction{
func() ([]byte, error) { return []byte("1"), nil },
func() ([]byte, error) { return []byte("1"), nil },
func() ([]byte, error) { return []byte("1"), nil },
},
RunScript: []fakeexec.FakeRunAction{
func() ([]byte, []byte, error) { return nil, nil, nil },
func() ([]byte, []byte, error) { return nil, nil, nil },
func() ([]byte, []byte, error) { return nil, nil, nil },
},
}
fexec := fakeexec.FakeExec{
CommandScript: []fakeexec.FakeCommandAction{
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
},
LookPathFunc: func(cmd string) (string, error) { return cmd, nil },
}

reset(&fexec, newFakeDockerChecker(nil, nil), "/test.sock")
if fcmd.RunCalls != 1 {
t.Errorf("expected 1 call to Run, got %d", fcmd.RunCalls)
if fcmd.RunCalls != 2 {
t.Errorf("expected 2 call to Run, got %d", fcmd.RunCalls)
}
if !strings.Contains(fcmd.RunLog[0][2], "crictl") {
t.Errorf("expected a call to crictl, got %v", fcmd.RunLog[0])
}

fexec.LookPathFunc = func(cmd string) (string, error) { return "", errors.New("no crictl") }
reset(&fexec, newFakeDockerChecker(nil, nil), "/test.sock")
if fcmd.RunCalls != 2 {
t.Errorf("expected 2 calls to Run, got %d", fcmd.RunCalls)
if fcmd.RunCalls != 3 {
t.Errorf("expected 3 calls to Run, got %d", fcmd.RunCalls)
}
if !strings.Contains(fcmd.RunLog[1][2], "docker") {
if !strings.Contains(fcmd.RunLog[2][2], "docker") {
t.Errorf("expected a call to docker, got %v", fcmd.RunLog[0])
}
}