From 809389c8d650fe41978cace70350090b2e82657d Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Wed, 2 Oct 2019 14:29:14 -0700 Subject: [PATCH 01/59] implementing new interface RunCmd for exec_runner & fake_runner --- pkg/minikube/command/command_runner.go | 40 ++++++++++++++++++++++++++ pkg/minikube/command/exec_runner.go | 26 +++++++++++++++++ pkg/minikube/command/fake_runner.go | 26 +++++++++++++++++ 3 files changed, 92 insertions(+) diff --git a/pkg/minikube/command/command_runner.go b/pkg/minikube/command/command_runner.go index 57f250b0cab3..20fab53ff7e4 100644 --- a/pkg/minikube/command/command_runner.go +++ b/pkg/minikube/command/command_runner.go @@ -17,15 +17,29 @@ limitations under the License. package command import ( + "bytes" "fmt" "io" + "os/exec" "path" + "strings" "k8s.io/minikube/pkg/minikube/assets" ) +type RunResult struct { + Stdout *bytes.Buffer + Stderr *bytes.Buffer + ExitCode int + Args []string +} + // Runner represents an interface to run commands. type Runner interface { + // RunCmd is a new expermintal way to run commands, takes Cmd interface and returns run result. + // if succesfull will cause a clean up to get rid of older methods. + RunCmd(cmd *exec.Cmd) (*RunResult, error) + // Run starts the specified command and waits for it to complete. Run(cmd string) error @@ -56,3 +70,29 @@ type Runner interface { func getDeleteFileCommand(f assets.CopyableFile) string { return fmt.Sprintf("sudo rm %s", path.Join(f.GetTargetDir(), f.GetTargetName())) } + +// Command returns a human readable command string that does not induce eye fatigue +func (rr RunResult) Command() string { + var sb strings.Builder + sb.WriteString(strings.TrimPrefix(rr.Args[0], "../../")) + for _, a := range rr.Args[1:] { + if strings.Contains(a, " ") { + sb.WriteString(fmt.Sprintf(` "%s"`, a)) + continue + } + sb.WriteString(fmt.Sprintf(" %s", a)) + } + return sb.String() +} + +// Output returns human-readable output for an execution result +func (rr RunResult) Output() string { + var sb strings.Builder + if rr.Stdout.Len() > 0 { + sb.WriteString(fmt.Sprintf("-- stdout --\n%s\n-- /stdout --", rr.Stdout.Bytes())) + } + if rr.Stderr.Len() > 0 { + sb.WriteString(fmt.Sprintf("\n** stderr ** \n%s\n** /stderr **", rr.Stderr.Bytes())) + } + return sb.String() +} diff --git a/pkg/minikube/command/exec_runner.go b/pkg/minikube/command/exec_runner.go index 84891597e74c..cea3743f85fa 100644 --- a/pkg/minikube/command/exec_runner.go +++ b/pkg/minikube/command/exec_runner.go @@ -24,6 +24,7 @@ import ( "path" "path/filepath" "strconv" + "time" "github.com/golang/glog" "github.com/pkg/errors" @@ -35,6 +36,31 @@ import ( // It implements the CommandRunner interface. type ExecRunner struct{} +// RunCmd implements the Command Runner interface to run a exec.Cmd object +func (*ExecRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { + rr := &RunResult{Args: cmd.Args} + glog.Infof("(ExecRunner) Run: %v", rr.Command()) + + var outb, errb bytes.Buffer + cmd.Stdout, rr.Stdout = &outb, &outb + cmd.Stderr, rr.Stderr = &errb, &errb + start := time.Now() + err := cmd.Run() + elapsed := time.Since(start) + if err == nil { + // Reduce log spam + if elapsed > (1 * time.Second) { + glog.Infof("(ExecRunner) Done: %v: (%s)", rr.Command(), elapsed) + } + } else { + if exitError, ok := err.(*exec.ExitError); ok { + rr.ExitCode = exitError.ExitCode() + } + glog.Infof("(ExecRunner) Non-zero exit: %v: %v (%s)\n%s", rr.Command(), err, elapsed, rr.Output()) + } + return rr, err +} + // Run starts the specified command in a bash shell and waits for it to complete. func (*ExecRunner) Run(cmd string) error { glog.Infoln("Run:", cmd) diff --git a/pkg/minikube/command/fake_runner.go b/pkg/minikube/command/fake_runner.go index 029000cdc80b..be858957c0aa 100644 --- a/pkg/minikube/command/fake_runner.go +++ b/pkg/minikube/command/fake_runner.go @@ -20,9 +20,12 @@ import ( "bytes" "fmt" "io" + "os/exec" + "time" "golang.org/x/sync/syncmap" + "github.com/golang/glog" "github.com/pkg/errors" "k8s.io/minikube/pkg/minikube/assets" @@ -43,6 +46,29 @@ func NewFakeCommandRunner() *FakeCommandRunner { return &FakeCommandRunner{} } +// RunCmd implements the Command Runner interface to run a exec.Cmd object +func (f *FakeCommandRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { + rr := &RunResult{Args: cmd.Args} + glog.Infof("(FakeCommandRunner) Run: %v", rr.Command()) + + start := time.Now() + + out, ok := f.cmdMap.Load(cmd.Args) + rr.Stderr = bytes.NewBuffer([]byte(out.(string))) // converting fake output string to a buffer + + elapsed := time.Since(start) + if ok { + // Reduce log spam + if elapsed > (1 * time.Second) { + glog.Infof("(FakeCommandRunner) Done: %v: (%s)", rr.Command(), elapsed) + } + } else { + glog.Infof("(FakeCommandRunner) Non-zero exit: %v: (%s)\n%s", rr.Command(), elapsed, rr.Output()) + return rr, fmt.Errorf("unavailable command: %s", cmd) + } + return rr, nil +} + // Run returns nil if output has been set for the given command text. func (f *FakeCommandRunner) Run(cmd string) error { _, err := f.CombinedOutput(cmd) From 88183240ca63927d47c9b3567de590c8cbb9f029 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Wed, 2 Oct 2019 15:09:42 -0700 Subject: [PATCH 02/59] move teePrefix from util to ssh_runner --- pkg/minikube/command/ssh_runner.go | 33 ++++++++++++++++++++++++++++-- pkg/util/utils.go | 29 -------------------------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/pkg/minikube/command/ssh_runner.go b/pkg/minikube/command/ssh_runner.go index 01fd780e970a..9117d7cabf70 100644 --- a/pkg/minikube/command/ssh_runner.go +++ b/pkg/minikube/command/ssh_runner.go @@ -17,6 +17,7 @@ limitations under the License. package command import ( + "bufio" "bytes" "fmt" "io" @@ -81,13 +82,13 @@ func teeSSH(s *ssh.Session, cmd string, outB io.Writer, errB io.Writer) error { wg.Add(2) go func() { - if err := util.TeePrefix(util.ErrPrefix, errPipe, errB, glog.V(8).Infof); err != nil { + if err := teePrefix(util.ErrPrefix, errPipe, errB, glog.V(8).Infof); err != nil { glog.Errorf("tee stderr: %v", err) } wg.Done() }() go func() { - if err := util.TeePrefix(util.OutPrefix, outPipe, outB, glog.V(8).Infof); err != nil { + if err := teePrefix(util.OutPrefix, outPipe, outB, glog.V(8).Infof); err != nil { glog.Errorf("tee stdout: %v", err) } wg.Done() @@ -198,3 +199,31 @@ func (s *SSHRunner) Copy(f assets.CopyableFile) error { } return g.Wait() } + +// teePrefix copies bytes from a reader to writer, logging each new line. +func teePrefix(prefix string, r io.Reader, w io.Writer, logger func(format string, args ...interface{})) error { + scanner := bufio.NewScanner(r) + scanner.Split(bufio.ScanBytes) + var line bytes.Buffer + + for scanner.Scan() { + b := scanner.Bytes() + if _, err := w.Write(b); err != nil { + return err + } + + if bytes.IndexAny(b, "\r\n") == 0 { + if line.Len() > 0 { + logger("%s%s", prefix, line.String()) + line.Reset() + } + continue + } + line.Write(b) + } + // Catch trailing output in case stream does not end with a newline + if line.Len() > 0 { + logger("%s%s", prefix, line.String()) + } + return nil +} diff --git a/pkg/util/utils.go b/pkg/util/utils.go index c549ca4ebe44..b9d53b1e7600 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -17,7 +17,6 @@ limitations under the License. package util import ( - "bufio" "bytes" "fmt" "io" @@ -150,34 +149,6 @@ func MaybeChownDirRecursiveToMinikubeUser(dir string) error { return nil } -// TeePrefix copies bytes from a reader to writer, logging each new line. -func TeePrefix(prefix string, r io.Reader, w io.Writer, logger func(format string, args ...interface{})) error { - scanner := bufio.NewScanner(r) - scanner.Split(bufio.ScanBytes) - var line bytes.Buffer - - for scanner.Scan() { - b := scanner.Bytes() - if _, err := w.Write(b); err != nil { - return err - } - - if bytes.IndexAny(b, "\r\n") == 0 { - if line.Len() > 0 { - logger("%s%s", prefix, line.String()) - line.Reset() - } - continue - } - line.Write(b) - } - // Catch trailing output in case stream does not end with a newline - if line.Len() > 0 { - logger("%s%s", prefix, line.String()) - } - return nil -} - // ReplaceChars returns a copy of the src slice with each string modified by the replacer func ReplaceChars(src []string, replacer *strings.Replacer) []string { ret := make([]string, len(src)) From eaa01716ead5cb4e71b396c3ebe3bd2651152edc Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Wed, 2 Oct 2019 15:56:21 -0700 Subject: [PATCH 03/59] move unit tests from util to command_runner --- pkg/minikube/command/ssh_runner.go | 42 +++++++++++++++++ pkg/minikube/command/ssh_runner_test.go | 63 +++++++++++++++++++++++++ pkg/util/utils_test.go | 41 ---------------- 3 files changed, 105 insertions(+), 41 deletions(-) create mode 100644 pkg/minikube/command/ssh_runner_test.go diff --git a/pkg/minikube/command/ssh_runner.go b/pkg/minikube/command/ssh_runner.go index 9117d7cabf70..537ad6c66331 100644 --- a/pkg/minikube/command/ssh_runner.go +++ b/pkg/minikube/command/ssh_runner.go @@ -21,8 +21,11 @@ import ( "bytes" "fmt" "io" + "os/exec" "path" + "strings" "sync" + "time" "github.com/golang/glog" "github.com/pkg/errors" @@ -98,6 +101,45 @@ func teeSSH(s *ssh.Session, cmd string, outB io.Writer, errB io.Writer) error { return err } +// RunCmd implements the Command Runner interface to run a exec.Cmd object +func (s *SSHRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { + rr := &RunResult{Args: cmd.Args} + glog.Infof("(SSHRunner) Run: %v", rr.Command()) + + var outb, errb bytes.Buffer + cmd.Stdout, rr.Stdout = &outb, &outb + cmd.Stderr, rr.Stderr = &errb, &errb + start := time.Now() + + sess, err := s.c.NewSession() + if err != nil { + return rr, errors.Wrap(err, "NewSession") + } + + defer func() { + if err := sess.Close(); err != nil { + if err != io.EOF { + glog.Errorf("session close: %v", err) + } + } + }() + + elapsed := time.Since(start) + err = teeSSH(sess, strings.Join(cmd.Args, " "), &outb, &errb) + if err == nil { + // Reduce log spam + if elapsed > (1 * time.Second) { + glog.Infof("(SSHRunner) Done: %v: (%s)", rr.Command(), elapsed) + } + } else { + if exitError, ok := err.(*exec.ExitError); ok { + rr.ExitCode = exitError.ExitCode() + } + glog.Infof("(SSHRunner) Non-zero exit: %v: %v (%s)\n%s", rr.Command(), err, elapsed, rr.Output()) + } + return rr, err +} + // Run starts a command on the remote and waits for it to return. func (s *SSHRunner) Run(cmd string) error { glog.Infof("SSH: %s", cmd) diff --git a/pkg/minikube/command/ssh_runner_test.go b/pkg/minikube/command/ssh_runner_test.go new file mode 100644 index 000000000000..df9e7d509e60 --- /dev/null +++ b/pkg/minikube/command/ssh_runner_test.go @@ -0,0 +1,63 @@ +/* +Copyright 2019 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package command + +import ( + "bytes" + "fmt" + "strings" + "sync" + "testing" +) + +func TestTeePrefix(t *testing.T) { + var in bytes.Buffer + var out bytes.Buffer + var logged strings.Builder + + logSink := func(format string, args ...interface{}) { + logged.WriteString("(" + fmt.Sprintf(format, args...) + ")") + } + + // Simulate the primary use case: tee in the background. This also helps avoid I/O races. + var wg sync.WaitGroup + wg.Add(1) + go func() { + if err := teePrefix(":", &in, &out, logSink); err != nil { + t.Errorf("teePrefix: %v", err) + } + wg.Done() + }() + + in.Write([]byte("goo")) + in.Write([]byte("\n")) + in.Write([]byte("g\r\n\r\n")) + in.Write([]byte("le")) + wg.Wait() + + gotBytes := out.Bytes() + wantBytes := []byte("goo\ng\r\n\r\nle") + if !bytes.Equal(gotBytes, wantBytes) { + t.Errorf("output=%q, want: %q", gotBytes, wantBytes) + } + + gotLog := logged.String() + wantLog := "(:goo)(:g)(:le)" + if gotLog != wantLog { + t.Errorf("log=%q, want: %q", gotLog, wantLog) + } +} diff --git a/pkg/util/utils_test.go b/pkg/util/utils_test.go index 4fc94ce7bc59..26a10724a482 100644 --- a/pkg/util/utils_test.go +++ b/pkg/util/utils_test.go @@ -17,10 +17,7 @@ limitations under the License. package util import ( - "bytes" - "fmt" "strings" - "sync" "testing" ) @@ -44,44 +41,6 @@ func TestGetBinaryDownloadURL(t *testing.T) { } -func TestTeePrefix(t *testing.T) { - var in bytes.Buffer - var out bytes.Buffer - var logged strings.Builder - - logSink := func(format string, args ...interface{}) { - logged.WriteString("(" + fmt.Sprintf(format, args...) + ")") - } - - // Simulate the primary use case: tee in the background. This also helps avoid I/O races. - var wg sync.WaitGroup - wg.Add(1) - go func() { - if err := TeePrefix(":", &in, &out, logSink); err != nil { - t.Errorf("TeePrefix: %v", err) - } - wg.Done() - }() - - in.Write([]byte("goo")) - in.Write([]byte("\n")) - in.Write([]byte("g\r\n\r\n")) - in.Write([]byte("le")) - wg.Wait() - - gotBytes := out.Bytes() - wantBytes := []byte("goo\ng\r\n\r\nle") - if !bytes.Equal(gotBytes, wantBytes) { - t.Errorf("output=%q, want: %q", gotBytes, wantBytes) - } - - gotLog := logged.String() - wantLog := "(:goo)(:g)(:le)" - if gotLog != wantLog { - t.Errorf("log=%q, want: %q", gotLog, wantLog) - } -} - func TestReplaceChars(t *testing.T) { testData := []struct { src []string From 2f276e27ef713dbbb43c034277ed54b59bc39e08 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 3 Oct 2019 15:39:48 -0700 Subject: [PATCH 04/59] fix format type --- pkg/minikube/command/fake_runner.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/minikube/command/fake_runner.go b/pkg/minikube/command/fake_runner.go index be858957c0aa..b4e5a4d34e59 100644 --- a/pkg/minikube/command/fake_runner.go +++ b/pkg/minikube/command/fake_runner.go @@ -21,6 +21,7 @@ import ( "fmt" "io" "os/exec" + "strings" "time" "golang.org/x/sync/syncmap" @@ -64,7 +65,7 @@ func (f *FakeCommandRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { } } else { glog.Infof("(FakeCommandRunner) Non-zero exit: %v: (%s)\n%s", rr.Command(), elapsed, rr.Output()) - return rr, fmt.Errorf("unavailable command: %s", cmd) + return rr, fmt.Errorf("unavailable command: %s", strings.Join(cmd.Args, " ")) } return rr, nil } From 27321d5f335e5cac3a531f302650497bed1807ad Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Fri, 4 Oct 2019 10:55:51 -0700 Subject: [PATCH 05/59] add ExecCmd and convert kubeadm,cert to new interface --- pkg/minikube/bootstrapper/certs.go | 27 +++--- pkg/minikube/bootstrapper/kubeadm/kubeadm.go | 87 ++++++++++++-------- pkg/minikube/command/exec_runner.go | 5 ++ 3 files changed, 72 insertions(+), 47 deletions(-) diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index e5d2edd18ca6..6545c5d366f1 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -330,9 +330,10 @@ func getSubjectHash(cmd command.Runner, filePath string) (string, error) { // configureCACerts looks up and installs all uploaded PEM certificates in /usr/share/ca-certificates to system-wide certificate store (/etc/ssl/certs). // OpenSSL binary required in minikube ISO -func configureCACerts(cmd command.Runner, caCerts map[string]string) error { +func configureCACerts(cr command.Runner, caCerts map[string]string) error { hasSSLBinary := true - if err := cmd.Run("which openssl"); err != nil { + _, err := cr.RunCmd(command.ExecCmd("which openssl")) + if err != nil { hasSSLBinary = false } @@ -343,24 +344,28 @@ func configureCACerts(cmd command.Runner, caCerts map[string]string) error { for _, caCertFile := range caCerts { dstFilename := path.Base(caCertFile) certStorePath := path.Join(SSLCertStoreDir, dstFilename) - if err := cmd.Run(fmt.Sprintf("sudo test -f '%s'", certStorePath)); err != nil { - if err := cmd.Run(fmt.Sprintf("sudo ln -s '%s' '%s'", caCertFile, certStorePath)); err != nil { - return errors.Wrapf(err, "error making symbol link for certificate %s", caCertFile) + + cmd := command.ExecCmd(fmt.Sprintf("sudo test -f '%s'", certStorePath)) + _, err := cr.RunCmd(cmd) + if err != nil { + cmd = command.ExecCmd(fmt.Sprintf("sudo ln -s '%s' '%s'", caCertFile, certStorePath)) + rr, err := cr.RunCmd(cmd) + if err != nil { + return errors.Wrapf(err, "error making symbol link for certificate %s : %q", caCertFile, rr.Output()) } } if hasSSLBinary { - subjectHash, err := getSubjectHash(cmd, caCertFile) + subjectHash, err := getSubjectHash(cr, caCertFile) if err != nil { return errors.Wrapf(err, "error calculating subject hash for certificate %s", caCertFile) } subjectHashLink := path.Join(SSLCertStoreDir, fmt.Sprintf("%s.0", subjectHash)) - if err := cmd.Run(fmt.Sprintf("sudo test -f '%s'", subjectHashLink)); err != nil { - if err := cmd.Run(fmt.Sprintf("sudo ln -s '%s' '%s'", certStorePath, subjectHashLink)); err != nil { - return errors.Wrapf(err, "error making subject hash symbol link for certificate %s", caCertFile) - } + cmd = command.ExecCmd(fmt.Sprintf("sudo test -f '%s'", subjectHashLink)) + rr, err := cr.RunCmd(cmd) + if err != nil { + return errors.Wrapf(err, "error making subject hash symbol link for certificate %s, %q", caCertFile, rr.Output()) } } } - return nil } diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index faa391e3714c..3de10157990a 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -136,12 +136,12 @@ func NewKubeadmBootstrapper(api libmachine.API) (*Bootstrapper, error) { // GetKubeletStatus returns the kubelet status func (k *Bootstrapper) GetKubeletStatus() (string, error) { - statusCmd := `sudo systemctl is-active kubelet` - status, err := k.c.CombinedOutput(statusCmd) + cmd := command.ExecCmd("sudo systemctl is-active kubelet") + rr, err := k.c.RunCmd(cmd) if err != nil { - return "", errors.Wrap(err, "getting status") + return "", errors.Wrapf(err, "getting kublet status. command: %q output: %q", rr.Command(), rr.Output()) } - s := strings.TrimSpace(status) + s := strings.TrimSpace(rr.Stdout.String() + rr.Stderr.String()) switch s { case "active": return state.Running.String(), nil @@ -222,16 +222,19 @@ func etcdDataDir() string { // createCompatSymlinks creates compatibility symlinks to transition running services to new directory structures func (k *Bootstrapper) createCompatSymlinks() error { legacyEtcd := "/data/minikube" - if err := k.c.Run(fmt.Sprintf("sudo test -d %s", legacyEtcd)); err != nil { - glog.Infof("%s check failed, skipping compat symlinks: %v", legacyEtcd, err) + cmd := command.ExecCmd(fmt.Sprintf("sudo test -d %s", legacyEtcd)) + rr, err := k.c.RunCmd(cmd) + if err != nil { + glog.Infof("%s check failed, skipping compat symlinks: %v %q", legacyEtcd, err, rr.Output()) return nil } glog.Infof("Found %s, creating compatibility symlinks ...", legacyEtcd) - cmd := fmt.Sprintf("sudo ln -s %s %s", legacyEtcd, etcdDataDir()) - out, err := k.c.CombinedOutput(cmd) + + cmd = command.ExecCmd(fmt.Sprintf("sudo ln -s %s %s", legacyEtcd, etcdDataDir())) + rr, err = k.c.RunCmd(cmd) if err != nil { - return errors.Wrapf(err, "cmd failed: %s\n%s\n", cmd, out) + return errors.Wrapf(err, "create symlink failed: %s\n%q\n", rr.Command(), rr.Output()) } return nil } @@ -273,11 +276,11 @@ func (k *Bootstrapper) StartCluster(k8s config.KubernetesConfig) error { ignore = append(ignore, "SystemVerification") } - cmd := fmt.Sprintf("%s init --config %s %s --ignore-preflight-errors=%s", + c := fmt.Sprintf("%s init --config %s %s --ignore-preflight-errors=%s", invokeKubeadm(k8s.KubernetesVersion), yamlConfigPath, extraFlags, strings.Join(ignore, ",")) - out, err := k.c.CombinedOutput(cmd) + rr, err := k.c.RunCmd(command.ExecCmd(c)) if err != nil { - return errors.Wrapf(err, "cmd failed: %s\n%s\n", cmd, out) + return errors.Wrapf(err, "init failed. cmd: %q\noutput:%q\n", rr.Command(), rr.Output()) } glog.Infof("Configuring cluster permissions ...") @@ -302,22 +305,25 @@ func (k *Bootstrapper) StartCluster(k8s config.KubernetesConfig) error { // adjustResourceLimits makes fine adjustments to pod resources that aren't possible via kubeadm config. func (k *Bootstrapper) adjustResourceLimits() error { - score, err := k.c.CombinedOutput("cat /proc/$(pgrep kube-apiserver)/oom_adj") + rr, err := k.c.RunCmd(command.ExecCmd("cat /proc/$(pgrep kube-apiserver)/oom_adj")) if err != nil { - return errors.Wrap(err, "oom_adj check") + return errors.Wrap(err, "oom_adj check. command: %q output: %q") } - glog.Infof("apiserver oom_adj: %s", score) + glog.Infof("apiserver oom_adj: %s", rr.Stdout.String()) // oom_adj is already a negative number - if strings.HasPrefix(score, "-") { + if strings.HasPrefix(rr.Stdout.String(), "-") { return nil } glog.Infof("adjusting apiserver oom_adj to -10") + cmd := command.ExecCmd("echo -10 | sudo tee /proc/$(pgrep kube-apiserver)/oom_adj") // Prevent the apiserver from OOM'ing before other pods, as it is our gateway into the cluster. // It'd be preferable to do this via Kubernetes, but kubeadm doesn't have a way to set pod QoS. - if err := k.c.Run("echo -10 | sudo tee /proc/$(pgrep kube-apiserver)/oom_adj"); err != nil { - return errors.Wrap(err, "oom_adj adjust") + rr, err = k.c.RunCmd(cmd) + if err != nil { + return errors.Wrap(err, fmt.Sprintf("oom_adj adjust: %s", rr.Output())) } + return nil } @@ -434,9 +440,11 @@ func (k *Bootstrapper) RestartCluster(k8s config.KubernetesConfig) error { } // Run commands one at a time so that it is easier to root cause failures. - for _, cmd := range cmds { - if err := k.c.Run(cmd); err != nil { - return errors.Wrapf(err, "running cmd: %s", cmd) + for _, c := range cmds { + cmd := command.ExecCmd(c) + rr, err := k.c.RunCmd(cmd) + if err != nil { + return errors.Wrapf(err, "running cmd: %s , output: %s", rr.Command(), rr.Output()) } } @@ -444,8 +452,11 @@ func (k *Bootstrapper) RestartCluster(k8s config.KubernetesConfig) error { return errors.Wrap(err, "waiting for apiserver") } // restart the proxy and coredns - if err := k.c.Run(fmt.Sprintf("%s phase addon all --config %s", baseCmd, yamlConfigPath)); err != nil { - return errors.Wrapf(err, "addon phase") + + cmd := command.ExecCmd(fmt.Sprintf("%s phase addon all --config %s", baseCmd, yamlConfigPath)) + rr, err := k.c.RunCmd(cmd) + if err != nil { + return errors.Wrapf(err, fmt.Sprintf("addon phase cmd:%q output:%q", rr.Command(), rr.Output())) } if err := k.adjustResourceLimits(); err != nil { @@ -465,9 +476,10 @@ func (k *Bootstrapper) waitForAPIServer(k8s config.KubernetesConfig) error { // To give a better error message, first check for process existence via ssh // Needs minutes in case the image isn't cached (such as with v1.10.x) err := wait.PollImmediate(time.Millisecond*300, time.Minute*3, func() (bool, error) { - ierr := k.c.Run(`sudo pgrep kube-apiserver`) + cmd := command.ExecCmd("sudo pgrep kube-apiserver") + rr, ierr := k.c.RunCmd(cmd) if ierr != nil { - glog.Warningf("pgrep apiserver: %v", ierr) + glog.Warningf("pgrep apiserver: %v cmd: %s output: %s", ierr, rr.Command(), rr.Output()) return false, nil } return true, nil @@ -504,13 +516,14 @@ func (k *Bootstrapper) DeleteCluster(k8s config.KubernetesConfig) error { return errors.Wrap(err, "parsing kubernetes version") } - cmd := fmt.Sprintf("%s reset --force", invokeKubeadm(k8s.KubernetesVersion)) + c := fmt.Sprintf("%s reset --force", invokeKubeadm(k8s.KubernetesVersion)) if version.LT(semver.MustParse("1.11.0")) { - cmd = fmt.Sprintf("%s reset", invokeKubeadm(k8s.KubernetesVersion)) + c = fmt.Sprintf("%s reset", invokeKubeadm(k8s.KubernetesVersion)) } - out, err := k.c.CombinedOutput(cmd) + + rr, err := k.c.RunCmd(command.ExecCmd(c)) if err != nil { - return errors.Wrapf(err, "kubeadm reset: %s\n%s\n", cmd, out) + return errors.Wrapf(err, "kubeadm reset: cmd: %q\noutput:%q\n", rr.Command(), rr.Output()) } return nil @@ -526,9 +539,10 @@ func (k *Bootstrapper) PullImages(k8s config.KubernetesConfig) error { return fmt.Errorf("pull command is not supported by kubeadm v%s", version) } - cmd := fmt.Sprintf("%s config images pull --config %s", invokeKubeadm(k8s.KubernetesVersion), yamlConfigPath) - if err := k.c.Run(cmd); err != nil { - return errors.Wrapf(err, "running cmd: %s", cmd) + cmd := command.ExecCmd(fmt.Sprintf("%s config images pull --config %s", invokeKubeadm(k8s.KubernetesVersion), yamlConfigPath)) + rr, err := k.c.RunCmd(cmd) + if err != nil { + return errors.Wrapf(err, "running cmd: %q output: %q", rr.Command(), rr.Output()) } return nil } @@ -623,9 +637,9 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error { glog.Infof("kubelet %s config:\n%s", cfg.KubernetesVersion, kubeletCfg) // stop kubelet to avoid "Text File Busy" error - err = k.c.Run(`pgrep kubelet && sudo systemctl stop kubelet`) + rr, err := k.c.RunCmd(command.ExecCmd("pgrep kubelet && sudo systemctl stop kubelet")) if err != nil { - glog.Warningf("unable to stop kubelet: %s", err) + glog.Warningf("unable to stop kubelet: %s command: %q output: %q", err, rr.Command(), rr.Output()) } if err := transferBinaries(cfg, k.c); err != nil { return errors.Wrap(err, "downloading binaries") @@ -640,8 +654,9 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error { } } - if err := k.c.Run(`sudo systemctl daemon-reload && sudo systemctl start kubelet`); err != nil { - return errors.Wrap(err, "starting kubelet") + rr, err = k.c.RunCmd(command.ExecCmd("sudo systemctl daemon-reload && sudo systemctl start kubelet")) + if err != nil { + return errors.Wrapf(err, "starting kubelet command: %q output: %q", rr.Command(), rr.Output()) } return nil } diff --git a/pkg/minikube/command/exec_runner.go b/pkg/minikube/command/exec_runner.go index cea3743f85fa..a9a5378298d7 100644 --- a/pkg/minikube/command/exec_runner.go +++ b/pkg/minikube/command/exec_runner.go @@ -31,6 +31,11 @@ import ( "k8s.io/minikube/pkg/minikube/assets" ) +// ExecCmd returns a exec.Cmd from a string +func ExecCmd(c string) *exec.Cmd { + return exec.Command("/bin/bash", "-c", c) +} + // ExecRunner runs commands using the os/exec package. // // It implements the CommandRunner interface. From 36de216aa61b125c199b832a7cdc0136d2468cd3 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Fri, 4 Oct 2019 12:51:18 -0700 Subject: [PATCH 06/59] fixing fake_runner for interface --- pkg/drivers/none/none.go | 19 +++++++++++-------- pkg/minikube/command/fake_runner.go | 19 +++++++++++++++---- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/pkg/drivers/none/none.go b/pkg/drivers/none/none.go index da282af9662d..f90effda0cb8 100644 --- a/pkg/drivers/none/none.go +++ b/pkg/drivers/none/none.go @@ -220,19 +220,22 @@ func (d *Driver) RunSSHCommandFromDriver() error { } // stopKubelet idempotently stops the kubelet -func stopKubelet(exec command.Runner) error { +func stopKubelet(cr command.Runner) error { glog.Infof("stopping kubelet.service ...") stop := func() error { - cmdStop := "sudo systemctl stop kubelet.service" - cmdCheck := "sudo systemctl show -p SubState kubelet" - err := exec.Run(cmdStop) + cmdStop := command.ExecCmd("sudo systemctl stop kubelet.service") + rr, err := cr.RunCmd(cmdStop) if err != nil { - glog.Errorf("temporary error for %q : %v", cmdStop, err) + glog.Errorf("temporary error for %q : %v", rr.Command(), err) } + var out bytes.Buffer - errStatus := exec.CombinedOutputTo(cmdCheck, &out) - if errStatus != nil { - glog.Errorf("temporary error: for %q : %v", cmdCheck, errStatus) + cmdCheck := command.ExecCmd("sudo systemctl show -p SubState kubelet") + cmdCheck.Stdout = &out + cmdCheck.Stderr = &out + rr, err = cr.RunCmd(cmdCheck) + if err != nil { + glog.Errorf("temporary error: for %q : %v output: %q", cmdCheck, err, rr.Output()) } if !strings.Contains(out.String(), "dead") && !strings.Contains(out.String(), "failed") { return fmt.Errorf("unexpected kubelet state: %q", out) diff --git a/pkg/minikube/command/fake_runner.go b/pkg/minikube/command/fake_runner.go index b4e5a4d34e59..ed9240957080 100644 --- a/pkg/minikube/command/fake_runner.go +++ b/pkg/minikube/command/fake_runner.go @@ -54,18 +54,29 @@ func (f *FakeCommandRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { start := time.Now() - out, ok := f.cmdMap.Load(cmd.Args) - rr.Stderr = bytes.NewBuffer([]byte(out.(string))) // converting fake output string to a buffer + out, ok := f.cmdMap.Load(strings.Join(cmd.Args, " ")) + buf := new(bytes.Buffer) // creating a buffer reader to convert out to rr.stdout + outStr := "" + if out != nil { + outStr = out.(string) + } + _, err := buf.WriteString(outStr) + if err != nil { + return rr, errors.Wrap(err, "Writing outStr to FakeCommandRunner's buffer") + } + rr.Stdout = buf + rr.Stderr = buf elapsed := time.Since(start) + if ok { // Reduce log spam if elapsed > (1 * time.Second) { glog.Infof("(FakeCommandRunner) Done: %v: (%s)", rr.Command(), elapsed) } } else { - glog.Infof("(FakeCommandRunner) Non-zero exit: %v: (%s)\n%s", rr.Command(), elapsed, rr.Output()) - return rr, fmt.Errorf("unavailable command: %s", strings.Join(cmd.Args, " ")) + glog.Infof("(FakeCommandRunner) Non-zero exit: %v: (%s)\n%s", rr.Command(), elapsed, out) + return rr, fmt.Errorf("unavailable command: %s", rr.Command()) } return rr, nil } From c7af9e78fa1854418c380a3de8e7149f2a1ca8eb Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Fri, 4 Oct 2019 12:57:21 -0700 Subject: [PATCH 07/59] remove extra error wrap --- pkg/minikube/bootstrapper/certs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index 6545c5d366f1..d23e4bea3f9b 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -141,7 +141,7 @@ func SetupCerts(cmd command.Runner, k8s config.KubernetesConfig) error { // configure CA certificates if err := configureCACerts(cmd, caCerts); err != nil { - return errors.Wrapf(err, "error configuring CA certificates during provisioning %v", err) + return errors.Wrapf(err, "configuring CA certs") } return nil } From 46442073e9e4160023fcb2024b85974ef84736fc Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Fri, 4 Oct 2019 13:07:29 -0700 Subject: [PATCH 08/59] improve error wrap --- pkg/minikube/bootstrapper/certs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index d23e4bea3f9b..4180cf9a6e05 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -141,7 +141,7 @@ func SetupCerts(cmd command.Runner, k8s config.KubernetesConfig) error { // configure CA certificates if err := configureCACerts(cmd, caCerts); err != nil { - return errors.Wrapf(err, "configuring CA certs") + return errors.Wrapf(err, "Configuring CA certs") } return nil } From 52dc6ad6b3dc7502c096448d8f77d4872fcfb664 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Fri, 4 Oct 2019 13:51:59 -0700 Subject: [PATCH 09/59] travis buddy to only return error --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 289137e66e3f..4d75c6491e17 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,3 +42,5 @@ notifications: on_failure: always on_cancel: always on_error: always +travisBuddy: + regex: "(\d+ fail|error|Fail|Error|Failed)" \ No newline at end of file From 12fab35c33b122d13150b028b54ed16c997fc4df Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Fri, 4 Oct 2019 13:55:30 -0700 Subject: [PATCH 10/59] travis-buddy config --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4d75c6491e17..f7f7ac7feb9d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,6 +34,8 @@ matrix: script: make test after_success: - bash <(curl -s https://codecov.io/bash) +travisBuddy: + regex: (\d+ fail|error|Fail|Error|Failed) notifications: webhooks: urls: @@ -42,5 +44,3 @@ notifications: on_failure: always on_cancel: always on_error: always -travisBuddy: - regex: "(\d+ fail|error|Fail|Error|Failed)" \ No newline at end of file From a6cf688c3ade21d1e5840a4331e43d8d6c1cb0af Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Fri, 4 Oct 2019 14:11:54 -0700 Subject: [PATCH 11/59] travisbuddy tweak --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f7f7ac7feb9d..3171e9d7e943 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,7 +35,8 @@ matrix: after_success: - bash <(curl -s https://codecov.io/bash) travisBuddy: - regex: (\d+ fail|error|Fail|Error|Failed) + regex: '(\d+ fail|error|Fail|Error|Failed)' + regexOptions: "gm" notifications: webhooks: urls: From 723f62c0d7f6a76f23bdcdbc6ccc9c26e7f1e959 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Fri, 4 Oct 2019 14:19:14 -0700 Subject: [PATCH 12/59] tweak travisbuddy regex --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3171e9d7e943..d714cce75e5e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,8 +35,8 @@ matrix: after_success: - bash <(curl -s https://codecov.io/bash) travisBuddy: - regex: '(\d+ fail|error|Fail|Error|Failed)' - regexOptions: "gm" + regex: '(\d+ Error)' + regexOptions: "g" notifications: webhooks: urls: From d75f41770e7289de7aa307ef6ed04aa2652afc46 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Fri, 4 Oct 2019 14:28:22 -0700 Subject: [PATCH 13/59] tweak travisbuddy regex again --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d714cce75e5e..4e5b1665623e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,7 +35,7 @@ matrix: after_success: - bash <(curl -s https://codecov.io/bash) travisBuddy: - regex: '(\d+ Error)' + regex: (\d+ Error) regexOptions: "g" notifications: webhooks: From 7709c77c8b9245e384700736ca716e748185a53e Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Sun, 6 Oct 2019 17:07:54 -0700 Subject: [PATCH 14/59] fix formatting --- pkg/drivers/none/none.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/drivers/none/none.go b/pkg/drivers/none/none.go index f90effda0cb8..b5912f562063 100644 --- a/pkg/drivers/none/none.go +++ b/pkg/drivers/none/none.go @@ -235,7 +235,7 @@ func stopKubelet(cr command.Runner) error { cmdCheck.Stderr = &out rr, err = cr.RunCmd(cmdCheck) if err != nil { - glog.Errorf("temporary error: for %q : %v output: %q", cmdCheck, err, rr.Output()) + glog.Errorf("temporary error: for %q : %v output: %q", rr.Command(), err, rr.Output()) } if !strings.Contains(out.String(), "dead") && !strings.Contains(out.String(), "failed") { return fmt.Errorf("unexpected kubelet state: %q", out) From 9df56183fd8e126fb40278559bc6543bf3a1317c Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Sun, 6 Oct 2019 19:17:36 -0700 Subject: [PATCH 15/59] fix fakerunner runcmd unit test --- pkg/minikube/command/fake_runner.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/minikube/command/fake_runner.go b/pkg/minikube/command/fake_runner.go index ed9240957080..ba110aecefdc 100644 --- a/pkg/minikube/command/fake_runner.go +++ b/pkg/minikube/command/fake_runner.go @@ -49,12 +49,12 @@ func NewFakeCommandRunner() *FakeCommandRunner { // RunCmd implements the Command Runner interface to run a exec.Cmd object func (f *FakeCommandRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { - rr := &RunResult{Args: cmd.Args} + rr := &RunResult{Args: cmd.Args[2:]} // to get rid of /bin/bash -c part glog.Infof("(FakeCommandRunner) Run: %v", rr.Command()) start := time.Now() - out, ok := f.cmdMap.Load(strings.Join(cmd.Args, " ")) + out, ok := f.cmdMap.Load(strings.Join(rr.Args, " ")) buf := new(bytes.Buffer) // creating a buffer reader to convert out to rr.stdout outStr := "" if out != nil { From 8fcdae926ef2666859102854d8d063c3d03964e2 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Sun, 6 Oct 2019 22:06:29 -0700 Subject: [PATCH 16/59] refactor --- pkg/drivers/none/none.go | 21 +++++++++++++++------ pkg/minikube/tunnel/route_darwin.go | 24 ++++++++++++------------ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/pkg/drivers/none/none.go b/pkg/drivers/none/none.go index b5912f562063..377e8af9debe 100644 --- a/pkg/drivers/none/none.go +++ b/pkg/drivers/none/none.go @@ -171,9 +171,10 @@ func (d *Driver) Remove() error { return errors.Wrap(err, "kill") } glog.Infof("Removing: %s", cleanupPaths) - cmd := fmt.Sprintf("sudo rm -rf %s", strings.Join(cleanupPaths, " ")) - if err := d.exec.Run(cmd); err != nil { - glog.Errorf("cleanup incomplete: %v", err) + c := command.ExecCmd(fmt.Sprintf("sudo rm -rf %s", strings.Join(cleanupPaths, " "))) + rr, err := d.exec.RunCmd(c) + if err != nil { + glog.Errorf("cleanup incomplete: %v , output: %s", err, rr.Output()) } return nil } @@ -253,11 +254,19 @@ func stopKubelet(cr command.Runner) error { // restartKubelet restarts the kubelet func restartKubelet(exec command.Runner) error { glog.Infof("restarting kubelet.service ...") - return exec.Run("sudo systemctl restart kubelet.service") + rr, err := exec.RunCmd(command.ExecCmd("sudo systemctl restart kubelet.service")) + if err != nil { + return errors.Wrapf(err, "restartKubelet with output: %s", rr.Output()) + } + return nil } // checkKubelet returns an error if the kubelet is not running. -func checkKubelet(exec command.Runner) error { +func checkKubelet(cr command.Runner) error { glog.Infof("checking for running kubelet ...") - return exec.Run("systemctl is-active --quiet service kubelet") + rr, err := cr.RunCmd(command.ExecCmd("systemctl is-active --quiet service kubelet")) + if err != nil { + return errors.Wrapf(err, "checkKubelet output: %s", rr.Output()) + } + return nil } diff --git a/pkg/minikube/tunnel/route_darwin.go b/pkg/minikube/tunnel/route_darwin.go index 815eff6bfe4a..0e2f5064ff28 100644 --- a/pkg/minikube/tunnel/route_darwin.go +++ b/pkg/minikube/tunnel/route_darwin.go @@ -156,21 +156,21 @@ func (router *osRouter) Cleanup(route *Route) error { if !exists { return nil } - command := exec.Command("sudo", "route", "-n", "delete", route.DestCIDR.String()) - stdInAndOut, err := command.CombinedOutput() + cmd := exec.Command("sudo", "route", "-n", "delete", route.DestCIDR.String()) + stdInAndOut, err := cmd.CombinedOutput() if err != nil { return err } - message := fmt.Sprintf("%s", stdInAndOut) - glog.V(4).Infof("%s", message) + msg := fmt.Sprintf("%s", stdInAndOut) + glog.V(4).Infof("%s", msg) re := regexp.MustCompile("^delete net ([^:]*)$") - if !re.MatchString(message) { - return fmt.Errorf("error deleting route: %s, %d", message, len(strings.Split(message, "\n"))) + if !re.MatchString(msg) { + return fmt.Errorf("error deleting route: %s, %d", msg, len(strings.Split(msg, "\n"))) } // idempotent removal of cluster domain dns resolverFile := fmt.Sprintf("/etc/resolver/%s", route.ClusterDomain) - command = exec.Command("sudo", "rm", "-f", resolverFile) - if err := command.Run(); err != nil { + cmd = exec.Command("sudo", "rm", "-f", resolverFile) + if err := cmd.Run(); err != nil { return fmt.Errorf("could not remove %s: %s", resolverFile, err) } return nil @@ -191,12 +191,12 @@ func writeResolverFile(route *Route) error { if err = tmpFile.Close(); err != nil { return err } - command := exec.Command("sudo", "mkdir", "-p", "/etc/resolver") - if err := command.Run(); err != nil { + cmd := exec.Command("sudo", "mkdir", "-p", "/etc/resolver") + if err := cmd.Run(); err != nil { return err } - command = exec.Command("sudo", "cp", "-f", tmpFile.Name(), resolverFile) - if err := command.Run(); err != nil { + cmd = exec.Command("sudo", "cp", "-f", tmpFile.Name(), resolverFile) + if err := cmd.Run(); err != nil { return err } return nil From a78deab26f571ab45ef813e29c3ffb3025203b1d Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Mon, 7 Oct 2019 22:23:23 -0700 Subject: [PATCH 17/59] adding a new ExecCmd2 --- pkg/minikube/bootstrapper/certs.go | 13 +++++----- pkg/minikube/bootstrapper/kubeadm/kubeadm.go | 26 ++++++++++---------- pkg/minikube/command/exec_runner.go | 7 ++++++ 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index 4180cf9a6e05..b93952fb0b01 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -332,7 +332,7 @@ func getSubjectHash(cmd command.Runner, filePath string) (string, error) { // OpenSSL binary required in minikube ISO func configureCACerts(cr command.Runner, caCerts map[string]string) error { hasSSLBinary := true - _, err := cr.RunCmd(command.ExecCmd("which openssl")) + _, err := cr.RunCmd(command.ExecCmd2("which openssl")) if err != nil { hasSSLBinary = false } @@ -345,10 +345,10 @@ func configureCACerts(cr command.Runner, caCerts map[string]string) error { dstFilename := path.Base(caCertFile) certStorePath := path.Join(SSLCertStoreDir, dstFilename) - cmd := command.ExecCmd(fmt.Sprintf("sudo test -f '%s'", certStorePath)) + cmd := command.ExecCmd2(fmt.Sprintf("sudo test -f '%s'", certStorePath)) _, err := cr.RunCmd(cmd) if err != nil { - cmd = command.ExecCmd(fmt.Sprintf("sudo ln -s '%s' '%s'", caCertFile, certStorePath)) + cmd = command.ExecCmd2(fmt.Sprintf("sudo ln -s '%s' '%s'", caCertFile, certStorePath)) rr, err := cr.RunCmd(cmd) if err != nil { return errors.Wrapf(err, "error making symbol link for certificate %s : %q", caCertFile, rr.Output()) @@ -360,10 +360,11 @@ func configureCACerts(cr command.Runner, caCerts map[string]string) error { return errors.Wrapf(err, "error calculating subject hash for certificate %s", caCertFile) } subjectHashLink := path.Join(SSLCertStoreDir, fmt.Sprintf("%s.0", subjectHash)) - cmd = command.ExecCmd(fmt.Sprintf("sudo test -f '%s'", subjectHashLink)) - rr, err := cr.RunCmd(cmd) + _, err = cr.RunCmd(command.ExecCmd2(fmt.Sprintf("sudo test -f '%s'", subjectHashLink))) if err != nil { - return errors.Wrapf(err, "error making subject hash symbol link for certificate %s, %q", caCertFile, rr.Output()) + if rr, err := cr.RunCmd(command.ExecCmd2(fmt.Sprintf("sudo ln -s '%s' '%s'", certStorePath, subjectHashLink))); err != nil { + return errors.Wrapf(err, "error making subject hash symbol %s link for certificate %s. cmd: %q output: %q", subjectHash, caCertFile, rr.Command(), rr.Output()) + } } } } diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index 3de10157990a..4ee851ec7ba8 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -136,7 +136,7 @@ func NewKubeadmBootstrapper(api libmachine.API) (*Bootstrapper, error) { // GetKubeletStatus returns the kubelet status func (k *Bootstrapper) GetKubeletStatus() (string, error) { - cmd := command.ExecCmd("sudo systemctl is-active kubelet") + cmd := command.ExecCmd2("sudo systemctl is-active kubelet") rr, err := k.c.RunCmd(cmd) if err != nil { return "", errors.Wrapf(err, "getting kublet status. command: %q output: %q", rr.Command(), rr.Output()) @@ -222,7 +222,7 @@ func etcdDataDir() string { // createCompatSymlinks creates compatibility symlinks to transition running services to new directory structures func (k *Bootstrapper) createCompatSymlinks() error { legacyEtcd := "/data/minikube" - cmd := command.ExecCmd(fmt.Sprintf("sudo test -d %s", legacyEtcd)) + cmd := command.ExecCmd2(fmt.Sprintf("sudo test -d %s", legacyEtcd)) rr, err := k.c.RunCmd(cmd) if err != nil { glog.Infof("%s check failed, skipping compat symlinks: %v %q", legacyEtcd, err, rr.Output()) @@ -231,7 +231,7 @@ func (k *Bootstrapper) createCompatSymlinks() error { glog.Infof("Found %s, creating compatibility symlinks ...", legacyEtcd) - cmd = command.ExecCmd(fmt.Sprintf("sudo ln -s %s %s", legacyEtcd, etcdDataDir())) + cmd = command.ExecCmd2(fmt.Sprintf("sudo ln -s %s %s", legacyEtcd, etcdDataDir())) rr, err = k.c.RunCmd(cmd) if err != nil { return errors.Wrapf(err, "create symlink failed: %s\n%q\n", rr.Command(), rr.Output()) @@ -278,7 +278,7 @@ func (k *Bootstrapper) StartCluster(k8s config.KubernetesConfig) error { c := fmt.Sprintf("%s init --config %s %s --ignore-preflight-errors=%s", invokeKubeadm(k8s.KubernetesVersion), yamlConfigPath, extraFlags, strings.Join(ignore, ",")) - rr, err := k.c.RunCmd(command.ExecCmd(c)) + rr, err := k.c.RunCmd(command.ExecCmd2(c)) if err != nil { return errors.Wrapf(err, "init failed. cmd: %q\noutput:%q\n", rr.Command(), rr.Output()) } @@ -305,7 +305,7 @@ func (k *Bootstrapper) StartCluster(k8s config.KubernetesConfig) error { // adjustResourceLimits makes fine adjustments to pod resources that aren't possible via kubeadm config. func (k *Bootstrapper) adjustResourceLimits() error { - rr, err := k.c.RunCmd(command.ExecCmd("cat /proc/$(pgrep kube-apiserver)/oom_adj")) + rr, err := k.c.RunCmd(command.ExecCmd2("cat /proc/$(pgrep kube-apiserver)/oom_adj")) if err != nil { return errors.Wrap(err, "oom_adj check. command: %q output: %q") } @@ -316,7 +316,7 @@ func (k *Bootstrapper) adjustResourceLimits() error { } glog.Infof("adjusting apiserver oom_adj to -10") - cmd := command.ExecCmd("echo -10 | sudo tee /proc/$(pgrep kube-apiserver)/oom_adj") + cmd := command.ExecCmd2("echo -10 | sudo tee /proc/$(pgrep kube-apiserver)/oom_adj") // Prevent the apiserver from OOM'ing before other pods, as it is our gateway into the cluster. // It'd be preferable to do this via Kubernetes, but kubeadm doesn't have a way to set pod QoS. rr, err = k.c.RunCmd(cmd) @@ -441,7 +441,7 @@ func (k *Bootstrapper) RestartCluster(k8s config.KubernetesConfig) error { // Run commands one at a time so that it is easier to root cause failures. for _, c := range cmds { - cmd := command.ExecCmd(c) + cmd := command.ExecCmd2(c) rr, err := k.c.RunCmd(cmd) if err != nil { return errors.Wrapf(err, "running cmd: %s , output: %s", rr.Command(), rr.Output()) @@ -453,7 +453,7 @@ func (k *Bootstrapper) RestartCluster(k8s config.KubernetesConfig) error { } // restart the proxy and coredns - cmd := command.ExecCmd(fmt.Sprintf("%s phase addon all --config %s", baseCmd, yamlConfigPath)) + cmd := command.ExecCmd2(fmt.Sprintf("%s phase addon all --config %s", baseCmd, yamlConfigPath)) rr, err := k.c.RunCmd(cmd) if err != nil { return errors.Wrapf(err, fmt.Sprintf("addon phase cmd:%q output:%q", rr.Command(), rr.Output())) @@ -476,7 +476,7 @@ func (k *Bootstrapper) waitForAPIServer(k8s config.KubernetesConfig) error { // To give a better error message, first check for process existence via ssh // Needs minutes in case the image isn't cached (such as with v1.10.x) err := wait.PollImmediate(time.Millisecond*300, time.Minute*3, func() (bool, error) { - cmd := command.ExecCmd("sudo pgrep kube-apiserver") + cmd := command.ExecCmd2("sudo pgrep kube-apiserver") rr, ierr := k.c.RunCmd(cmd) if ierr != nil { glog.Warningf("pgrep apiserver: %v cmd: %s output: %s", ierr, rr.Command(), rr.Output()) @@ -521,7 +521,7 @@ func (k *Bootstrapper) DeleteCluster(k8s config.KubernetesConfig) error { c = fmt.Sprintf("%s reset", invokeKubeadm(k8s.KubernetesVersion)) } - rr, err := k.c.RunCmd(command.ExecCmd(c)) + rr, err := k.c.RunCmd(command.ExecCmd2(c)) if err != nil { return errors.Wrapf(err, "kubeadm reset: cmd: %q\noutput:%q\n", rr.Command(), rr.Output()) } @@ -539,7 +539,7 @@ func (k *Bootstrapper) PullImages(k8s config.KubernetesConfig) error { return fmt.Errorf("pull command is not supported by kubeadm v%s", version) } - cmd := command.ExecCmd(fmt.Sprintf("%s config images pull --config %s", invokeKubeadm(k8s.KubernetesVersion), yamlConfigPath)) + cmd := command.ExecCmd2(fmt.Sprintf("%s config images pull --config %s", invokeKubeadm(k8s.KubernetesVersion), yamlConfigPath)) rr, err := k.c.RunCmd(cmd) if err != nil { return errors.Wrapf(err, "running cmd: %q output: %q", rr.Command(), rr.Output()) @@ -637,7 +637,7 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error { glog.Infof("kubelet %s config:\n%s", cfg.KubernetesVersion, kubeletCfg) // stop kubelet to avoid "Text File Busy" error - rr, err := k.c.RunCmd(command.ExecCmd("pgrep kubelet && sudo systemctl stop kubelet")) + rr, err := k.c.RunCmd(command.ExecCmd2("pgrep kubelet && sudo systemctl stop kubelet")) if err != nil { glog.Warningf("unable to stop kubelet: %s command: %q output: %q", err, rr.Command(), rr.Output()) } @@ -654,7 +654,7 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error { } } - rr, err = k.c.RunCmd(command.ExecCmd("sudo systemctl daemon-reload && sudo systemctl start kubelet")) + rr, err = k.c.RunCmd(command.ExecCmd2("sudo systemctl daemon-reload && sudo systemctl start kubelet")) if err != nil { return errors.Wrapf(err, "starting kubelet command: %q output: %q", rr.Command(), rr.Output()) } diff --git a/pkg/minikube/command/exec_runner.go b/pkg/minikube/command/exec_runner.go index a9a5378298d7..53b46ea39ff4 100644 --- a/pkg/minikube/command/exec_runner.go +++ b/pkg/minikube/command/exec_runner.go @@ -24,6 +24,7 @@ import ( "path" "path/filepath" "strconv" + "strings" "time" "github.com/golang/glog" @@ -36,6 +37,12 @@ func ExecCmd(c string) *exec.Cmd { return exec.Command("/bin/bash", "-c", c) } +// ExecCmd returns a exec.Cmd from a string +func ExecCmd2(c string) *exec.Cmd { + args := strings.Split(c, " ") + return exec.Command(args[0], args[1:]...) +} + // ExecRunner runs commands using the os/exec package. // // It implements the CommandRunner interface. From 0c435b050b2d2e5ce2f4d84855cb61b0839b1164 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Mon, 7 Oct 2019 22:43:07 -0700 Subject: [PATCH 18/59] fix unit test for cert --- pkg/minikube/command/fake_runner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/minikube/command/fake_runner.go b/pkg/minikube/command/fake_runner.go index ba110aecefdc..4a558eea2a54 100644 --- a/pkg/minikube/command/fake_runner.go +++ b/pkg/minikube/command/fake_runner.go @@ -49,7 +49,7 @@ func NewFakeCommandRunner() *FakeCommandRunner { // RunCmd implements the Command Runner interface to run a exec.Cmd object func (f *FakeCommandRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { - rr := &RunResult{Args: cmd.Args[2:]} // to get rid of /bin/bash -c part + rr := &RunResult{Args: cmd.Args} // to get rid of /bin/bash -c part glog.Infof("(FakeCommandRunner) Run: %v", rr.Command()) start := time.Now() From b8181a081f164f3e3e0c00d62a7f38b149bf7809 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Tue, 8 Oct 2019 11:39:10 -0700 Subject: [PATCH 19/59] move more to exec.Cmd2 --- pkg/drivers/none/none.go | 10 +++++----- pkg/minikube/command/fake_runner.go | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/drivers/none/none.go b/pkg/drivers/none/none.go index 377e8af9debe..f0bbf650d243 100644 --- a/pkg/drivers/none/none.go +++ b/pkg/drivers/none/none.go @@ -171,7 +171,7 @@ func (d *Driver) Remove() error { return errors.Wrap(err, "kill") } glog.Infof("Removing: %s", cleanupPaths) - c := command.ExecCmd(fmt.Sprintf("sudo rm -rf %s", strings.Join(cleanupPaths, " "))) + c := command.ExecCmd2(fmt.Sprintf("sudo rm -rf %s", strings.Join(cleanupPaths, " "))) rr, err := d.exec.RunCmd(c) if err != nil { glog.Errorf("cleanup incomplete: %v , output: %s", err, rr.Output()) @@ -224,14 +224,14 @@ func (d *Driver) RunSSHCommandFromDriver() error { func stopKubelet(cr command.Runner) error { glog.Infof("stopping kubelet.service ...") stop := func() error { - cmdStop := command.ExecCmd("sudo systemctl stop kubelet.service") + cmdStop := command.ExecCmd2("sudo systemctl stop kubelet.service") rr, err := cr.RunCmd(cmdStop) if err != nil { glog.Errorf("temporary error for %q : %v", rr.Command(), err) } var out bytes.Buffer - cmdCheck := command.ExecCmd("sudo systemctl show -p SubState kubelet") + cmdCheck := command.ExecCmd2("sudo systemctl show -p SubState kubelet") cmdCheck.Stdout = &out cmdCheck.Stderr = &out rr, err = cr.RunCmd(cmdCheck) @@ -254,7 +254,7 @@ func stopKubelet(cr command.Runner) error { // restartKubelet restarts the kubelet func restartKubelet(exec command.Runner) error { glog.Infof("restarting kubelet.service ...") - rr, err := exec.RunCmd(command.ExecCmd("sudo systemctl restart kubelet.service")) + rr, err := exec.RunCmd(command.ExecCmd2("sudo systemctl restart kubelet.service")) if err != nil { return errors.Wrapf(err, "restartKubelet with output: %s", rr.Output()) } @@ -264,7 +264,7 @@ func restartKubelet(exec command.Runner) error { // checkKubelet returns an error if the kubelet is not running. func checkKubelet(cr command.Runner) error { glog.Infof("checking for running kubelet ...") - rr, err := cr.RunCmd(command.ExecCmd("systemctl is-active --quiet service kubelet")) + rr, err := cr.RunCmd(command.ExecCmd2("systemctl is-active --quiet service kubelet")) if err != nil { return errors.Wrapf(err, "checkKubelet output: %s", rr.Output()) } diff --git a/pkg/minikube/command/fake_runner.go b/pkg/minikube/command/fake_runner.go index 4a558eea2a54..f18cfb97149c 100644 --- a/pkg/minikube/command/fake_runner.go +++ b/pkg/minikube/command/fake_runner.go @@ -49,7 +49,7 @@ func NewFakeCommandRunner() *FakeCommandRunner { // RunCmd implements the Command Runner interface to run a exec.Cmd object func (f *FakeCommandRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { - rr := &RunResult{Args: cmd.Args} // to get rid of /bin/bash -c part + rr := &RunResult{Args: cmd.Args} glog.Infof("(FakeCommandRunner) Run: %v", rr.Command()) start := time.Now() From 927146361c6ace41f8db04b1e68111fb7beb25b5 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Tue, 8 Oct 2019 13:09:59 -0700 Subject: [PATCH 20/59] get rid of ExecCmd2 --- pkg/minikube/bootstrapper/certs.go | 10 ++++---- pkg/minikube/bootstrapper/kubeadm/kubeadm.go | 26 ++++++++++---------- pkg/minikube/command/exec_runner.go | 7 +----- 3 files changed, 19 insertions(+), 24 deletions(-) diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index b93952fb0b01..c0c7ee7a3445 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -332,7 +332,7 @@ func getSubjectHash(cmd command.Runner, filePath string) (string, error) { // OpenSSL binary required in minikube ISO func configureCACerts(cr command.Runner, caCerts map[string]string) error { hasSSLBinary := true - _, err := cr.RunCmd(command.ExecCmd2("which openssl")) + _, err := cr.RunCmd(command.ExecCmd("which openssl")) if err != nil { hasSSLBinary = false } @@ -345,10 +345,10 @@ func configureCACerts(cr command.Runner, caCerts map[string]string) error { dstFilename := path.Base(caCertFile) certStorePath := path.Join(SSLCertStoreDir, dstFilename) - cmd := command.ExecCmd2(fmt.Sprintf("sudo test -f '%s'", certStorePath)) + cmd := command.ExecCmd(fmt.Sprintf("sudo test -f '%s'", certStorePath)) _, err := cr.RunCmd(cmd) if err != nil { - cmd = command.ExecCmd2(fmt.Sprintf("sudo ln -s '%s' '%s'", caCertFile, certStorePath)) + cmd = command.ExecCmd(fmt.Sprintf("sudo ln -s '%s' '%s'", caCertFile, certStorePath)) rr, err := cr.RunCmd(cmd) if err != nil { return errors.Wrapf(err, "error making symbol link for certificate %s : %q", caCertFile, rr.Output()) @@ -360,9 +360,9 @@ func configureCACerts(cr command.Runner, caCerts map[string]string) error { return errors.Wrapf(err, "error calculating subject hash for certificate %s", caCertFile) } subjectHashLink := path.Join(SSLCertStoreDir, fmt.Sprintf("%s.0", subjectHash)) - _, err = cr.RunCmd(command.ExecCmd2(fmt.Sprintf("sudo test -f '%s'", subjectHashLink))) + _, err = cr.RunCmd(command.ExecCmd(fmt.Sprintf("sudo test -f '%s'", subjectHashLink))) if err != nil { - if rr, err := cr.RunCmd(command.ExecCmd2(fmt.Sprintf("sudo ln -s '%s' '%s'", certStorePath, subjectHashLink))); err != nil { + if rr, err := cr.RunCmd(command.ExecCmd(fmt.Sprintf("sudo ln -s '%s' '%s'", certStorePath, subjectHashLink))); err != nil { return errors.Wrapf(err, "error making subject hash symbol %s link for certificate %s. cmd: %q output: %q", subjectHash, caCertFile, rr.Command(), rr.Output()) } } diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index 4ee851ec7ba8..3de10157990a 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -136,7 +136,7 @@ func NewKubeadmBootstrapper(api libmachine.API) (*Bootstrapper, error) { // GetKubeletStatus returns the kubelet status func (k *Bootstrapper) GetKubeletStatus() (string, error) { - cmd := command.ExecCmd2("sudo systemctl is-active kubelet") + cmd := command.ExecCmd("sudo systemctl is-active kubelet") rr, err := k.c.RunCmd(cmd) if err != nil { return "", errors.Wrapf(err, "getting kublet status. command: %q output: %q", rr.Command(), rr.Output()) @@ -222,7 +222,7 @@ func etcdDataDir() string { // createCompatSymlinks creates compatibility symlinks to transition running services to new directory structures func (k *Bootstrapper) createCompatSymlinks() error { legacyEtcd := "/data/minikube" - cmd := command.ExecCmd2(fmt.Sprintf("sudo test -d %s", legacyEtcd)) + cmd := command.ExecCmd(fmt.Sprintf("sudo test -d %s", legacyEtcd)) rr, err := k.c.RunCmd(cmd) if err != nil { glog.Infof("%s check failed, skipping compat symlinks: %v %q", legacyEtcd, err, rr.Output()) @@ -231,7 +231,7 @@ func (k *Bootstrapper) createCompatSymlinks() error { glog.Infof("Found %s, creating compatibility symlinks ...", legacyEtcd) - cmd = command.ExecCmd2(fmt.Sprintf("sudo ln -s %s %s", legacyEtcd, etcdDataDir())) + cmd = command.ExecCmd(fmt.Sprintf("sudo ln -s %s %s", legacyEtcd, etcdDataDir())) rr, err = k.c.RunCmd(cmd) if err != nil { return errors.Wrapf(err, "create symlink failed: %s\n%q\n", rr.Command(), rr.Output()) @@ -278,7 +278,7 @@ func (k *Bootstrapper) StartCluster(k8s config.KubernetesConfig) error { c := fmt.Sprintf("%s init --config %s %s --ignore-preflight-errors=%s", invokeKubeadm(k8s.KubernetesVersion), yamlConfigPath, extraFlags, strings.Join(ignore, ",")) - rr, err := k.c.RunCmd(command.ExecCmd2(c)) + rr, err := k.c.RunCmd(command.ExecCmd(c)) if err != nil { return errors.Wrapf(err, "init failed. cmd: %q\noutput:%q\n", rr.Command(), rr.Output()) } @@ -305,7 +305,7 @@ func (k *Bootstrapper) StartCluster(k8s config.KubernetesConfig) error { // adjustResourceLimits makes fine adjustments to pod resources that aren't possible via kubeadm config. func (k *Bootstrapper) adjustResourceLimits() error { - rr, err := k.c.RunCmd(command.ExecCmd2("cat /proc/$(pgrep kube-apiserver)/oom_adj")) + rr, err := k.c.RunCmd(command.ExecCmd("cat /proc/$(pgrep kube-apiserver)/oom_adj")) if err != nil { return errors.Wrap(err, "oom_adj check. command: %q output: %q") } @@ -316,7 +316,7 @@ func (k *Bootstrapper) adjustResourceLimits() error { } glog.Infof("adjusting apiserver oom_adj to -10") - cmd := command.ExecCmd2("echo -10 | sudo tee /proc/$(pgrep kube-apiserver)/oom_adj") + cmd := command.ExecCmd("echo -10 | sudo tee /proc/$(pgrep kube-apiserver)/oom_adj") // Prevent the apiserver from OOM'ing before other pods, as it is our gateway into the cluster. // It'd be preferable to do this via Kubernetes, but kubeadm doesn't have a way to set pod QoS. rr, err = k.c.RunCmd(cmd) @@ -441,7 +441,7 @@ func (k *Bootstrapper) RestartCluster(k8s config.KubernetesConfig) error { // Run commands one at a time so that it is easier to root cause failures. for _, c := range cmds { - cmd := command.ExecCmd2(c) + cmd := command.ExecCmd(c) rr, err := k.c.RunCmd(cmd) if err != nil { return errors.Wrapf(err, "running cmd: %s , output: %s", rr.Command(), rr.Output()) @@ -453,7 +453,7 @@ func (k *Bootstrapper) RestartCluster(k8s config.KubernetesConfig) error { } // restart the proxy and coredns - cmd := command.ExecCmd2(fmt.Sprintf("%s phase addon all --config %s", baseCmd, yamlConfigPath)) + cmd := command.ExecCmd(fmt.Sprintf("%s phase addon all --config %s", baseCmd, yamlConfigPath)) rr, err := k.c.RunCmd(cmd) if err != nil { return errors.Wrapf(err, fmt.Sprintf("addon phase cmd:%q output:%q", rr.Command(), rr.Output())) @@ -476,7 +476,7 @@ func (k *Bootstrapper) waitForAPIServer(k8s config.KubernetesConfig) error { // To give a better error message, first check for process existence via ssh // Needs minutes in case the image isn't cached (such as with v1.10.x) err := wait.PollImmediate(time.Millisecond*300, time.Minute*3, func() (bool, error) { - cmd := command.ExecCmd2("sudo pgrep kube-apiserver") + cmd := command.ExecCmd("sudo pgrep kube-apiserver") rr, ierr := k.c.RunCmd(cmd) if ierr != nil { glog.Warningf("pgrep apiserver: %v cmd: %s output: %s", ierr, rr.Command(), rr.Output()) @@ -521,7 +521,7 @@ func (k *Bootstrapper) DeleteCluster(k8s config.KubernetesConfig) error { c = fmt.Sprintf("%s reset", invokeKubeadm(k8s.KubernetesVersion)) } - rr, err := k.c.RunCmd(command.ExecCmd2(c)) + rr, err := k.c.RunCmd(command.ExecCmd(c)) if err != nil { return errors.Wrapf(err, "kubeadm reset: cmd: %q\noutput:%q\n", rr.Command(), rr.Output()) } @@ -539,7 +539,7 @@ func (k *Bootstrapper) PullImages(k8s config.KubernetesConfig) error { return fmt.Errorf("pull command is not supported by kubeadm v%s", version) } - cmd := command.ExecCmd2(fmt.Sprintf("%s config images pull --config %s", invokeKubeadm(k8s.KubernetesVersion), yamlConfigPath)) + cmd := command.ExecCmd(fmt.Sprintf("%s config images pull --config %s", invokeKubeadm(k8s.KubernetesVersion), yamlConfigPath)) rr, err := k.c.RunCmd(cmd) if err != nil { return errors.Wrapf(err, "running cmd: %q output: %q", rr.Command(), rr.Output()) @@ -637,7 +637,7 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error { glog.Infof("kubelet %s config:\n%s", cfg.KubernetesVersion, kubeletCfg) // stop kubelet to avoid "Text File Busy" error - rr, err := k.c.RunCmd(command.ExecCmd2("pgrep kubelet && sudo systemctl stop kubelet")) + rr, err := k.c.RunCmd(command.ExecCmd("pgrep kubelet && sudo systemctl stop kubelet")) if err != nil { glog.Warningf("unable to stop kubelet: %s command: %q output: %q", err, rr.Command(), rr.Output()) } @@ -654,7 +654,7 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error { } } - rr, err = k.c.RunCmd(command.ExecCmd2("sudo systemctl daemon-reload && sudo systemctl start kubelet")) + rr, err = k.c.RunCmd(command.ExecCmd("sudo systemctl daemon-reload && sudo systemctl start kubelet")) if err != nil { return errors.Wrapf(err, "starting kubelet command: %q output: %q", rr.Command(), rr.Output()) } diff --git a/pkg/minikube/command/exec_runner.go b/pkg/minikube/command/exec_runner.go index 53b46ea39ff4..7ce29dd4ca8e 100644 --- a/pkg/minikube/command/exec_runner.go +++ b/pkg/minikube/command/exec_runner.go @@ -34,12 +34,7 @@ import ( // ExecCmd returns a exec.Cmd from a string func ExecCmd(c string) *exec.Cmd { - return exec.Command("/bin/bash", "-c", c) -} - -// ExecCmd returns a exec.Cmd from a string -func ExecCmd2(c string) *exec.Cmd { - args := strings.Split(c, " ") + args := strings.Split(c, " ") // maybe alternatively? ("/bin/bash", "-c", c) return exec.Command(args[0], args[1:]...) } From 91618aa38b5e11cb41bf528c31ec37cbfa3abafb Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Tue, 8 Oct 2019 15:13:54 -0700 Subject: [PATCH 21/59] get rid of ExecCmd all the way --- pkg/drivers/none/none.go | 30 ++++++------ pkg/minikube/bootstrapper/certs.go | 21 ++++---- pkg/minikube/bootstrapper/kubeadm/kubeadm.go | 51 ++++++++------------ pkg/minikube/command/exec_runner.go | 7 --- 4 files changed, 45 insertions(+), 64 deletions(-) diff --git a/pkg/drivers/none/none.go b/pkg/drivers/none/none.go index f0bbf650d243..9f57f5387c47 100644 --- a/pkg/drivers/none/none.go +++ b/pkg/drivers/none/none.go @@ -19,6 +19,7 @@ package none import ( "bytes" "fmt" + "os/exec" "strings" "time" @@ -171,9 +172,9 @@ func (d *Driver) Remove() error { return errors.Wrap(err, "kill") } glog.Infof("Removing: %s", cleanupPaths) - c := command.ExecCmd2(fmt.Sprintf("sudo rm -rf %s", strings.Join(cleanupPaths, " "))) - rr, err := d.exec.RunCmd(c) - if err != nil { + c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo rm -rf %s", strings.Join(cleanupPaths, " "))) + + if rr, err := d.exec.RunCmd(c); err != nil { glog.Errorf("cleanup incomplete: %v , output: %s", err, rr.Output()) } return nil @@ -224,18 +225,15 @@ func (d *Driver) RunSSHCommandFromDriver() error { func stopKubelet(cr command.Runner) error { glog.Infof("stopping kubelet.service ...") stop := func() error { - cmdStop := command.ExecCmd2("sudo systemctl stop kubelet.service") - rr, err := cr.RunCmd(cmdStop) - if err != nil { + cmdStop := exec.Command("/bin/bash", "-c", "sudo systemctl stop kubelet.service") + if rr, err := cr.RunCmd(cmdStop); err != nil { glog.Errorf("temporary error for %q : %v", rr.Command(), err) } - var out bytes.Buffer - cmdCheck := command.ExecCmd2("sudo systemctl show -p SubState kubelet") + cmdCheck := exec.Command("/bin/bash", "-c", "sudo systemctl show -p SubState kubelet") cmdCheck.Stdout = &out cmdCheck.Stderr = &out - rr, err = cr.RunCmd(cmdCheck) - if err != nil { + if rr, err := cr.RunCmd(cmdCheck); err != nil { glog.Errorf("temporary error: for %q : %v output: %q", rr.Command(), err, rr.Output()) } if !strings.Contains(out.String(), "dead") && !strings.Contains(out.String(), "failed") { @@ -252,11 +250,11 @@ func stopKubelet(cr command.Runner) error { } // restartKubelet restarts the kubelet -func restartKubelet(exec command.Runner) error { +func restartKubelet(cr command.Runner) error { glog.Infof("restarting kubelet.service ...") - rr, err := exec.RunCmd(command.ExecCmd2("sudo systemctl restart kubelet.service")) - if err != nil { - return errors.Wrapf(err, "restartKubelet with output: %s", rr.Output()) + c := exec.Command("/bin/bash", "-c", "sudo systemctl restart kubelet.service") + if rr, err := cr.RunCmd(c); err != nil { + return errors.Wrapf(err, "restartKubelet output: %s", rr.Output()) } return nil } @@ -264,8 +262,8 @@ func restartKubelet(exec command.Runner) error { // checkKubelet returns an error if the kubelet is not running. func checkKubelet(cr command.Runner) error { glog.Infof("checking for running kubelet ...") - rr, err := cr.RunCmd(command.ExecCmd2("systemctl is-active --quiet service kubelet")) - if err != nil { + c := exec.Command("/bin/bash", "-c", "systemctl is-active --quiet service kubelet") + if rr, err := cr.RunCmd(c); err != nil { return errors.Wrapf(err, "checkKubelet output: %s", rr.Output()) } return nil diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index c0c7ee7a3445..d7c821296ce6 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -22,6 +22,7 @@ import ( "io/ioutil" "net" "os" + "os/exec" "path" "path/filepath" "strings" @@ -332,7 +333,8 @@ func getSubjectHash(cmd command.Runner, filePath string) (string, error) { // OpenSSL binary required in minikube ISO func configureCACerts(cr command.Runner, caCerts map[string]string) error { hasSSLBinary := true - _, err := cr.RunCmd(command.ExecCmd("which openssl")) + c := exec.Command("/bin/bash", "-c", "which openssl") + _, err := cr.RunCmd(c) if err != nil { hasSSLBinary = false } @@ -345,13 +347,13 @@ func configureCACerts(cr command.Runner, caCerts map[string]string) error { dstFilename := path.Base(caCertFile) certStorePath := path.Join(SSLCertStoreDir, dstFilename) - cmd := command.ExecCmd(fmt.Sprintf("sudo test -f '%s'", certStorePath)) - _, err := cr.RunCmd(cmd) + c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo test -f '%s'", certStorePath)) + _, err := cr.RunCmd(c) if err != nil { - cmd = command.ExecCmd(fmt.Sprintf("sudo ln -s '%s' '%s'", caCertFile, certStorePath)) - rr, err := cr.RunCmd(cmd) - if err != nil { - return errors.Wrapf(err, "error making symbol link for certificate %s : %q", caCertFile, rr.Output()) + c = exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ln -s '%s' '%s'", caCertFile, certStorePath)) + + if rr, err := cr.RunCmd(c); err != nil { + return errors.Wrapf(err, "error making symbol link for certificate %s output: %s", caCertFile, rr.Output()) } } if hasSSLBinary { @@ -360,9 +362,10 @@ func configureCACerts(cr command.Runner, caCerts map[string]string) error { return errors.Wrapf(err, "error calculating subject hash for certificate %s", caCertFile) } subjectHashLink := path.Join(SSLCertStoreDir, fmt.Sprintf("%s.0", subjectHash)) - _, err = cr.RunCmd(command.ExecCmd(fmt.Sprintf("sudo test -f '%s'", subjectHashLink))) + + _, err = cr.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo test -f '%s'", subjectHashLink))) if err != nil { - if rr, err := cr.RunCmd(command.ExecCmd(fmt.Sprintf("sudo ln -s '%s' '%s'", certStorePath, subjectHashLink))); err != nil { + if rr, err := cr.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ln -s '%s' '%s'", certStorePath, subjectHashLink))); err != nil { return errors.Wrapf(err, "error making subject hash symbol %s link for certificate %s. cmd: %q output: %q", subjectHash, caCertFile, rr.Command(), rr.Output()) } } diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index 3de10157990a..54e51257154b 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -19,6 +19,7 @@ package kubeadm import ( "bytes" "crypto/tls" + "os/exec" "fmt" "net" @@ -136,8 +137,7 @@ func NewKubeadmBootstrapper(api libmachine.API) (*Bootstrapper, error) { // GetKubeletStatus returns the kubelet status func (k *Bootstrapper) GetKubeletStatus() (string, error) { - cmd := command.ExecCmd("sudo systemctl is-active kubelet") - rr, err := k.c.RunCmd(cmd) + rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "sudo systemctl is-active kubelet")) if err != nil { return "", errors.Wrapf(err, "getting kublet status. command: %q output: %q", rr.Command(), rr.Output()) } @@ -222,18 +222,15 @@ func etcdDataDir() string { // createCompatSymlinks creates compatibility symlinks to transition running services to new directory structures func (k *Bootstrapper) createCompatSymlinks() error { legacyEtcd := "/data/minikube" - cmd := command.ExecCmd(fmt.Sprintf("sudo test -d %s", legacyEtcd)) - rr, err := k.c.RunCmd(cmd) + rr, err := k.c.RunCmd(exec.Command(fmt.Sprintf("sudo test -d %s", legacyEtcd))) if err != nil { glog.Infof("%s check failed, skipping compat symlinks: %v %q", legacyEtcd, err, rr.Output()) return nil } - glog.Infof("Found %s, creating compatibility symlinks ...", legacyEtcd) - cmd = command.ExecCmd(fmt.Sprintf("sudo ln -s %s %s", legacyEtcd, etcdDataDir())) - rr, err = k.c.RunCmd(cmd) - if err != nil { + c := exec.Command(fmt.Sprintf("sudo ln -s %s %s", legacyEtcd, etcdDataDir())) + if rr, err = k.c.RunCmd(c); err != nil { return errors.Wrapf(err, "create symlink failed: %s\n%q\n", rr.Command(), rr.Output()) } return nil @@ -276,11 +273,10 @@ func (k *Bootstrapper) StartCluster(k8s config.KubernetesConfig) error { ignore = append(ignore, "SystemVerification") } - c := fmt.Sprintf("%s init --config %s %s --ignore-preflight-errors=%s", - invokeKubeadm(k8s.KubernetesVersion), yamlConfigPath, extraFlags, strings.Join(ignore, ",")) - rr, err := k.c.RunCmd(command.ExecCmd(c)) - if err != nil { - return errors.Wrapf(err, "init failed. cmd: %q\noutput:%q\n", rr.Command(), rr.Output()) + c := exec.Command("/bin/bash", "-c", fmt.Sprintf("%s init --config %s %s --ignore-preflight-errors=%s", + invokeKubeadm(k8s.KubernetesVersion), yamlConfigPath, extraFlags, strings.Join(ignore, ","))) + if rr, err := k.c.RunCmd(c); err != nil { + return errors.Wrapf(err, "init failed. cmd: %q output:%q", rr.Command(), rr.Output()) } glog.Infof("Configuring cluster permissions ...") @@ -305,7 +301,7 @@ func (k *Bootstrapper) StartCluster(k8s config.KubernetesConfig) error { // adjustResourceLimits makes fine adjustments to pod resources that aren't possible via kubeadm config. func (k *Bootstrapper) adjustResourceLimits() error { - rr, err := k.c.RunCmd(command.ExecCmd("cat /proc/$(pgrep kube-apiserver)/oom_adj")) + rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "cat /proc/$(pgrep kube-apiserver)/oom_adj")) if err != nil { return errors.Wrap(err, "oom_adj check. command: %q output: %q") } @@ -316,10 +312,9 @@ func (k *Bootstrapper) adjustResourceLimits() error { } glog.Infof("adjusting apiserver oom_adj to -10") - cmd := command.ExecCmd("echo -10 | sudo tee /proc/$(pgrep kube-apiserver)/oom_adj") // Prevent the apiserver from OOM'ing before other pods, as it is our gateway into the cluster. // It'd be preferable to do this via Kubernetes, but kubeadm doesn't have a way to set pod QoS. - rr, err = k.c.RunCmd(cmd) + rr, err = k.c.RunCmd(exec.Command("/bin/bash", "-c", "echo -10 | sudo tee /proc/$(pgrep kube-apiserver)/oom_adj")) if err != nil { return errors.Wrap(err, fmt.Sprintf("oom_adj adjust: %s", rr.Output())) } @@ -441,8 +436,7 @@ func (k *Bootstrapper) RestartCluster(k8s config.KubernetesConfig) error { // Run commands one at a time so that it is easier to root cause failures. for _, c := range cmds { - cmd := command.ExecCmd(c) - rr, err := k.c.RunCmd(cmd) + rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", c)) if err != nil { return errors.Wrapf(err, "running cmd: %s , output: %s", rr.Command(), rr.Output()) } @@ -451,11 +445,9 @@ func (k *Bootstrapper) RestartCluster(k8s config.KubernetesConfig) error { if err := k.waitForAPIServer(k8s); err != nil { return errors.Wrap(err, "waiting for apiserver") } - // restart the proxy and coredns - cmd := command.ExecCmd(fmt.Sprintf("%s phase addon all --config %s", baseCmd, yamlConfigPath)) - rr, err := k.c.RunCmd(cmd) - if err != nil { + // restart the proxy and coredns + if rr, err := k.c.RunCmd(exec.Command(fmt.Sprintf("%s phase addon all --config %s", baseCmd, yamlConfigPath))); err != nil { return errors.Wrapf(err, fmt.Sprintf("addon phase cmd:%q output:%q", rr.Command(), rr.Output())) } @@ -476,8 +468,7 @@ func (k *Bootstrapper) waitForAPIServer(k8s config.KubernetesConfig) error { // To give a better error message, first check for process existence via ssh // Needs minutes in case the image isn't cached (such as with v1.10.x) err := wait.PollImmediate(time.Millisecond*300, time.Minute*3, func() (bool, error) { - cmd := command.ExecCmd("sudo pgrep kube-apiserver") - rr, ierr := k.c.RunCmd(cmd) + rr, ierr := k.c.RunCmd(exec.Command("/bin/bash", "-c", "sudo pgrep kube-apiserver")) if ierr != nil { glog.Warningf("pgrep apiserver: %v cmd: %s output: %s", ierr, rr.Command(), rr.Output()) return false, nil @@ -521,8 +512,7 @@ func (k *Bootstrapper) DeleteCluster(k8s config.KubernetesConfig) error { c = fmt.Sprintf("%s reset", invokeKubeadm(k8s.KubernetesVersion)) } - rr, err := k.c.RunCmd(command.ExecCmd(c)) - if err != nil { + if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", c)); err != nil { return errors.Wrapf(err, "kubeadm reset: cmd: %q\noutput:%q\n", rr.Command(), rr.Output()) } @@ -539,8 +529,7 @@ func (k *Bootstrapper) PullImages(k8s config.KubernetesConfig) error { return fmt.Errorf("pull command is not supported by kubeadm v%s", version) } - cmd := command.ExecCmd(fmt.Sprintf("%s config images pull --config %s", invokeKubeadm(k8s.KubernetesVersion), yamlConfigPath)) - rr, err := k.c.RunCmd(cmd) + rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("%s config images pull --config %s", invokeKubeadm(k8s.KubernetesVersion), yamlConfigPath))) if err != nil { return errors.Wrapf(err, "running cmd: %q output: %q", rr.Command(), rr.Output()) } @@ -637,8 +626,7 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error { glog.Infof("kubelet %s config:\n%s", cfg.KubernetesVersion, kubeletCfg) // stop kubelet to avoid "Text File Busy" error - rr, err := k.c.RunCmd(command.ExecCmd("pgrep kubelet && sudo systemctl stop kubelet")) - if err != nil { + if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "pgrep kubelet && sudo systemctl stop kubelet")); err != nil { glog.Warningf("unable to stop kubelet: %s command: %q output: %q", err, rr.Command(), rr.Output()) } if err := transferBinaries(cfg, k.c); err != nil { @@ -654,8 +642,7 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error { } } - rr, err = k.c.RunCmd(command.ExecCmd("sudo systemctl daemon-reload && sudo systemctl start kubelet")) - if err != nil { + if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "sudo systemctl daemon-reload && sudo systemctl start kubelet")); err != nil { return errors.Wrapf(err, "starting kubelet command: %q output: %q", rr.Command(), rr.Output()) } return nil diff --git a/pkg/minikube/command/exec_runner.go b/pkg/minikube/command/exec_runner.go index 7ce29dd4ca8e..cea3743f85fa 100644 --- a/pkg/minikube/command/exec_runner.go +++ b/pkg/minikube/command/exec_runner.go @@ -24,7 +24,6 @@ import ( "path" "path/filepath" "strconv" - "strings" "time" "github.com/golang/glog" @@ -32,12 +31,6 @@ import ( "k8s.io/minikube/pkg/minikube/assets" ) -// ExecCmd returns a exec.Cmd from a string -func ExecCmd(c string) *exec.Cmd { - args := strings.Split(c, " ") // maybe alternatively? ("/bin/bash", "-c", c) - return exec.Command(args[0], args[1:]...) -} - // ExecRunner runs commands using the os/exec package. // // It implements the CommandRunner interface. From 25e3d870e51ad974d49a68131596e8667dc591b3 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Tue, 8 Oct 2019 17:08:38 -0700 Subject: [PATCH 22/59] fixing with shelquote --- go.mod | 1 + go.sum | 2 ++ pkg/drivers/none/none.go | 12 ++++++------ pkg/minikube/bootstrapper/kubeadm/kubeadm.go | 2 +- pkg/minikube/command/ssh_runner.go | 9 +++++++-- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 80bd0d20550f..379119217a29 100644 --- a/go.mod +++ b/go.mod @@ -44,6 +44,7 @@ require ( github.com/juju/testing v0.0.0-20190723135506-ce30eb24acd2 // indirect github.com/juju/utils v0.0.0-20180820210520-bf9cc5bdd62d // indirect github.com/juju/version v0.0.0-20180108022336-b64dbd566305 // indirect + github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/libvirt/libvirt-go v3.4.0+incompatible github.com/machine-drivers/docker-machine-driver-vmware v0.1.1 github.com/mattn/go-isatty v0.0.8 diff --git a/go.sum b/go.sum index cae562ed96dd..d987e7ac51c9 100644 --- a/go.sum +++ b/go.sum @@ -296,6 +296,8 @@ github.com/juju/version v0.0.0-20180108022336-b64dbd566305 h1:lQxPJ1URr2fjsKnJRt github.com/juju/version v0.0.0-20180108022336-b64dbd566305/go.mod h1:kE8gK5X0CImdr7qpSKl3xB2PmpySSmfj7zVbkZFs81U= github.com/kardianos/osext v0.0.0-20150410034420-8fef92e41e22/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= diff --git a/pkg/drivers/none/none.go b/pkg/drivers/none/none.go index 9f57f5387c47..f0a7b38d33c1 100644 --- a/pkg/drivers/none/none.go +++ b/pkg/drivers/none/none.go @@ -26,6 +26,7 @@ import ( "github.com/docker/machine/libmachine/drivers" "github.com/docker/machine/libmachine/state" "github.com/golang/glog" + "github.com/kballard/go-shellquote" "github.com/pkg/errors" "k8s.io/apimachinery/pkg/util/net" pkgdrivers "k8s.io/minikube/pkg/drivers" @@ -172,8 +173,7 @@ func (d *Driver) Remove() error { return errors.Wrap(err, "kill") } glog.Infof("Removing: %s", cleanupPaths) - c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo rm -rf %s", strings.Join(cleanupPaths, " "))) - + c := exec.Command("sudo", "rm", "-rf", shellquote.Join(cleanupPaths...)) if rr, err := d.exec.RunCmd(c); err != nil { glog.Errorf("cleanup incomplete: %v , output: %s", err, rr.Output()) } @@ -225,12 +225,12 @@ func (d *Driver) RunSSHCommandFromDriver() error { func stopKubelet(cr command.Runner) error { glog.Infof("stopping kubelet.service ...") stop := func() error { - cmdStop := exec.Command("/bin/bash", "-c", "sudo systemctl stop kubelet.service") + cmdStop := exec.Command("sudo", "systemctl", "stop", "kubelet.service") if rr, err := cr.RunCmd(cmdStop); err != nil { glog.Errorf("temporary error for %q : %v", rr.Command(), err) } var out bytes.Buffer - cmdCheck := exec.Command("/bin/bash", "-c", "sudo systemctl show -p SubState kubelet") + cmdCheck := exec.Command("sudo", "systemctl", "show", "-p", "SubState", "kubelet") cmdCheck.Stdout = &out cmdCheck.Stderr = &out if rr, err := cr.RunCmd(cmdCheck); err != nil { @@ -252,7 +252,7 @@ func stopKubelet(cr command.Runner) error { // restartKubelet restarts the kubelet func restartKubelet(cr command.Runner) error { glog.Infof("restarting kubelet.service ...") - c := exec.Command("/bin/bash", "-c", "sudo systemctl restart kubelet.service") + c := exec.Command("sudo", "systemctl", "restart", "kubelet.service") if rr, err := cr.RunCmd(c); err != nil { return errors.Wrapf(err, "restartKubelet output: %s", rr.Output()) } @@ -262,7 +262,7 @@ func restartKubelet(cr command.Runner) error { // checkKubelet returns an error if the kubelet is not running. func checkKubelet(cr command.Runner) error { glog.Infof("checking for running kubelet ...") - c := exec.Command("/bin/bash", "-c", "systemctl is-active --quiet service kubelet") + c := exec.Command("systemctl", "is-active", "--quiet", "service", "kubelet") if rr, err := cr.RunCmd(c); err != nil { return errors.Wrapf(err, "checkKubelet output: %s", rr.Output()) } diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index 54e51257154b..b0a9cf943888 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -447,7 +447,7 @@ func (k *Bootstrapper) RestartCluster(k8s config.KubernetesConfig) error { } // restart the proxy and coredns - if rr, err := k.c.RunCmd(exec.Command(fmt.Sprintf("%s phase addon all --config %s", baseCmd, yamlConfigPath))); err != nil { + if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("%s phase addon all --config %s", baseCmd, yamlConfigPath))); err != nil { return errors.Wrapf(err, fmt.Sprintf("addon phase cmd:%q output:%q", rr.Command(), rr.Output())) } diff --git a/pkg/minikube/command/ssh_runner.go b/pkg/minikube/command/ssh_runner.go index 537ad6c66331..ad31bde8099f 100644 --- a/pkg/minikube/command/ssh_runner.go +++ b/pkg/minikube/command/ssh_runner.go @@ -23,11 +23,11 @@ import ( "io" "os/exec" "path" - "strings" "sync" "time" "github.com/golang/glog" + "github.com/kballard/go-shellquote" "github.com/pkg/errors" "golang.org/x/crypto/ssh" "golang.org/x/sync/errgroup" @@ -125,7 +125,12 @@ func (s *SSHRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { }() elapsed := time.Since(start) - err = teeSSH(sess, strings.Join(cmd.Args, " "), &outb, &errb) + fmt.Println("------------------------------MEDYAAAAAAAA------------------------------") + fmt.Printf("raw args:+%v", cmd.Args) + fmt.Printf("shellquote:{{{%s}}}", shellquote.Join(cmd.Args...)) + fmt.Println("------------------------------END MEDYAAAAAAAA------------------------------") + + err = teeSSH(sess, shellquote.Join(cmd.Args...), &outb, &errb) if err == nil { // Reduce log spam if elapsed > (1 * time.Second) { From 83f736d9ff87f60468c43a1af0b0cdf0063ccafa Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Tue, 8 Oct 2019 17:33:19 -0700 Subject: [PATCH 23/59] fix unit test for cert --- pkg/minikube/bootstrapper/certs_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/minikube/bootstrapper/certs_test.go b/pkg/minikube/bootstrapper/certs_test.go index e6a25f484e4d..d7083b7c8a4f 100644 --- a/pkg/minikube/bootstrapper/certs_test.go +++ b/pkg/minikube/bootstrapper/certs_test.go @@ -62,9 +62,9 @@ func TestSetupCerts(t *testing.T) { certStorePath := path.Join(SSLCertStoreDir, dst) certNameHash := "abcdef" remoteCertHashLink := path.Join(SSLCertStoreDir, fmt.Sprintf("%s.0", certNameHash)) - cmdMap[fmt.Sprintf("sudo ln -s '%s' '%s'", certFile, certStorePath)] = "1" - cmdMap[fmt.Sprintf("openssl x509 -hash -noout -in '%s'", certFile)] = certNameHash - cmdMap[fmt.Sprintf("sudo ln -s '%s' '%s'", certStorePath, remoteCertHashLink)] = "1" + cmdMap[fmt.Sprintf("/bin/bash -c sudo ln -s '%s' '%s'", certFile, certStorePath)] = "1" + cmdMap[fmt.Sprintf("/bin/bash -c openssl x509 -hash -noout -in '%s'", certFile)] = certNameHash + cmdMap[fmt.Sprintf("/bin/bash -c sudo ln -s '%s' '%s'", certStorePath, remoteCertHashLink)] = "1" } f := command.NewFakeCommandRunner() f.SetCommandToOutput(cmdMap) From da5cae6af055ab48d58c8ff81d8f0f925d30ecc4 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Tue, 8 Oct 2019 18:31:02 -0700 Subject: [PATCH 24/59] shellquoting more --- pkg/minikube/bootstrapper/kubeadm/kubeadm.go | 15 +++++++++++++-- pkg/minikube/command/ssh_runner.go | 5 ----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index b0a9cf943888..ad630101f9aa 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -35,6 +35,7 @@ import ( "github.com/docker/machine/libmachine" "github.com/docker/machine/libmachine/state" "github.com/golang/glog" + "github.com/kballard/go-shellquote" "github.com/pkg/errors" "golang.org/x/sync/errgroup" "k8s.io/apimachinery/pkg/labels" @@ -625,10 +626,16 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error { glog.Infof("kubelet %s config:\n%s", cfg.KubernetesVersion, kubeletCfg) + stopCmd, err := shellquote.Split("pgrep kubelet && sudo systemctl stop kubelet") + if err != nil { + return errors.Wrapf(err, "shellquote split") + } + // stop kubelet to avoid "Text File Busy" error - if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "pgrep kubelet && sudo systemctl stop kubelet")); err != nil { + if rr, err := k.c.RunCmd(exec.Command("/bin/bash -c", stopCmd...)); err != nil { glog.Warningf("unable to stop kubelet: %s command: %q output: %q", err, rr.Command(), rr.Output()) } + if err := transferBinaries(cfg, k.c); err != nil { return errors.Wrap(err, "downloading binaries") } @@ -642,7 +649,11 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error { } } - if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "sudo systemctl daemon-reload && sudo systemctl start kubelet")); err != nil { + c, err := shellquote.Split("sudo systemctl daemon-reload && sudo systemctl start kubelet") + if err != nil { + return errors.Wrapf(err, "shellquote cmd") + } + if rr, err := k.c.RunCmd(exec.Command("/bin/bash -c", c...)); err != nil { return errors.Wrapf(err, "starting kubelet command: %q output: %q", rr.Command(), rr.Output()) } return nil diff --git a/pkg/minikube/command/ssh_runner.go b/pkg/minikube/command/ssh_runner.go index ad31bde8099f..9213681bb31b 100644 --- a/pkg/minikube/command/ssh_runner.go +++ b/pkg/minikube/command/ssh_runner.go @@ -125,11 +125,6 @@ func (s *SSHRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { }() elapsed := time.Since(start) - fmt.Println("------------------------------MEDYAAAAAAAA------------------------------") - fmt.Printf("raw args:+%v", cmd.Args) - fmt.Printf("shellquote:{{{%s}}}", shellquote.Join(cmd.Args...)) - fmt.Println("------------------------------END MEDYAAAAAAAA------------------------------") - err = teeSSH(sess, shellquote.Join(cmd.Args...), &outb, &errb) if err == nil { // Reduce log spam From 79e65c1b44ad80f57fe195d3faa58fd00dfb7805 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Tue, 8 Oct 2019 19:23:05 -0700 Subject: [PATCH 25/59] fix --- pkg/minikube/bootstrapper/kubeadm/kubeadm.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index ad630101f9aa..d4da43aa255b 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -649,11 +649,11 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error { } } - c, err := shellquote.Split("sudo systemctl daemon-reload && sudo systemctl start kubelet") + c, err := shellquote.Split("-c sudo systemctl daemon-reload && sudo systemctl start kubelet") if err != nil { return errors.Wrapf(err, "shellquote cmd") } - if rr, err := k.c.RunCmd(exec.Command("/bin/bash -c", c...)); err != nil { + if rr, err := k.c.RunCmd(exec.Command("/bin/bash", c...)); err != nil { return errors.Wrapf(err, "starting kubelet command: %q output: %q", rr.Command(), rr.Output()) } return nil From 7109b222492a7eb6f3c839c8f0c4caf2dc0659b4 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Wed, 9 Oct 2019 16:06:13 -0700 Subject: [PATCH 26/59] refactor more --- pkg/minikube/bootstrapper/certs.go | 22 +++++---- pkg/minikube/bootstrapper/kubeadm/kubeadm.go | 27 ++++------- pkg/minikube/cluster/mount.go | 42 ++++++++--------- pkg/minikube/command/command_runner.go | 18 -------- pkg/minikube/cruntime/containerd.go | 35 ++++++++++++--- pkg/minikube/cruntime/cri.go | 47 ++++++++++++++++---- pkg/minikube/cruntime/crio.go | 31 ++++++++++--- pkg/minikube/cruntime/cruntime.go | 16 ++++--- pkg/minikube/logs/logs.go | 34 ++++++++++---- 9 files changed, 169 insertions(+), 103 deletions(-) diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index d7c821296ce6..9349c88b13df 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -319,13 +319,12 @@ func collectCACerts() (map[string]string, error) { } // getSubjectHash calculates Certificate Subject Hash for creating certificate symlinks -func getSubjectHash(cmd command.Runner, filePath string) (string, error) { - out, err := cmd.CombinedOutput(fmt.Sprintf("openssl x509 -hash -noout -in '%s'", filePath)) +func getSubjectHash(cr command.Runner, filePath string) (string, error) { + rr, err := cr.RunCmd(exec.Command("openssl", "x509", "-hash", "-noout", "-in", fmt.Sprintf("'%s'", filePath))) if err != nil { - return "", err + return "", errors.Wrapf(err, "getSubjectHash") } - - stringHash := strings.TrimSpace(out) + stringHash := strings.TrimSpace(rr.Stdout.String()) return stringHash, nil } @@ -333,7 +332,7 @@ func getSubjectHash(cmd command.Runner, filePath string) (string, error) { // OpenSSL binary required in minikube ISO func configureCACerts(cr command.Runner, caCerts map[string]string) error { hasSSLBinary := true - c := exec.Command("/bin/bash", "-c", "which openssl") + c := exec.Command("/bin/bash", "-c", "which", "openssl") _, err := cr.RunCmd(c) if err != nil { hasSSLBinary = false @@ -347,10 +346,9 @@ func configureCACerts(cr command.Runner, caCerts map[string]string) error { dstFilename := path.Base(caCertFile) certStorePath := path.Join(SSLCertStoreDir, dstFilename) - c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo test -f '%s'", certStorePath)) - _, err := cr.RunCmd(c) + _, err := cr.RunCmd(exec.Command("/bin/bash", "-c", "sudo", "test", "-f", "%s", certStorePath)) if err != nil { - c = exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ln -s '%s' '%s'", caCertFile, certStorePath)) + c = exec.Command("/bin/bash", "-c", "sudo", "ln", "-s", caCertFile, certStorePath) if rr, err := cr.RunCmd(c); err != nil { return errors.Wrapf(err, "error making symbol link for certificate %s output: %s", caCertFile, rr.Output()) @@ -363,10 +361,10 @@ func configureCACerts(cr command.Runner, caCerts map[string]string) error { } subjectHashLink := path.Join(SSLCertStoreDir, fmt.Sprintf("%s.0", subjectHash)) - _, err = cr.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo test -f '%s'", subjectHashLink))) + _, err = cr.RunCmd(exec.Command("/bin/bash", "-c", "sudo", "test", "-f", subjectHashLink)) if err != nil { - if rr, err := cr.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ln -s '%s' '%s'", certStorePath, subjectHashLink))); err != nil { - return errors.Wrapf(err, "error making subject hash symbol %s link for certificate %s. cmd: %q output: %q", subjectHash, caCertFile, rr.Command(), rr.Output()) + if rr, err := cr.RunCmd(exec.Command("/bin/bash", "-c", "sudo", "ln", "-s", certStorePath, subjectHashLink)); err != nil { + return errors.Wrapf(err, "error making subject hash symbol %s link for certificate %s. output: %q", subjectHash, caCertFile, rr.Output()) } } } diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index d4da43aa255b..ae8b712f4b32 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -35,7 +35,6 @@ import ( "github.com/docker/machine/libmachine" "github.com/docker/machine/libmachine/state" "github.com/golang/glog" - "github.com/kballard/go-shellquote" "github.com/pkg/errors" "golang.org/x/sync/errgroup" "k8s.io/apimachinery/pkg/labels" @@ -138,7 +137,7 @@ func NewKubeadmBootstrapper(api libmachine.API) (*Bootstrapper, error) { // GetKubeletStatus returns the kubelet status func (k *Bootstrapper) GetKubeletStatus() (string, error) { - rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "sudo systemctl is-active kubelet")) + rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "sudo", "systemctl", "is-active", "kubelet")) if err != nil { return "", errors.Wrapf(err, "getting kublet status. command: %q output: %q", rr.Command(), rr.Output()) } @@ -274,8 +273,7 @@ func (k *Bootstrapper) StartCluster(k8s config.KubernetesConfig) error { ignore = append(ignore, "SystemVerification") } - c := exec.Command("/bin/bash", "-c", fmt.Sprintf("%s init --config %s %s --ignore-preflight-errors=%s", - invokeKubeadm(k8s.KubernetesVersion), yamlConfigPath, extraFlags, strings.Join(ignore, ","))) + c := exec.Command("/bin/bash", "-c", "init", "--config", invokeKubeadm(k8s.KubernetesVersion), yamlConfigPath, extraFlags, fmt.Sprintf("--ignore-preflight-errors=%s", strings.Join(ignore, ","))) if rr, err := k.c.RunCmd(c); err != nil { return errors.Wrapf(err, "init failed. cmd: %q output:%q", rr.Command(), rr.Output()) } @@ -302,7 +300,7 @@ func (k *Bootstrapper) StartCluster(k8s config.KubernetesConfig) error { // adjustResourceLimits makes fine adjustments to pod resources that aren't possible via kubeadm config. func (k *Bootstrapper) adjustResourceLimits() error { - rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "cat /proc/$(pgrep kube-apiserver)/oom_adj")) + rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "cat", "/proc/$(pgrep kube-apiserver)/oom_adj")) if err != nil { return errors.Wrap(err, "oom_adj check. command: %q output: %q") } @@ -315,7 +313,7 @@ func (k *Bootstrapper) adjustResourceLimits() error { // Prevent the apiserver from OOM'ing before other pods, as it is our gateway into the cluster. // It'd be preferable to do this via Kubernetes, but kubeadm doesn't have a way to set pod QoS. - rr, err = k.c.RunCmd(exec.Command("/bin/bash", "-c", "echo -10 | sudo tee /proc/$(pgrep kube-apiserver)/oom_adj")) + rr, err = k.c.RunCmd(exec.Command("/bin/bash", "-c", "echo", "-10", "|", "sudo", "tee", "/proc/$(pgrep kube-apiserver)/oom_adj")) if err != nil { return errors.Wrap(err, fmt.Sprintf("oom_adj adjust: %s", rr.Output())) } @@ -448,7 +446,7 @@ func (k *Bootstrapper) RestartCluster(k8s config.KubernetesConfig) error { } // restart the proxy and coredns - if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("%s phase addon all --config %s", baseCmd, yamlConfigPath))); err != nil { + if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", baseCmd, "phase", "addon", "all", "--config", yamlConfigPath)); err != nil { return errors.Wrapf(err, fmt.Sprintf("addon phase cmd:%q output:%q", rr.Command(), rr.Output())) } @@ -626,13 +624,10 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error { glog.Infof("kubelet %s config:\n%s", cfg.KubernetesVersion, kubeletCfg) - stopCmd, err := shellquote.Split("pgrep kubelet && sudo systemctl stop kubelet") - if err != nil { - return errors.Wrapf(err, "shellquote split") - } + stopCmd := exec.Command("/bin/bash", "-c", "pgrep", "kubelet", "&&", "sudo", "systemctl", "stop", "kubelet") // stop kubelet to avoid "Text File Busy" error - if rr, err := k.c.RunCmd(exec.Command("/bin/bash -c", stopCmd...)); err != nil { + if rr, err := k.c.RunCmd(stopCmd); err != nil { glog.Warningf("unable to stop kubelet: %s command: %q output: %q", err, rr.Command(), rr.Output()) } @@ -649,12 +644,8 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error { } } - c, err := shellquote.Split("-c sudo systemctl daemon-reload && sudo systemctl start kubelet") - if err != nil { - return errors.Wrapf(err, "shellquote cmd") - } - if rr, err := k.c.RunCmd(exec.Command("/bin/bash", c...)); err != nil { - return errors.Wrapf(err, "starting kubelet command: %q output: %q", rr.Command(), rr.Output()) + if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "sudo", "systemctl", "daemon-reload", "&&", "sudo", "systemctl", "start", "kubelet")); err != nil { + return errors.Wrapf(err, "starting kubelet, output: %s", rr.Output()) } return nil } diff --git a/pkg/minikube/cluster/mount.go b/pkg/minikube/cluster/mount.go index 59e3af10558e..79fd63e13229 100644 --- a/pkg/minikube/cluster/mount.go +++ b/pkg/minikube/cluster/mount.go @@ -19,12 +19,14 @@ package cluster import ( "fmt" "os" + "os/exec" "sort" "strconv" "strings" "github.com/golang/glog" "github.com/pkg/errors" + "k8s.io/minikube/pkg/minikube/command" ) // MountConfig defines the options available to the Mount command @@ -49,7 +51,7 @@ type MountConfig struct { // mountRunner is the subset of CommandRunner used for mounting type mountRunner interface { - CombinedOutput(string) (string, error) + RunCmd(*exec.Cmd) (*command.RunResult, error) } // Mount runs the mount command from the 9p client on the VM to the 9p server on the host @@ -58,14 +60,19 @@ func Mount(r mountRunner, source string, target string, c *MountConfig) error { return errors.Wrap(err, "umount") } - cmd := fmt.Sprintf("sudo mkdir -m %o -p %s && %s", c.Mode, target, mntCmd(source, target, c)) - glog.Infof("Will run: %s", cmd) - out, err := r.CombinedOutput(cmd) + rr, err := r.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo mkdir -m %o -p %s && %s", c.Mode, target))) if err != nil { - glog.Infof("%s failed: err=%s, output: %q", cmd, err, out) - return errors.Wrap(err, out) + glog.Infof("Failed to create folder pre-mount: err=%v, output: %q", err, rr.Output()) + return errors.Wrap(err, "create folder pre-mount") } - glog.Infof("%s output: %q", cmd, out) + + rr, err := r.RunCmd(mntCmd(source, target, c)) + if err != nil { + glog.Infof("Failed to create folder before mount: err=%s, output: %q", err, rr.Output()) + return errors.Wrap(err, rr.Output()) + } + + glog.Infof("%s output: %q", rr.Command(), rr.Output()) return nil } @@ -97,7 +104,7 @@ func resolveGID(id string) string { } // mntCmd returns a mount command based on a config. -func mntCmd(source string, target string, c *MountConfig) string { +func mntCmd(source string, target string, c *MountConfig) *exec.Cmd { options := map[string]string{ "dfltgid": resolveGID(c.GID), "dfltuid": resolveUID(c.UID), @@ -128,23 +135,18 @@ func mntCmd(source string, target string, c *MountConfig) string { opts = append(opts, fmt.Sprintf("%s=%s", k, v)) } sort.Strings(opts) - return fmt.Sprintf("sudo mount -t %s -o %s %s %s", c.Type, strings.Join(opts, ","), source, target) -} - -// umountCmd returns a command for unmounting -func umountCmd(target string) string { - // grep because findmnt will also display the parent! - return fmt.Sprintf("[ \"x$(findmnt -T %s | grep %s)\" != \"x\" ] && sudo umount -f %s || echo ", target, target, target) + return exec.Command("/bin/bash", "-c", "sudo", "mount", "-t", c.Type, "-o", strings.Join(opts, ","), source, target) } // Unmount unmounts a path func Unmount(r mountRunner, target string) error { - cmd := umountCmd(target) - glog.Infof("Will run: %s", cmd) - out, err := r.CombinedOutput(cmd) - glog.Infof("unmount force err=%v, out=%s", err, out) + // grep because findmnt will also display the parent! + c := exec.Command("/bin/bash", "-c", fmt.Sprintf("[ \"x$(findmnt -T %s | grep %s)\" != \"x\" ] && sudo umount -f %s || echo ", target, target, target)) + rr, err := r.RunCmd(c) if err != nil { - return errors.Wrap(err, out) + glog.Infof("unmount force err=%v, out=%s", err, rr.Output()) + return errors.Wrap(err, rr.Output()) } + glog.Infof("unmount for %s ran successfully", target) return nil } diff --git a/pkg/minikube/command/command_runner.go b/pkg/minikube/command/command_runner.go index 20fab53ff7e4..ad1b9f365886 100644 --- a/pkg/minikube/command/command_runner.go +++ b/pkg/minikube/command/command_runner.go @@ -19,7 +19,6 @@ package command import ( "bytes" "fmt" - "io" "os/exec" "path" "strings" @@ -43,23 +42,6 @@ type Runner interface { // Run starts the specified command and waits for it to complete. Run(cmd string) error - // CombinedOutputTo runs the command and stores both command - // output and error to out. A typical usage is: - // - // var b bytes.Buffer - // CombinedOutput(cmd, &b) - // fmt.Println(b.Bytes()) - // - // Or, you can set out to os.Stdout, the command output and - // error would show on your terminal immediately before you - // cmd exit. This is useful for a long run command such as - // continuously print running logs. - CombinedOutputTo(cmd string, out io.Writer) error - - // CombinedOutput runs the command and returns its combined standard - // output and standard error. - CombinedOutput(cmd string) (string, error) - // Copy is a convenience method that runs a command to copy a file Copy(assets.CopyableFile) error diff --git a/pkg/minikube/cruntime/containerd.go b/pkg/minikube/cruntime/containerd.go index a39298edf526..0d2e0aaac1b9 100644 --- a/pkg/minikube/cruntime/containerd.go +++ b/pkg/minikube/cruntime/containerd.go @@ -20,11 +20,13 @@ import ( "bytes" "encoding/base64" "fmt" + "os/exec" "path" "strings" "text/template" "github.com/golang/glog" + "github.com/pkg/errors" "k8s.io/minikube/pkg/minikube/bootstrapper/images" "k8s.io/minikube/pkg/minikube/out" ) @@ -152,13 +154,18 @@ func (r *Containerd) DefaultCNI() bool { // Active returns if containerd is active on the host func (r *Containerd) Active() bool { - err := r.Runner.Run("systemctl is-active --quiet service containerd") + c := exec.Command("/bin/bash", "-c", "systemctl", "is-active", "--quiet", "service", "containerd") + _, err := r.Runner.RunCmd(c) return err == nil } // Available returns an error if it is not possible to use this runtime on a host func (r *Containerd) Available() error { - return r.Runner.Run("command -v containerd") + c := exec.Command("/bin/bash", "-c", "command", "-v", "containerd") + if rr, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrapf(err, "check containerd availabilty. output: %s", rr.Output()) + } + return nil } // generateContainerdConfig sets up /etc/containerd/config.toml @@ -174,7 +181,11 @@ func generateContainerdConfig(cr CommandRunner, imageRepository string, k8sVersi if err := t.Execute(&b, opts); err != nil { return err } - return cr.Run(fmt.Sprintf("sudo mkdir -p %s && printf %%s \"%s\" | base64 -d | sudo tee %s", path.Dir(cPath), base64.StdEncoding.EncodeToString(b.Bytes()), cPath)) + c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo mkdir -p %s && printf %%s \"%s\" | base64 -d | sudo tee %s", path.Dir(cPath), base64.StdEncoding.EncodeToString(b.Bytes()), cPath)) + if rr, err := cr.RunCmd(c); err != nil { + return errors.Wrapf(err, "generate containerd cfg. ouptut: %s", rr.Output()) + } + return nil } // Enable idempotently enables containerd on a host @@ -194,18 +205,30 @@ func (r *Containerd) Enable(disOthers bool) error { return err } // Otherwise, containerd will fail API requests with 'Unimplemented' - return r.Runner.Run("sudo systemctl restart containerd") + c := exec.Command("/bin/bash", "-c", "sudo", "systemctl", "restart", "containerd") + if rr, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrapf(err, "enable containrd. output: %q", rr.Output()) + } + return nil } // Disable idempotently disables containerd on a host func (r *Containerd) Disable() error { - return r.Runner.Run("sudo systemctl stop containerd") + c := exec.Command("/bin/bash", "-c", "sudo", "systemctl", "stop", "containerd") + if rr, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrapf(err, "disable containrd. output: %q", rr.Output()) + } + return nil } // LoadImage loads an image into this runtime func (r *Containerd) LoadImage(path string) error { glog.Infof("Loading image: %s", path) - return r.Runner.Run(fmt.Sprintf("sudo ctr -n=k8s.io images import %s", path)) + c := exec.Command("/bin/bash", "-c", "ctr", "-n=k8s.io", "images", "import", path) + if rr, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrapf(err, "disable containrd. output: %q", rr.Output()) + } + return nil } // KubeletOptions returns kubelet options for a containerd diff --git a/pkg/minikube/cruntime/cri.go b/pkg/minikube/cruntime/cri.go index d3c8fd6e1302..98c22465cc78 100644 --- a/pkg/minikube/cruntime/cri.go +++ b/pkg/minikube/cruntime/cri.go @@ -21,11 +21,14 @@ import ( "encoding/base64" "fmt" "html/template" + "os/exec" "path" "strings" "github.com/golang/glog" + "github.com/pkg/errors" "k8s.io/minikube/pkg/minikube/bootstrapper/images" + "k8s.io/minikube/pkg/minikube/command" ) const ( @@ -330,19 +333,21 @@ plugin_dirs = [ // listCRIContainers returns a list of containers using crictl func listCRIContainers(cr CommandRunner, filter string) ([]string, error) { - var content string var err error + var rr *command.RunResult state := "Running" if filter != "" { - content, err = cr.CombinedOutput(fmt.Sprintf(`sudo crictl ps -a --name=%s --state=%s --quiet`, filter, state)) + c := exec.Command("/bin/bash/", "-c", fmt.Sprintf(`sudo crictl ps -a --name=%s --state=%s --quiet`, filter, state)) + rr, err = cr.RunCmd(c) } else { - content, err = cr.CombinedOutput(fmt.Sprintf(`sudo crictl ps -a --state=%s --quiet`, state)) + c := exec.Command("/bin/bash/", "-c", fmt.Sprintf(`sudo crictl ps -a --state=%s --quiet`, state)) + rr, err = cr.RunCmd(c) } if err != nil { - return nil, err + return nil, errors.Wrap(err, rr.Output()) } var ids []string - for _, line := range strings.Split(content, "\n") { + for _, line := range strings.Split(rr.Stderr.String(), "\n") { if line != "" { ids = append(ids, line) } @@ -356,7 +361,12 @@ func killCRIContainers(cr CommandRunner, ids []string) error { return nil } glog.Infof("Killing containers: %s", ids) - return cr.Run(fmt.Sprintf("sudo crictl rm %s", strings.Join(ids, " "))) + c := exec.Command(fmt.Sprintf("sudo crictl rm %s", strings.Join(ids, " "))) + rr, err := cr.RunCmd(c) + if err != nil { + return errors.Wrapf(err, "kill cri containers. output %s", rr.Output()) + } + return nil } // stopCRIContainers stops containers using crictl @@ -365,7 +375,13 @@ func stopCRIContainers(cr CommandRunner, ids []string) error { return nil } glog.Infof("Stopping containers: %s", ids) - return cr.Run(fmt.Sprintf("sudo crictl stop %s", strings.Join(ids, " "))) + c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo crictl rm %s", strings.Join(ids, " "))) + rr, err := cr.RunCmd(c) + if err != nil { + return errors.Wrapf(err, "stop cri containers. output %s", rr.Output()) + } + return nil + } // populateCRIConfig sets up /etc/crictl.yaml @@ -383,7 +399,13 @@ image-endpoint: unix://{{.Socket}} if err := t.Execute(&b, opts); err != nil { return err } - return cr.Run(fmt.Sprintf("sudo mkdir -p %s && printf %%s \"%s\" | sudo tee %s", path.Dir(cPath), b.String(), cPath)) + c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo mkdir -p %s && printf %%s \"%s\" | sudo tee %s", path.Dir(cPath), b.String(), cPath)) + if rr, err := cr.RunCmd(c); err != nil { + if err != nil { + return errors.Wrapf(err, "populateCRIConfig %s", rr.Output()) + } + } + return nil } // generateCRIOConfig sets up /etc/crio/crio.conf @@ -399,7 +421,14 @@ func generateCRIOConfig(cr CommandRunner, imageRepository string, k8sVersion str if err := t.Execute(&b, opts); err != nil { return err } - return cr.Run(fmt.Sprintf("sudo mkdir -p %s && printf %%s \"%s\" | base64 -d | sudo tee %s", path.Dir(cPath), base64.StdEncoding.EncodeToString(b.Bytes()), cPath)) + + c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo mkdir -p %s && printf %%s \"%s\" | base64 -d | sudo tee %s", path.Dir(cPath), base64.StdEncoding.EncodeToString(b.Bytes()), cPath)) + if rr, err := cr.RunCmd(c); err != nil { + if err != nil { + return errors.Wrapf(err, "generateCRIOConfig. %s", rr.Output()) + } + } + return nil } // criContainerLogCmd returns the command to retrieve the log for a container based on ID diff --git a/pkg/minikube/cruntime/crio.go b/pkg/minikube/cruntime/crio.go index cecefa3c8f1a..07bdb041f9a1 100644 --- a/pkg/minikube/cruntime/crio.go +++ b/pkg/minikube/cruntime/crio.go @@ -18,9 +18,11 @@ package cruntime import ( "fmt" + "os/exec" "strings" "github.com/golang/glog" + "github.com/pkg/errors" "k8s.io/minikube/pkg/minikube/out" ) @@ -70,12 +72,18 @@ func (r *CRIO) DefaultCNI() bool { // Available returns an error if it is not possible to use this runtime on a host func (r *CRIO) Available() error { - return r.Runner.Run("command -v crio") + c := exec.Command("/bin/bash", "-c", "command", "-v", "crio") + if rr, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrapf(err, "check crio available. output: %s", rr.Output()) + } + return nil + } // Active returns if CRIO is active on the host func (r *CRIO) Active() bool { - err := r.Runner.Run("systemctl is-active --quiet service crio") + c := exec.Command("/bin/bash", "-c", "systemctl is-active --quiet service crio") + _, err := r.Runner.RunCmd(c) return err == nil } @@ -95,18 +103,31 @@ func (r *CRIO) Enable(disOthers bool) error { if err := enableIPForwarding(r.Runner); err != nil { return err } - return r.Runner.Run("sudo systemctl restart crio") + + c := exec.Command("/bin/bash", "-c", "sudo systemctl restart crio") + if rr, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrapf(err, "enable crio. output: %s", rr.Output()) + } + return nil } // Disable idempotently disables CRIO on a host func (r *CRIO) Disable() error { - return r.Runner.Run("sudo systemctl stop crio") + c := exec.Command("/bin/bash", "-c", "sudo systemctl stop crio") + if rr, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrapf(err, "disable crio. output: %s", rr.Output()) + } + return nil } // LoadImage loads an image into this runtime func (r *CRIO) LoadImage(path string) error { glog.Infof("Loading image: %s", path) - return r.Runner.Run(fmt.Sprintf("sudo podman load -i %s", path)) + c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo podman load -i %s", path)) + if rr, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrapf(err, "LoadImage crio. output: %s", rr.Output()) + } + return nil } // KubeletOptions returns kubelet options for a runtime. diff --git a/pkg/minikube/cruntime/cruntime.go b/pkg/minikube/cruntime/cruntime.go index a7a17e9ffd46..ddabd4a6fcf2 100644 --- a/pkg/minikube/cruntime/cruntime.go +++ b/pkg/minikube/cruntime/cruntime.go @@ -19,16 +19,17 @@ package cruntime import ( "fmt" + "os/exec" "github.com/golang/glog" "github.com/pkg/errors" + "k8s.io/minikube/pkg/minikube/command" "k8s.io/minikube/pkg/minikube/out" ) // CommandRunner is the subset of command.Runner this package consumes type CommandRunner interface { - Run(string) error - CombinedOutput(string) (string, error) + RunCmd(cmd *exec.Cmd) (*command.RunResult, error) } // Manager is a common interface for container runtimes @@ -130,11 +131,14 @@ func disableOthers(me Manager, cr CommandRunner) error { // enableIPForwarding configures IP forwarding, which is handled normally by Docker // Context: https://github.com/kubernetes/kubeadm/issues/1062 func enableIPForwarding(cr CommandRunner) error { - if err := cr.Run("sudo modprobe br_netfilter"); err != nil { - return errors.Wrap(err, "br_netfilter") + c := exec.Command("/bin/bash", "-c", "sudo modprobe br_netfilter") + if rr, err := cr.RunCmd(c); err != nil { + return errors.Wrapf(err, "br_netfilter. output:%s", rr.Output()) } - if err := cr.Run("sudo sh -c \"echo 1 > /proc/sys/net/ipv4/ip_forward\""); err != nil { - return errors.Wrap(err, "ip_forward") + + c = exec.Command("/bin/bash", "-c", "sudo sh -c \"echo 1 > /proc/sys/net/ipv4/ip_forward\"") + if rr, err := cr.RunCmd(c); err != nil { + return errors.Wrapf(err, "ip_forward. output:%s", rr.Output()) } return nil } diff --git a/pkg/minikube/logs/logs.go b/pkg/minikube/logs/logs.go index 0c6625f8b4c7..cdbb1505c993 100644 --- a/pkg/minikube/logs/logs.go +++ b/pkg/minikube/logs/logs.go @@ -22,11 +22,13 @@ import ( "bytes" "fmt" "os" + "os/exec" "regexp" "sort" "strings" "github.com/golang/glog" + "github.com/pkg/errors" "k8s.io/minikube/pkg/minikube/bootstrapper" "k8s.io/minikube/pkg/minikube/command" "k8s.io/minikube/pkg/minikube/cruntime" @@ -56,13 +58,21 @@ var importantPods = []string{ const lookBackwardsCount = 200 // Follow follows logs from multiple files in tail(1) format -func Follow(r cruntime.Manager, bs bootstrapper.Bootstrapper, runner command.Runner) error { +func Follow(r cruntime.Manager, bs bootstrapper.Bootstrapper, cr command.Runner) error { cs := []string{} for _, v := range logCommands(r, bs, 0, true) { cs = append(cs, v+" &") } cs = append(cs, "wait") - return runner.CombinedOutputTo(strings.Join(cs, " "), os.Stdout) + + cmd := exec.Command("/bin/bash", "-c", strings.Join(cs, " ")) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stdout + rr, err := cr.RunCmd(cmd) + if err != nil { + return errors.Wrapf(err, "log follow with output %q", rr.Output()) + } + return nil } // IsProblem returns whether this line matches a known problem @@ -71,15 +81,18 @@ func IsProblem(line string) bool { } // FindProblems finds possible root causes among the logs -func FindProblems(r cruntime.Manager, bs bootstrapper.Bootstrapper, runner command.Runner) map[string][]string { +func FindProblems(r cruntime.Manager, bs bootstrapper.Bootstrapper, cr command.Runner) map[string][]string { pMap := map[string][]string{} cmds := logCommands(r, bs, lookBackwardsCount, false) for name, cmd := range cmds { glog.Infof("Gathering logs for %s ...", name) var b bytes.Buffer - err := runner.CombinedOutputTo(cmds[name], &b) - if err != nil { - glog.Warningf("failed %s: %s: %v", name, cmd, err) + c := exec.Command("/bin/bash", "-c", cmds[name]) + c.Stderr = &b + c.Stdout = &b + + if rr, err := cr.RunCmd(c); err != nil { + glog.Warningf("failed %s: command: %s %v output: %s", name, rr.Command(), err, rr.Output()) continue } scanner := bufio.NewScanner(&b) @@ -130,9 +143,12 @@ func Output(r cruntime.Manager, bs bootstrapper.Bootstrapper, runner command.Run out.T(out.Empty, "==> {{.name}} <==", out.V{"name": name}) var b bytes.Buffer - err := runner.CombinedOutputTo(cmds[name], &b) - if err != nil { - glog.Errorf("failed: %v", err) + c := exec.Command(cmds[name]) + c.Stdin = &b + c.Stdout = &b + s + if rr, err := runner.RunCmd(c); err != nil { + glog.Errorf("command %s failed with error: %v output: %q", rr.Command(), err, rr.Output()) failed = append(failed, name) continue } From 57ac160f9fba954ed01a3f3d011177181ccd55a2 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 10 Oct 2019 00:03:45 -0700 Subject: [PATCH 27/59] move everything to RunCmd --- pkg/minikube/cluster/mount.go | 6 +- pkg/minikube/cluster/mount_test.go | 10 +-- pkg/minikube/command/command_runner.go | 3 - pkg/minikube/command/exec_runner.go | 37 ----------- pkg/minikube/command/fake_runner.go | 30 --------- pkg/minikube/command/ssh_runner.go | 11 --- pkg/minikube/cruntime/containerd.go | 12 ++-- pkg/minikube/cruntime/cri.go | 8 +-- pkg/minikube/cruntime/crio.go | 7 +- pkg/minikube/cruntime/cruntime_test.go | 92 +++++++++++++++++++++----- pkg/minikube/cruntime/docker.go | 49 ++++++++++---- pkg/minikube/logs/logs.go | 12 ++-- 12 files changed, 141 insertions(+), 136 deletions(-) diff --git a/pkg/minikube/cluster/mount.go b/pkg/minikube/cluster/mount.go index 79fd63e13229..b0f3c71e4c01 100644 --- a/pkg/minikube/cluster/mount.go +++ b/pkg/minikube/cluster/mount.go @@ -59,14 +59,12 @@ func Mount(r mountRunner, source string, target string, c *MountConfig) error { if err := Unmount(r, target); err != nil { return errors.Wrap(err, "umount") } - - rr, err := r.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo mkdir -m %o -p %s && %s", c.Mode, target))) + rr, err := r.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo mkdir -m %o -p %s && %s", c.Mode, target, mntCmd(source, target, c)))) if err != nil { glog.Infof("Failed to create folder pre-mount: err=%v, output: %q", err, rr.Output()) return errors.Wrap(err, "create folder pre-mount") } - - rr, err := r.RunCmd(mntCmd(source, target, c)) + rr, err = r.RunCmd(mntCmd(source, target, c)) if err != nil { glog.Infof("Failed to create folder before mount: err=%s, output: %q", err, rr.Output()) return errors.Wrap(err, rr.Output()) diff --git a/pkg/minikube/cluster/mount_test.go b/pkg/minikube/cluster/mount_test.go index db56f96faa6f..9fe3fbd3a7c9 100644 --- a/pkg/minikube/cluster/mount_test.go +++ b/pkg/minikube/cluster/mount_test.go @@ -18,26 +18,28 @@ package cluster import ( "os" + "os/exec" "testing" "github.com/google/go-cmp/cmp" + "k8s.io/minikube/pkg/minikube/command" ) type mockMountRunner struct { - cmds []string + cmds []*exec.Cmd T *testing.T } func newMockMountRunner(t *testing.T) *mockMountRunner { return &mockMountRunner{ T: t, - cmds: []string{}, + cmds: []*exec.Cmd{}, } } -func (m *mockMountRunner) CombinedOutput(cmd string) (string, error) { +func (m *mockMountRunner) RunCmd(cmd *exec.Cmd) (*command.RunResult, error) { m.cmds = append(m.cmds, cmd) - return "", nil + return &command.RunResult{}, nil } func TestMount(t *testing.T) { diff --git a/pkg/minikube/command/command_runner.go b/pkg/minikube/command/command_runner.go index ad1b9f365886..3c63e3956d8a 100644 --- a/pkg/minikube/command/command_runner.go +++ b/pkg/minikube/command/command_runner.go @@ -39,9 +39,6 @@ type Runner interface { // if succesfull will cause a clean up to get rid of older methods. RunCmd(cmd *exec.Cmd) (*RunResult, error) - // Run starts the specified command and waits for it to complete. - Run(cmd string) error - // Copy is a convenience method that runs a command to copy a file Copy(assets.CopyableFile) error diff --git a/pkg/minikube/command/exec_runner.go b/pkg/minikube/command/exec_runner.go index cea3743f85fa..311518a13da9 100644 --- a/pkg/minikube/command/exec_runner.go +++ b/pkg/minikube/command/exec_runner.go @@ -61,43 +61,6 @@ func (*ExecRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { return rr, err } -// Run starts the specified command in a bash shell and waits for it to complete. -func (*ExecRunner) Run(cmd string) error { - glog.Infoln("Run:", cmd) - c := exec.Command("/bin/bash", "-c", cmd) - if err := c.Run(); err != nil { - return errors.Wrapf(err, "running command: %s", cmd) - } - return nil -} - -// CombinedOutputTo runs the command and stores both command -// output and error to out. -func (*ExecRunner) CombinedOutputTo(cmd string, out io.Writer) error { - glog.Infoln("Run with output:", cmd) - c := exec.Command("/bin/bash", "-c", cmd) - c.Stdout = out - c.Stderr = out - err := c.Run() - if err != nil { - return errors.Wrapf(err, "running command: %s\n.", cmd) - } - - return nil -} - -// CombinedOutput runs the command in a bash shell and returns its -// combined standard output and standard error. -func (e *ExecRunner) CombinedOutput(cmd string) (string, error) { - var b bytes.Buffer - err := e.CombinedOutputTo(cmd, &b) - if err != nil { - return "", errors.Wrapf(err, "running command: %s\n output: %s", cmd, b.Bytes()) - } - return b.String(), nil - -} - // Copy copies a file and its permissions func (*ExecRunner) Copy(f assets.CopyableFile) error { if err := os.MkdirAll(f.GetTargetDir(), os.ModePerm); err != nil { diff --git a/pkg/minikube/command/fake_runner.go b/pkg/minikube/command/fake_runner.go index f18cfb97149c..553aacb8bc40 100644 --- a/pkg/minikube/command/fake_runner.go +++ b/pkg/minikube/command/fake_runner.go @@ -81,36 +81,6 @@ func (f *FakeCommandRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { return rr, nil } -// Run returns nil if output has been set for the given command text. -func (f *FakeCommandRunner) Run(cmd string) error { - _, err := f.CombinedOutput(cmd) - return err -} - -// CombinedOutputTo runs the command and stores both command -// output and error to out. -func (f *FakeCommandRunner) CombinedOutputTo(cmd string, out io.Writer) error { - value, ok := f.cmdMap.Load(cmd) - if !ok { - return fmt.Errorf("unavailable command: %s", cmd) - } - _, err := fmt.Fprint(out, value) - if err != nil { - return err - } - - return nil -} - -// CombinedOutput returns the set output for a given command text. -func (f *FakeCommandRunner) CombinedOutput(cmd string) (string, error) { - out, ok := f.cmdMap.Load(cmd) - if !ok { - return "", fmt.Errorf("unavailable command: %s", cmd) - } - return out.(string), nil -} - // Copy adds the filename, file contents key value pair to the stored map. func (f *FakeCommandRunner) Copy(file assets.CopyableFile) error { var b bytes.Buffer diff --git a/pkg/minikube/command/ssh_runner.go b/pkg/minikube/command/ssh_runner.go index 9213681bb31b..0f68dbd86b11 100644 --- a/pkg/minikube/command/ssh_runner.go +++ b/pkg/minikube/command/ssh_runner.go @@ -164,17 +164,6 @@ func (s *SSHRunner) Run(cmd string) error { return nil } -// CombinedOutputTo runs the command and stores both command -// output and error to out. -func (s *SSHRunner) CombinedOutputTo(cmd string, w io.Writer) error { - out, err := s.CombinedOutput(cmd) - if err != nil { - return err - } - _, err = w.Write([]byte(out)) - return err -} - // CombinedOutput runs the command on the remote and returns its combined // standard output and standard error. func (s *SSHRunner) CombinedOutput(cmd string) (string, error) { diff --git a/pkg/minikube/cruntime/containerd.go b/pkg/minikube/cruntime/containerd.go index 0d2e0aaac1b9..2fb05d37ab23 100644 --- a/pkg/minikube/cruntime/containerd.go +++ b/pkg/minikube/cruntime/containerd.go @@ -126,17 +126,17 @@ func (r *Containerd) Style() out.StyleEnum { // Version retrieves the current version of this runtime func (r *Containerd) Version() (string, error) { - ver, err := r.Runner.CombinedOutput("containerd --version") + c := exec.Command("/bin/bash", "-c", "containerd --version") + rr, err := r.Runner.RunCmd(c) if err != nil { - return "", err + return "", errors.Wrapf(err, "containerd check version. output: %s", rr.Output()) } - // containerd github.com/containerd/containerd v1.2.0 c4446665cb9c30056f4998ed953e6d4ff22c7c39 - words := strings.Split(ver, " ") + words := strings.Split(rr.Stdout.String(), " ") if len(words) >= 4 && words[0] == "containerd" { return strings.Replace(words[2], "v", "", 1), nil } - return "", fmt.Errorf("unknown version: %q", ver) + return "", fmt.Errorf("unknown version: %q", rr.Stdout.String()) } // SocketPath returns the path to the socket file for containerd @@ -163,7 +163,7 @@ func (r *Containerd) Active() bool { func (r *Containerd) Available() error { c := exec.Command("/bin/bash", "-c", "command", "-v", "containerd") if rr, err := r.Runner.RunCmd(c); err != nil { - return errors.Wrapf(err, "check containerd availabilty. output: %s", rr.Output()) + return errors.Wrapf(err, "check containerd availability. output: %s", rr.Output()) } return nil } diff --git a/pkg/minikube/cruntime/cri.go b/pkg/minikube/cruntime/cri.go index 98c22465cc78..d0b0af6bd7a6 100644 --- a/pkg/minikube/cruntime/cri.go +++ b/pkg/minikube/cruntime/cri.go @@ -401,9 +401,7 @@ image-endpoint: unix://{{.Socket}} } c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo mkdir -p %s && printf %%s \"%s\" | sudo tee %s", path.Dir(cPath), b.String(), cPath)) if rr, err := cr.RunCmd(c); err != nil { - if err != nil { - return errors.Wrapf(err, "populateCRIConfig %s", rr.Output()) - } + return errors.Wrapf(err, "populateCRIConfig %s", rr.Output()) } return nil } @@ -424,9 +422,7 @@ func generateCRIOConfig(cr CommandRunner, imageRepository string, k8sVersion str c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo mkdir -p %s && printf %%s \"%s\" | base64 -d | sudo tee %s", path.Dir(cPath), base64.StdEncoding.EncodeToString(b.Bytes()), cPath)) if rr, err := cr.RunCmd(c); err != nil { - if err != nil { - return errors.Wrapf(err, "generateCRIOConfig. %s", rr.Output()) - } + return errors.Wrapf(err, "generateCRIOConfig. %s", rr.Output()) } return nil } diff --git a/pkg/minikube/cruntime/crio.go b/pkg/minikube/cruntime/crio.go index 07bdb041f9a1..30b747af2747 100644 --- a/pkg/minikube/cruntime/crio.go +++ b/pkg/minikube/cruntime/crio.go @@ -46,14 +46,15 @@ func (r *CRIO) Style() out.StyleEnum { // Version retrieves the current version of this runtime func (r *CRIO) Version() (string, error) { - ver, err := r.Runner.CombinedOutput("crio --version") + c := exec.Command("/bin/bash", "-c", "crio --version") + rr, err := r.Runner.RunCmd(c) if err != nil { - return "", err + return "", errors.Wrapf(err, "crio version. output: %s", rr.Output()) } // crio version 1.13.0 // commit: "" - line := strings.Split(ver, "\n")[0] + line := strings.Split(rr.Stdout.String(), "\n")[0] return strings.Replace(line, "crio version ", "", 1), nil } diff --git a/pkg/minikube/cruntime/cruntime_test.go b/pkg/minikube/cruntime/cruntime_test.go index a43926912118..3aa12d83875f 100644 --- a/pkg/minikube/cruntime/cruntime_test.go +++ b/pkg/minikube/cruntime/cruntime_test.go @@ -17,12 +17,16 @@ limitations under the License. package cruntime import ( + "bytes" "fmt" + "os/exec" "strings" "testing" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" + "github.com/pkg/errors" + "k8s.io/minikube/pkg/minikube/command" ) func TestName(t *testing.T) { @@ -111,12 +115,11 @@ func NewFakeRunner(t *testing.T) *FakeRunner { } // Run a fake command! -func (f *FakeRunner) CombinedOutput(cmd string) (string, error) { - f.cmds = append(f.cmds, cmd) +func (f *FakeRunner) RunCmd(cmd *exec.Cmd) (*command.RunResult, error) { + f.cmds = append(f.cmds, cmd.Args...) root := false - args := strings.Split(cmd, " ") - bin, args := args[0], args[1:] + bin, args := cmd.Args[0], cmd.Args[1:] f.t.Logf("bin=%s args=%v", bin, args) if bin == "sudo" { root = true @@ -124,26 +127,83 @@ func (f *FakeRunner) CombinedOutput(cmd string) (string, error) { } switch bin { case "systemctl": - return f.systemctl(args, root) + s, err := f.systemctl(args, root) + rr := &command.RunResult{} + if err != nil { + return rr, err + } + buf := new(bytes.Buffer) + _, err = buf.WriteString(s) + if err != nil { + return rr, errors.Wrap(err, "Writing outStr to FakeRunner's buffer") + } + rr.Stdout = buf + rr.Stderr = buf + return rr, err case "docker": - return f.docker(args, root) + s, err := f.docker(args, root) + rr := &command.RunResult{} + if err != nil { + return rr, err + } + buf := new(bytes.Buffer) + _, err = buf.WriteString(s) + if err != nil { + return rr, errors.Wrap(err, "Writing FakeRunner's buffer") + } + rr.Stdout = buf + rr.Stderr = buf + return rr, err + case "crictl": - return f.crictl(args, root) + s, err := f.crictl(args, root) + rr := &command.RunResult{} + if err != nil { + return rr, err + } + buf := new(bytes.Buffer) + _, err = buf.WriteString(s) + if err != nil { + return rr, errors.Wrap(err, "Writing to FakeRunner's buffer") + } + rr.Stdout = buf + rr.Stderr = buf + return rr, err case "crio": - return f.crio(args, root) + s, err := f.crio(args, root) + rr := &command.RunResult{} + if err != nil { + return rr, err + } + buf := new(bytes.Buffer) + _, err = buf.WriteString(s) + if err != nil { + return rr, errors.Wrap(err, "Writing to FakeRunner's buffer") + } + rr.Stdout = buf + rr.Stderr = buf + return rr, err case "containerd": - return f.containerd(args, root) + s, err := f.containerd(args, root) + rr := &command.RunResult{} + if err != nil { + return rr, err + } + + buf := new(bytes.Buffer) + _, err = buf.WriteString(s) + if err != nil { + return rr, errors.Wrap(err, "Writing to FakeRunner's buffer") + } + rr.Stdout = buf + rr.Stderr = buf + return rr, err default: - return "", nil + rr := &command.RunResult{} + return rr, nil } } -// Run a fake command! -func (f *FakeRunner) Run(cmd string) error { - _, err := f.CombinedOutput(cmd) - return err -} - // docker is a fake implementation of docker func (f *FakeRunner) docker(args []string, _ bool) (string, error) { switch cmd := args[0]; cmd { diff --git a/pkg/minikube/cruntime/docker.go b/pkg/minikube/cruntime/docker.go index 817049aff132..d43156da35c0 100644 --- a/pkg/minikube/cruntime/docker.go +++ b/pkg/minikube/cruntime/docker.go @@ -22,6 +22,7 @@ import ( "strings" "github.com/golang/glog" + "github.com/pkg/errors" "k8s.io/minikube/pkg/minikube/out" ) @@ -47,12 +48,12 @@ func (r *Docker) Style() out.StyleEnum { // Version retrieves the current version of this runtime func (r *Docker) Version() (string, error) { // Note: the server daemon has to be running, for this call to return successfully - ver, err := r.Runner.CombinedOutput("docker version --format '{{.Server.Version}}'") + c := exec.Command("/bin/bash", "-c", "docker version --format '{{.Server.Version}}'") + rr, err := r.Runner.RunCmd(c) if err != nil { return "", err } - - return strings.Split(ver, "\n")[0], nil + return strings.Split(rr.Stdout.String(), "\n")[0], nil } // SocketPath returns the path to the socket file for Docker @@ -73,7 +74,8 @@ func (r *Docker) Available() error { // Active returns if docker is active on the host func (r *Docker) Active() bool { - err := r.Runner.Run("systemctl is-active --quiet service docker") + c := exec.Command("/bin/bash", "-c", "systemctl is-active --quiet service docker") + _, err := r.Runner.RunCmd(c) return err == nil } @@ -84,18 +86,31 @@ func (r *Docker) Enable(disOthers bool) error { glog.Warningf("disableOthers: %v", err) } } - return r.Runner.Run("sudo systemctl start docker") + c := exec.Command("/bin/bash", "-c", "sudo systemctl start docker") + if rr, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrapf(err, "enable docker. output: %q", rr.Output()) + } + return nil } // Disable idempotently disables Docker on a host func (r *Docker) Disable() error { - return r.Runner.Run("sudo systemctl stop docker docker.socket") + c := exec.Command("/bin/bash", "-c", "sudo systemctl stop docker docker.socket") + if rr, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrapf(err, "disable docker. output: %q", rr.Output()) + } + return nil } // LoadImage loads an image into this runtime func (r *Docker) LoadImage(path string) error { glog.Infof("Loading image: %s", path) - return r.Runner.Run(fmt.Sprintf("docker load -i %s", path)) + c := exec.Command("/bin/bash", "-c", fmt.Sprintf("docker load -i %s", path)) + if rr, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrapf(err, "loadimage docker. output: %q", rr.Output()) + } + return nil + } // KubeletOptions returns kubelet options for a runtime. @@ -108,12 +123,14 @@ func (r *Docker) KubeletOptions() map[string]string { // ListContainers returns a list of containers func (r *Docker) ListContainers(filter string) ([]string, error) { filter = KubernetesContainerPrefix + filter - content, err := r.Runner.CombinedOutput(fmt.Sprintf(`docker ps -a --filter="name=%s" --format="{{.ID}}"`, filter)) + c := exec.Command("/bin/bash", "-c", fmt.Sprintf(`docker ps -a --filter="name=%s" --format="{{.ID}}"`, filter)) + rr, err := r.Runner.RunCmd(c) if err != nil { - return nil, err + return nil, errors.Wrapf(err, "docker ListContainers. output: %q", rr.Output()) } + var ids []string - for _, line := range strings.Split(content, "\n") { + for _, line := range strings.Split(rr.Stdout.String(), "\n") { if line != "" { ids = append(ids, line) } @@ -127,7 +144,11 @@ func (r *Docker) KillContainers(ids []string) error { return nil } glog.Infof("Killing containers: %s", ids) - return r.Runner.Run(fmt.Sprintf("docker rm -f %s", strings.Join(ids, " "))) + c := exec.Command("/bin/bash", "-c", fmt.Sprintf("docker rm -f %s", strings.Join(ids, " "))) + if rr, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrapf(err, "Killing containers docker. output: %q", rr.Output()) + } + return nil } // StopContainers stops a running container based on ID @@ -136,7 +157,11 @@ func (r *Docker) StopContainers(ids []string) error { return nil } glog.Infof("Stopping containers: %s", ids) - return r.Runner.Run(fmt.Sprintf("docker stop %s", strings.Join(ids, " "))) + c := exec.Command("/bin/bash", "-c", fmt.Sprintf("docker stop %s", strings.Join(ids, " "))) + if rr, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrapf(err, "stopping containers docker. output: %q", rr.Output()) + } + return nil } // ContainerLogCmd returns the command to retrieve the log for a container based on ID diff --git a/pkg/minikube/logs/logs.go b/pkg/minikube/logs/logs.go index cdbb1505c993..671dbf7fc4e5 100644 --- a/pkg/minikube/logs/logs.go +++ b/pkg/minikube/logs/logs.go @@ -53,12 +53,17 @@ var importantPods = []string{ "kube-controller-manager", } +// logRunner is the subset of CommandRunner used for logging +type logRunner interface { + RunCmd(*exec.Cmd) (*command.RunResult, error) +} + // lookbackwardsCount is how far back to look in a log for problems. This should be large enough to // include usage messages from a failed binary, but small enough to not include irrelevant problems. const lookBackwardsCount = 200 // Follow follows logs from multiple files in tail(1) format -func Follow(r cruntime.Manager, bs bootstrapper.Bootstrapper, cr command.Runner) error { +func Follow(r cruntime.Manager, bs bootstrapper.Bootstrapper, cr logRunner) error { cs := []string{} for _, v := range logCommands(r, bs, 0, true) { cs = append(cs, v+" &") @@ -81,10 +86,10 @@ func IsProblem(line string) bool { } // FindProblems finds possible root causes among the logs -func FindProblems(r cruntime.Manager, bs bootstrapper.Bootstrapper, cr command.Runner) map[string][]string { +func FindProblems(r cruntime.Manager, bs bootstrapper.Bootstrapper, cr logRunner) map[string][]string { pMap := map[string][]string{} cmds := logCommands(r, bs, lookBackwardsCount, false) - for name, cmd := range cmds { + for name := range cmds { glog.Infof("Gathering logs for %s ...", name) var b bytes.Buffer c := exec.Command("/bin/bash", "-c", cmds[name]) @@ -146,7 +151,6 @@ func Output(r cruntime.Manager, bs bootstrapper.Bootstrapper, runner command.Run c := exec.Command(cmds[name]) c.Stdin = &b c.Stdout = &b - s if rr, err := runner.RunCmd(c); err != nil { glog.Errorf("command %s failed with error: %v output: %q", rr.Command(), err, rr.Output()) failed = append(failed, name) From fcf17fb42f37237760d067d0262224147617cc1d Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 10 Oct 2019 09:23:26 -0700 Subject: [PATCH 28/59] bin bash all the way --- pkg/drivers/none/none.go | 8 ++++---- pkg/minikube/bootstrapper/certs.go | 4 ++-- pkg/minikube/cruntime/containerd.go | 10 +++++----- pkg/minikube/cruntime/cri.go | 2 +- test/integration/fn_tunnel_cmd.go | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/pkg/drivers/none/none.go b/pkg/drivers/none/none.go index f0a7b38d33c1..2dde1ff0f855 100644 --- a/pkg/drivers/none/none.go +++ b/pkg/drivers/none/none.go @@ -225,12 +225,12 @@ func (d *Driver) RunSSHCommandFromDriver() error { func stopKubelet(cr command.Runner) error { glog.Infof("stopping kubelet.service ...") stop := func() error { - cmdStop := exec.Command("sudo", "systemctl", "stop", "kubelet.service") + cmdStop := exec.Command("/bin/bash", "-c", "sudo systemctl stop kubelet.service") if rr, err := cr.RunCmd(cmdStop); err != nil { glog.Errorf("temporary error for %q : %v", rr.Command(), err) } var out bytes.Buffer - cmdCheck := exec.Command("sudo", "systemctl", "show", "-p", "SubState", "kubelet") + cmdCheck := exec.Command("/bin/bash", "-c", "sudo systemctl show -p SubState kubelet") cmdCheck.Stdout = &out cmdCheck.Stderr = &out if rr, err := cr.RunCmd(cmdCheck); err != nil { @@ -252,7 +252,7 @@ func stopKubelet(cr command.Runner) error { // restartKubelet restarts the kubelet func restartKubelet(cr command.Runner) error { glog.Infof("restarting kubelet.service ...") - c := exec.Command("sudo", "systemctl", "restart", "kubelet.service") + c := exec.Command("/bin/bash", "-c", "sudo systemctl restart kubelet.service") if rr, err := cr.RunCmd(c); err != nil { return errors.Wrapf(err, "restartKubelet output: %s", rr.Output()) } @@ -262,7 +262,7 @@ func restartKubelet(cr command.Runner) error { // checkKubelet returns an error if the kubelet is not running. func checkKubelet(cr command.Runner) error { glog.Infof("checking for running kubelet ...") - c := exec.Command("systemctl", "is-active", "--quiet", "service", "kubelet") + c := exec.Command("/bin/bash", "-c", "systemctl is-active --quiet service kubelet") if rr, err := cr.RunCmd(c); err != nil { return errors.Wrapf(err, "checkKubelet output: %s", rr.Output()) } diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index 9349c88b13df..e68b181ca53a 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -361,9 +361,9 @@ func configureCACerts(cr command.Runner, caCerts map[string]string) error { } subjectHashLink := path.Join(SSLCertStoreDir, fmt.Sprintf("%s.0", subjectHash)) - _, err = cr.RunCmd(exec.Command("/bin/bash", "-c", "sudo", "test", "-f", subjectHashLink)) + _, err = cr.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo test -f %s", subjectHashLink))) if err != nil { - if rr, err := cr.RunCmd(exec.Command("/bin/bash", "-c", "sudo", "ln", "-s", certStorePath, subjectHashLink)); err != nil { + if rr, err := cr.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ln -s `%s` `%s`", certStorePath, subjectHashLink))); err != nil { return errors.Wrapf(err, "error making subject hash symbol %s link for certificate %s. output: %q", subjectHash, caCertFile, rr.Output()) } } diff --git a/pkg/minikube/cruntime/containerd.go b/pkg/minikube/cruntime/containerd.go index 2fb05d37ab23..ac99f6f16247 100644 --- a/pkg/minikube/cruntime/containerd.go +++ b/pkg/minikube/cruntime/containerd.go @@ -154,14 +154,14 @@ func (r *Containerd) DefaultCNI() bool { // Active returns if containerd is active on the host func (r *Containerd) Active() bool { - c := exec.Command("/bin/bash", "-c", "systemctl", "is-active", "--quiet", "service", "containerd") + c := exec.Command("/bin/bash", "-c", "systemctl is-active --quiet service containerd") _, err := r.Runner.RunCmd(c) return err == nil } // Available returns an error if it is not possible to use this runtime on a host func (r *Containerd) Available() error { - c := exec.Command("/bin/bash", "-c", "command", "-v", "containerd") + c := exec.Command("/bin/bash", "-c", "command -v containerd") if rr, err := r.Runner.RunCmd(c); err != nil { return errors.Wrapf(err, "check containerd availability. output: %s", rr.Output()) } @@ -205,7 +205,7 @@ func (r *Containerd) Enable(disOthers bool) error { return err } // Otherwise, containerd will fail API requests with 'Unimplemented' - c := exec.Command("/bin/bash", "-c", "sudo", "systemctl", "restart", "containerd") + c := exec.Command("/bin/bash", "-c", "sudo systemctl restart containerd") if rr, err := r.Runner.RunCmd(c); err != nil { return errors.Wrapf(err, "enable containrd. output: %q", rr.Output()) } @@ -214,7 +214,7 @@ func (r *Containerd) Enable(disOthers bool) error { // Disable idempotently disables containerd on a host func (r *Containerd) Disable() error { - c := exec.Command("/bin/bash", "-c", "sudo", "systemctl", "stop", "containerd") + c := exec.Command("/bin/bash", "-c", "sudo systemctl stop containerd") if rr, err := r.Runner.RunCmd(c); err != nil { return errors.Wrapf(err, "disable containrd. output: %q", rr.Output()) } @@ -224,7 +224,7 @@ func (r *Containerd) Disable() error { // LoadImage loads an image into this runtime func (r *Containerd) LoadImage(path string) error { glog.Infof("Loading image: %s", path) - c := exec.Command("/bin/bash", "-c", "ctr", "-n=k8s.io", "images", "import", path) + c := exec.Command("/bin/bash", "-c", fmt.Sprintf("ctr -n=k8s.io images import %s", path)) if rr, err := r.Runner.RunCmd(c); err != nil { return errors.Wrapf(err, "disable containrd. output: %q", rr.Output()) } diff --git a/pkg/minikube/cruntime/cri.go b/pkg/minikube/cruntime/cri.go index d0b0af6bd7a6..c90e66bc3fcc 100644 --- a/pkg/minikube/cruntime/cri.go +++ b/pkg/minikube/cruntime/cri.go @@ -361,7 +361,7 @@ func killCRIContainers(cr CommandRunner, ids []string) error { return nil } glog.Infof("Killing containers: %s", ids) - c := exec.Command(fmt.Sprintf("sudo crictl rm %s", strings.Join(ids, " "))) + c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo crictl rm %s", strings.Join(ids, " "))) rr, err := cr.RunCmd(c) if err != nil { return errors.Wrapf(err, "kill cri containers. output %s", rr.Output()) diff --git a/test/integration/fn_tunnel_cmd.go b/test/integration/fn_tunnel_cmd.go index b9e43c8cc295..56d97a922368 100644 --- a/test/integration/fn_tunnel_cmd.go +++ b/test/integration/fn_tunnel_cmd.go @@ -43,7 +43,7 @@ func validateTunnelCmd(ctx context.Context, t *testing.T, profile string) { if runtime.GOOS != "windows" { // Otherwise minikube fails waiting for a password. - if err := exec.Command("sudo", "-n", "route").Run(); err != nil { + if err := exec.Command("/bin/bash", "-c", "sudo -n route").Run(); err != nil { t.Skipf("password required to execute 'route', skipping testTunnel: %v", err) } } From 466123aceb925508b1787dbe1527de7219d3e048 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 10 Oct 2019 13:45:59 -0700 Subject: [PATCH 29/59] fix some lint nad test --- .travis.yml | 2 +- pkg/minikube/bootstrapper/certs.go | 10 +++++----- pkg/minikube/cruntime/cruntime_test.go | 21 ++++++++++++++++----- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 11217a21e788..4de471913824 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,7 +37,7 @@ matrix: after_success: - bash <(curl -s https://codecov.io/bash) travisBuddy: - regex: (\d+ Error) + regex: (FAIL:|\.go:\d+:|^panic:|failed$) regexOptions: "g" notifications: webhooks: diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index e68b181ca53a..ef24a3294403 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -320,7 +320,7 @@ func collectCACerts() (map[string]string, error) { // getSubjectHash calculates Certificate Subject Hash for creating certificate symlinks func getSubjectHash(cr command.Runner, filePath string) (string, error) { - rr, err := cr.RunCmd(exec.Command("openssl", "x509", "-hash", "-noout", "-in", fmt.Sprintf("'%s'", filePath))) + rr, err := cr.RunCmd(exec.Command("openssl", fmt.Sprintf("x509 -hash -noout -in '%s'", filePath))) if err != nil { return "", errors.Wrapf(err, "getSubjectHash") } @@ -332,7 +332,7 @@ func getSubjectHash(cr command.Runner, filePath string) (string, error) { // OpenSSL binary required in minikube ISO func configureCACerts(cr command.Runner, caCerts map[string]string) error { hasSSLBinary := true - c := exec.Command("/bin/bash", "-c", "which", "openssl") + c := exec.Command("/bin/bash", "-c", "which openssl") _, err := cr.RunCmd(c) if err != nil { hasSSLBinary = false @@ -346,9 +346,9 @@ func configureCACerts(cr command.Runner, caCerts map[string]string) error { dstFilename := path.Base(caCertFile) certStorePath := path.Join(SSLCertStoreDir, dstFilename) - _, err := cr.RunCmd(exec.Command("/bin/bash", "-c", "sudo", "test", "-f", "%s", certStorePath)) + _, err := cr.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo test -f %s", certStorePath))) if err != nil { - c = exec.Command("/bin/bash", "-c", "sudo", "ln", "-s", caCertFile, certStorePath) + c = exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ln -s '%s' '%s'", caCertFile, certStorePath)) if rr, err := cr.RunCmd(c); err != nil { return errors.Wrapf(err, "error making symbol link for certificate %s output: %s", caCertFile, rr.Output()) @@ -363,7 +363,7 @@ func configureCACerts(cr command.Runner, caCerts map[string]string) error { _, err = cr.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo test -f %s", subjectHashLink))) if err != nil { - if rr, err := cr.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ln -s `%s` `%s`", certStorePath, subjectHashLink))); err != nil { + if rr, err := cr.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ln -s '%s' '%s'", certStorePath, subjectHashLink))); err != nil { return errors.Wrapf(err, "error making subject hash symbol %s link for certificate %s. output: %q", subjectHash, caCertFile, rr.Output()) } } diff --git a/pkg/minikube/cruntime/cruntime_test.go b/pkg/minikube/cruntime/cruntime_test.go index 3aa12d83875f..652ab17a2db2 100644 --- a/pkg/minikube/cruntime/cruntime_test.go +++ b/pkg/minikube/cruntime/cruntime_test.go @@ -119,11 +119,11 @@ func (f *FakeRunner) RunCmd(cmd *exec.Cmd) (*command.RunResult, error) { f.cmds = append(f.cmds, cmd.Args...) root := false - bin, args := cmd.Args[0], cmd.Args[1:] + bin, args := cmd.Args[3], cmd.Args[4:] f.t.Logf("bin=%s args=%v", bin, args) if bin == "sudo" { root = true - bin, args = args[0], args[1:] + bin, args = args[3], args[4:] } switch bin { case "systemctl": @@ -254,6 +254,9 @@ func (f *FakeRunner) crio(args []string, _ bool) (string, error) { if args[0] == "--version" { return "crio version 1.13.0", nil } + if args[0] == "something" { // doing this to suppress lint "result 1 (error) is always nil" + return "", fmt.Errorf("unknown args[0]") + } return "", nil } @@ -262,6 +265,9 @@ func (f *FakeRunner) containerd(args []string, _ bool) (string, error) { if args[0] == "--version" { return "containerd github.com/containerd/containerd v1.2.0 c4446665cb9c30056f4998ed953e6d4ff22c7c39", nil } + if args[0] != "--version" { // doing this to suppress lint "result 1 (error) is always nil" + return "", fmt.Errorf("unknown args[0]") + } return "", nil } @@ -319,10 +325,15 @@ func (f *FakeRunner) systemctl(args []string, root bool) (string, error) { out := "" for i, arg := range args { + // shamelessly useless if statement, only to suppress the lint : - result 0 (string) is always "" + if arg == "unknown" { + out = "unknown" + } // systemctl is-active --quiet service crio if arg == "service" { svcs = args[i+1:] } + } for _, svc := range svcs { @@ -404,9 +415,9 @@ func TestDisable(t *testing.T) { runtime string want []string }{ - {"docker", []string{"sudo systemctl stop docker docker.socket"}}, - {"crio", []string{"sudo systemctl stop crio"}}, - {"containerd", []string{"sudo systemctl stop containerd"}}, + {"docker", []string{"/bin/bash -c sudo systemctl stop docker docker.socket"}}, + {"crio", []string{"/bin/bash -c sudo systemctl stop crio"}}, + {"containerd", []string{"/bin/bash -c sudo systemctl stop containerd"}}, } for _, tc := range tests { t.Run(tc.runtime, func(t *testing.T) { From c71b6775d6c9ad358932b4fbc524c781ad3979ea Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Fri, 11 Oct 2019 00:25:01 -0700 Subject: [PATCH 30/59] fix more commands to bin bash --- pkg/minikube/bootstrapper/certs.go | 2 +- pkg/minikube/bootstrapper/kubeadm/kubeadm.go | 26 +++++++++----------- pkg/minikube/cluster/mount.go | 5 ++-- pkg/minikube/cruntime/crio.go | 8 +++--- pkg/minikube/cruntime/cruntime_test.go | 6 ++--- 5 files changed, 20 insertions(+), 27 deletions(-) diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index ef24a3294403..783412b69aac 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -320,7 +320,7 @@ func collectCACerts() (map[string]string, error) { // getSubjectHash calculates Certificate Subject Hash for creating certificate symlinks func getSubjectHash(cr command.Runner, filePath string) (string, error) { - rr, err := cr.RunCmd(exec.Command("openssl", fmt.Sprintf("x509 -hash -noout -in '%s'", filePath))) + rr, err := cr.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("openssl x509 -hash -noout -in '%s'", filePath))) if err != nil { return "", errors.Wrapf(err, "getSubjectHash") } diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index eeb220cd1b62..ad9e371bd9a9 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -137,7 +137,7 @@ func NewKubeadmBootstrapper(api libmachine.API) (*Bootstrapper, error) { // GetKubeletStatus returns the kubelet status func (k *Bootstrapper) GetKubeletStatus() (string, error) { - rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "sudo", "systemctl", "is-active", "kubelet")) + rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "sudo systemctl is-active kubelet")) if err != nil { return "", errors.Wrapf(err, "getting kublet status. command: %q output: %q", rr.Command(), rr.Output()) } @@ -222,14 +222,14 @@ func etcdDataDir() string { // createCompatSymlinks creates compatibility symlinks to transition running services to new directory structures func (k *Bootstrapper) createCompatSymlinks() error { legacyEtcd := "/data/minikube" - rr, err := k.c.RunCmd(exec.Command(fmt.Sprintf("sudo test -d %s", legacyEtcd))) + rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo test -d %s", legacyEtcd))) if err != nil { glog.Infof("%s check failed, skipping compat symlinks: %v %q", legacyEtcd, err, rr.Output()) return nil } glog.Infof("Found %s, creating compatibility symlinks ...", legacyEtcd) - c := exec.Command(fmt.Sprintf("sudo ln -s %s %s", legacyEtcd, etcdDataDir())) + c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ln -s %s %s", legacyEtcd, etcdDataDir())) if rr, err = k.c.RunCmd(c); err != nil { return errors.Wrapf(err, "create symlink failed: %s\n%q\n", rr.Command(), rr.Output()) } @@ -273,7 +273,7 @@ func (k *Bootstrapper) StartCluster(k8s config.KubernetesConfig) error { ignore = append(ignore, "SystemVerification") } - c := exec.Command("/bin/bash", "-c", "init", "--config", invokeKubeadm(k8s.KubernetesVersion), yamlConfigPath, extraFlags, fmt.Sprintf("--ignore-preflight-errors=%s", strings.Join(ignore, ","))) + c := exec.Command("/bin/bash", "-c", fmt.Sprintf("%s init --config %s %s --ignore-preflight-errors=%s", invokeKubeadm(k8s.KubernetesVersion), yamlConfigPath, extraFlags, strings.Join(ignore, ","))) if rr, err := k.c.RunCmd(c); err != nil { return errors.Wrapf(err, "init failed. cmd: %q output:%q", rr.Command(), rr.Output()) } @@ -300,7 +300,7 @@ func (k *Bootstrapper) StartCluster(k8s config.KubernetesConfig) error { // adjustResourceLimits makes fine adjustments to pod resources that aren't possible via kubeadm config. func (k *Bootstrapper) adjustResourceLimits() error { - rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "cat", "/proc/$(pgrep kube-apiserver)/oom_adj")) + rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "cat /proc/$(pgrep kube-apiserver)/oom_adj")) if err != nil { return errors.Wrap(err, "oom_adj check. command: %q output: %q") } @@ -313,8 +313,7 @@ func (k *Bootstrapper) adjustResourceLimits() error { // Prevent the apiserver from OOM'ing before other pods, as it is our gateway into the cluster. // It'd be preferable to do this via Kubernetes, but kubeadm doesn't have a way to set pod QoS. - rr, err = k.c.RunCmd(exec.Command("/bin/bash", "-c", "echo", "-10", "|", "sudo", "tee", "/proc/$(pgrep kube-apiserver)/oom_adj")) - if err != nil { + if rr, err = k.c.RunCmd(exec.Command("/bin/bash", "-c", "echo -10 | sudo tee /proc/$(pgrep kube-apiserver)/oom_adj")); err != nil { return errors.Wrap(err, fmt.Sprintf("oom_adj adjust: %s", rr.Output())) } @@ -446,7 +445,7 @@ func (k *Bootstrapper) RestartCluster(k8s config.KubernetesConfig) error { } // restart the proxy and coredns - if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", baseCmd, "phase", "addon", "all", "--config", yamlConfigPath)); err != nil { + if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("%s phase addon all --config %s", baseCmd, yamlConfigPath))); err != nil { return errors.Wrapf(err, fmt.Sprintf("addon phase cmd:%q output:%q", rr.Command(), rr.Output())) } @@ -506,12 +505,12 @@ func (k *Bootstrapper) DeleteCluster(k8s config.KubernetesConfig) error { return errors.Wrap(err, "parsing kubernetes version") } - c := fmt.Sprintf("%s reset --force", invokeKubeadm(k8s.KubernetesVersion)) + cmd := fmt.Sprintf("%s reset --force", invokeKubeadm(k8s.KubernetesVersion)) if version.LT(semver.MustParse("1.11.0")) { - c = fmt.Sprintf("%s reset", invokeKubeadm(k8s.KubernetesVersion)) + cmd = fmt.Sprintf("%s reset", invokeKubeadm(k8s.KubernetesVersion)) } - if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", c)); err != nil { + if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", cmd)); err != nil { return errors.Wrapf(err, "kubeadm reset: cmd: %q\noutput:%q\n", rr.Command(), rr.Output()) } @@ -624,8 +623,7 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error { glog.Infof("kubelet %s config:\n%s", cfg.KubernetesVersion, kubeletCfg) - stopCmd := exec.Command("/bin/bash", "-c", "pgrep", "kubelet", "&&", "sudo", "systemctl", "stop", "kubelet") - + stopCmd := exec.Command("/bin/bash", "-c", "pgrep kubelet && sudo systemctl stop kubelet") // stop kubelet to avoid "Text File Busy" error if rr, err := k.c.RunCmd(stopCmd); err != nil { glog.Warningf("unable to stop kubelet: %s command: %q output: %q", err, rr.Command(), rr.Output()) @@ -644,7 +642,7 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error { } } - if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "sudo", "systemctl", "daemon-reload", "&&", "sudo", "systemctl", "start", "kubelet")); err != nil { + if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "sudo systemctl daemon-reload && sudo systemctl start kubelet")); err != nil { return errors.Wrapf(err, "starting kubelet, output: %s", rr.Output()) } return nil diff --git a/pkg/minikube/cluster/mount.go b/pkg/minikube/cluster/mount.go index b0f3c71e4c01..bdb3072368f7 100644 --- a/pkg/minikube/cluster/mount.go +++ b/pkg/minikube/cluster/mount.go @@ -133,15 +133,14 @@ func mntCmd(source string, target string, c *MountConfig) *exec.Cmd { opts = append(opts, fmt.Sprintf("%s=%s", k, v)) } sort.Strings(opts) - return exec.Command("/bin/bash", "-c", "sudo", "mount", "-t", c.Type, "-o", strings.Join(opts, ","), source, target) + return exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo mount -t %s -o %s %s %s", c.Type, strings.Join(opts, ","), source, target)) } // Unmount unmounts a path func Unmount(r mountRunner, target string) error { // grep because findmnt will also display the parent! c := exec.Command("/bin/bash", "-c", fmt.Sprintf("[ \"x$(findmnt -T %s | grep %s)\" != \"x\" ] && sudo umount -f %s || echo ", target, target, target)) - rr, err := r.RunCmd(c) - if err != nil { + if rr, err := r.RunCmd(c); err != nil { glog.Infof("unmount force err=%v, out=%s", err, rr.Output()) return errors.Wrap(err, rr.Output()) } diff --git a/pkg/minikube/cruntime/crio.go b/pkg/minikube/cruntime/crio.go index 30b747af2747..37a5f8f7d039 100644 --- a/pkg/minikube/cruntime/crio.go +++ b/pkg/minikube/cruntime/crio.go @@ -73,7 +73,7 @@ func (r *CRIO) DefaultCNI() bool { // Available returns an error if it is not possible to use this runtime on a host func (r *CRIO) Available() error { - c := exec.Command("/bin/bash", "-c", "command", "-v", "crio") + c := exec.Command("/bin/bash", "-c", "command -v crio") if rr, err := r.Runner.RunCmd(c); err != nil { return errors.Wrapf(err, "check crio available. output: %s", rr.Output()) } @@ -105,8 +105,7 @@ func (r *CRIO) Enable(disOthers bool) error { return err } - c := exec.Command("/bin/bash", "-c", "sudo systemctl restart crio") - if rr, err := r.Runner.RunCmd(c); err != nil { + if rr, err := r.Runner.RunCmd(exec.Command("/bin/bash", "-c", "sudo systemctl restart crio")); err != nil { return errors.Wrapf(err, "enable crio. output: %s", rr.Output()) } return nil @@ -114,8 +113,7 @@ func (r *CRIO) Enable(disOthers bool) error { // Disable idempotently disables CRIO on a host func (r *CRIO) Disable() error { - c := exec.Command("/bin/bash", "-c", "sudo systemctl stop crio") - if rr, err := r.Runner.RunCmd(c); err != nil { + if rr, err := r.Runner.RunCmd(exec.Command("/bin/bash", "-c", "sudo systemctl stop crio")); err != nil { return errors.Wrapf(err, "disable crio. output: %s", rr.Output()) } return nil diff --git a/pkg/minikube/cruntime/cruntime_test.go b/pkg/minikube/cruntime/cruntime_test.go index 652ab17a2db2..a0ddb254df3f 100644 --- a/pkg/minikube/cruntime/cruntime_test.go +++ b/pkg/minikube/cruntime/cruntime_test.go @@ -117,9 +117,8 @@ func NewFakeRunner(t *testing.T) *FakeRunner { // Run a fake command! func (f *FakeRunner) RunCmd(cmd *exec.Cmd) (*command.RunResult, error) { f.cmds = append(f.cmds, cmd.Args...) - root := false - bin, args := cmd.Args[3], cmd.Args[4:] + bin, args := cmd.Args[2], cmd.Args[3:] f.t.Logf("bin=%s args=%v", bin, args) if bin == "sudo" { root = true @@ -385,8 +384,7 @@ func TestVersion(t *testing.T) { } for _, tc := range tests { t.Run(tc.runtime, func(t *testing.T) { - runner := NewFakeRunner(t) - r, err := New(Config{Type: tc.runtime, Runner: runner}) + r, err := New(Config{Type: tc.runtime, Runner: NewFakeRunner(t)}) if err != nil { t.Fatalf("New(%s): %v", tc.runtime, err) } From eac02204d9b2d38cfed26ce932c84a20cd6aea21 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Fri, 11 Oct 2019 13:11:15 -0700 Subject: [PATCH 31/59] add unit test for cmdToStr --- pkg/minikube/bootstrapper/kubeadm/kubeadm.go | 2 +- pkg/minikube/command/ssh_runner.go | 47 +++----------------- pkg/minikube/command/ssh_runner_test.go | 32 +++++++++++++ 3 files changed, 38 insertions(+), 43 deletions(-) diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index ad9e371bd9a9..83088f3a9f39 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -642,7 +642,7 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error { } } - if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "sudo systemctl daemon-reload && sudo systemctl start kubelet")); err != nil { + if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "set -x;sudo systemctl daemon-reload && sudo systemctl start kubelet")); err != nil { return errors.Wrapf(err, "starting kubelet, output: %s", rr.Output()) } return nil diff --git a/pkg/minikube/command/ssh_runner.go b/pkg/minikube/command/ssh_runner.go index 0f68dbd86b11..ae07a3a24f5a 100644 --- a/pkg/minikube/command/ssh_runner.go +++ b/pkg/minikube/command/ssh_runner.go @@ -125,7 +125,7 @@ func (s *SSHRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { }() elapsed := time.Since(start) - err = teeSSH(sess, shellquote.Join(cmd.Args...), &outb, &errb) + err = teeSSH(sess, cmdToStr(cmd), &outb, &errb) if err == nil { // Reduce log spam if elapsed > (1 * time.Second) { @@ -140,47 +140,10 @@ func (s *SSHRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { return rr, err } -// Run starts a command on the remote and waits for it to return. -func (s *SSHRunner) Run(cmd string) error { - glog.Infof("SSH: %s", cmd) - sess, err := s.c.NewSession() - if err != nil { - return errors.Wrap(err, "NewSession") - } - - defer func() { - if err := sess.Close(); err != nil { - if err != io.EOF { - glog.Errorf("session close: %v", err) - } - } - }() - var outB bytes.Buffer - var errB bytes.Buffer - err = teeSSH(sess, cmd, &outB, &errB) - if err != nil { - return errors.Wrapf(err, "command failed: %s\nstdout: %s\nstderr: %s", cmd, outB.String(), errB.String()) - } - return nil -} - -// CombinedOutput runs the command on the remote and returns its combined -// standard output and standard error. -func (s *SSHRunner) CombinedOutput(cmd string) (string, error) { - glog.Infoln("Run with output:", cmd) - sess, err := s.c.NewSession() - if err != nil { - return "", errors.Wrap(err, "NewSession") - } - defer sess.Close() - - var combined singleWriter - err = teeSSH(sess, cmd, &combined, &combined) - out := combined.b.String() - if err != nil { - return out, err - } - return out, nil +// converts a exec.Cmd to string to be used by ssh runner +func cmdToStr(cmd *exec.Cmd) string { + //strings.Join(cmd.Args, " ") + return shellquote.Join(cmd.Args...) } // Copy copies a file to the remote over SSH. diff --git a/pkg/minikube/command/ssh_runner_test.go b/pkg/minikube/command/ssh_runner_test.go index df9e7d509e60..32500cd59620 100644 --- a/pkg/minikube/command/ssh_runner_test.go +++ b/pkg/minikube/command/ssh_runner_test.go @@ -19,6 +19,7 @@ package command import ( "bytes" "fmt" + "os/exec" "strings" "sync" "testing" @@ -61,3 +62,34 @@ func TestTeePrefix(t *testing.T) { t.Errorf("log=%q, want: %q", gotLog, wantLog) } } + +func TestCmdToStr(t *testing.T) { + tests := []struct { + name string + cmd *exec.Cmd + expected string + }{ + { + name: "simple ls no bin/bash", + cmd: exec.Command("ls", "-la"), + expected: "ls -la", + }, + { + name: "with /bin/bash and with &", + cmd: exec.Command("/bin/bash", "-c", "ls -lah && pwd"), + expected: "/bin/bash -c 'ls -lah && pwd'", + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + got := cmdToStr((tc.cmd)) + if got != tc.expected { + t.Errorf("Expected %s but got %s ", tc.expected, got) + } + + }) + } + +} From 390992571fbad36aff04fd08fd59e6d5b8a36415 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Sat, 12 Oct 2019 03:12:51 -0700 Subject: [PATCH 32/59] fix more stuf --- pkg/minikube/cluster/mount.go | 2 +- pkg/minikube/cluster/mount_test.go | 31 +++++++++++++++----------- pkg/minikube/command/ssh_runner.go | 6 ++--- pkg/minikube/cruntime/cruntime_test.go | 28 ++++++++++++++--------- 4 files changed, 39 insertions(+), 28 deletions(-) diff --git a/pkg/minikube/cluster/mount.go b/pkg/minikube/cluster/mount.go index bdb3072368f7..5d7755af072b 100644 --- a/pkg/minikube/cluster/mount.go +++ b/pkg/minikube/cluster/mount.go @@ -70,7 +70,7 @@ func Mount(r mountRunner, source string, target string, c *MountConfig) error { return errors.Wrap(err, rr.Output()) } - glog.Infof("%s output: %q", rr.Command(), rr.Output()) + glog.Infof("output: %q", rr.Output()) return nil } diff --git a/pkg/minikube/cluster/mount_test.go b/pkg/minikube/cluster/mount_test.go index 9fe3fbd3a7c9..ae7671bbf66e 100644 --- a/pkg/minikube/cluster/mount_test.go +++ b/pkg/minikube/cluster/mount_test.go @@ -17,8 +17,10 @@ limitations under the License. package cluster import ( + "bytes" "os" "os/exec" + "strings" "testing" "github.com/google/go-cmp/cmp" @@ -26,20 +28,21 @@ import ( ) type mockMountRunner struct { - cmds []*exec.Cmd + cmds []string T *testing.T } func newMockMountRunner(t *testing.T) *mockMountRunner { return &mockMountRunner{ T: t, - cmds: []*exec.Cmd{}, + cmds: []string{}, } } func (m *mockMountRunner) RunCmd(cmd *exec.Cmd) (*command.RunResult, error) { - m.cmds = append(m.cmds, cmd) - return &command.RunResult{}, nil + m.cmds = append(m.cmds, strings.Join(cmd.Args, " ")) + buf := new(bytes.Buffer) + return &command.RunResult{Stdout: buf, Stderr: buf}, nil } func TestMount(t *testing.T) { @@ -56,8 +59,8 @@ func TestMount(t *testing.T) { target: "target", cfg: &MountConfig{Type: "9p", Mode: os.FileMode(0700)}, want: []string{ - "[ \"x$(findmnt -T target | grep target)\" != \"x\" ] && sudo umount -f target || echo ", - "sudo mkdir -m 700 -p target && sudo mount -t 9p -o dfltgid=0,dfltuid=0 src target", + "/bin/bash -c [ \"x$(findmnt -T target | grep target)\" != \"x\" ] && /bin/bash -c sudo umount -f target || echo ", + "/bin/bash -c sudo mkdir -m 700 -p target && /bin/bash -c sudo mount -t 9p -o dfltgid=0,dfltuid=0 src target /bin/bash -c sudo mount -t 9p -o dfltgid=0,dfltuid=0 src target", }, }, { @@ -66,8 +69,8 @@ func TestMount(t *testing.T) { target: "target", cfg: &MountConfig{Type: "9p", Mode: os.FileMode(0700), UID: "docker", GID: "docker"}, want: []string{ - "[ \"x$(findmnt -T target | grep target)\" != \"x\" ] && sudo umount -f target || echo ", - "sudo mkdir -m 700 -p target && sudo mount -t 9p -o dfltgid=$(grep ^docker: /etc/group | cut -d: -f3),dfltuid=$(id -u docker) src target", + "/bin/bash -c [ \"x$(findmnt -T target | grep target)\" != \"x\" ] && /bin/bash -c sudo umount -f target || echo ", + "/bin/bash -c sudo mkdir -m 700 -p target && /bin/bash -c sudo mount -t 9p -o dfltgid=$(grep ^docker: /etc/group | cut -d: -f3),dfltuid=$(id -u docker) src target", }, }, { @@ -79,7 +82,7 @@ func TestMount(t *testing.T) { "cache": "fscache", }}, want: []string{ - "[ \"x$(findmnt -T /target | grep /target)\" != \"x\" ] && sudo umount -f /target || echo ", + "[ \"x$(findmnt -T /target | grep /target)\" != \"x\" ] && /bin/bash -c sudo umount -f /target || echo ", "sudo mkdir -m 777 -p /target && sudo mount -t 9p -o cache=fscache,dfltgid=72,dfltuid=82,noextend,version=9p2000.u 10.0.0.1 /target", }, }, @@ -91,8 +94,8 @@ func TestMount(t *testing.T) { "version": "9p2000.L", }}, want: []string{ - "[ \"x$(findmnt -T tgt | grep tgt)\" != \"x\" ] && sudo umount -f tgt || echo ", - "sudo mkdir -m 700 -p tgt && sudo mount -t 9p -o dfltgid=0,dfltuid=0,version=9p2000.L src tgt", + "/bin/bash -c [ \"x$(findmnt -T tgt | grep tgt)\" != \"x\" ] && /bin/bash -c sudo umount -f tgt || echo ", + "/bin/bash -c sudo mkdir -m 700 -p tgt && sudo mount -t 9p -o dfltgid=0,dfltuid=0,version=9p2000.L src tgt", }, }, } @@ -103,7 +106,9 @@ func TestMount(t *testing.T) { if err != nil { t.Fatalf("Mount(%s, %s, %+v): %v", tc.source, tc.target, tc.cfg, err) } - if diff := cmp.Diff(r.cmds, tc.want); diff != "" { + got := strings.Join(r.cmds, " ") + want := strings.Join(tc.want, " ") + if diff := cmp.Diff(got, want); diff != "" { t.Errorf("command diff (-want +got): %s", diff) } }) @@ -117,7 +122,7 @@ func TestUnmount(t *testing.T) { t.Fatalf("Unmount(/mnt): %v", err) } - want := []string{"[ \"x$(findmnt -T /mnt | grep /mnt)\" != \"x\" ] && sudo umount -f /mnt || echo "} + want := []string{"[ \"x$(findmnt -T /mnt | grep /mnt)\" != \"x\" ] && /bin/bash -c sudo umount -f /mnt || echo "} if diff := cmp.Diff(r.cmds, want); diff != "" { t.Errorf("command diff (-want +got): %s", diff) } diff --git a/pkg/minikube/command/ssh_runner.go b/pkg/minikube/command/ssh_runner.go index ae07a3a24f5a..ee8ea16f1266 100644 --- a/pkg/minikube/command/ssh_runner.go +++ b/pkg/minikube/command/ssh_runner.go @@ -106,9 +106,9 @@ func (s *SSHRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { rr := &RunResult{Args: cmd.Args} glog.Infof("(SSHRunner) Run: %v", rr.Command()) - var outb, errb bytes.Buffer - cmd.Stdout, rr.Stdout = &outb, &outb - cmd.Stderr, rr.Stderr = &errb, &errb + var outb, errb singleWriter + rr.Stdout = &outb.b + rr.Stderr = &errb.b start := time.Now() sess, err := s.c.NewSession() diff --git a/pkg/minikube/cruntime/cruntime_test.go b/pkg/minikube/cruntime/cruntime_test.go index a0ddb254df3f..0cf963c337e2 100644 --- a/pkg/minikube/cruntime/cruntime_test.go +++ b/pkg/minikube/cruntime/cruntime_test.go @@ -23,8 +23,10 @@ import ( "strings" "testing" + "github.com/golang/glog" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" + "github.com/kballard/go-shellquote" "github.com/pkg/errors" "k8s.io/minikube/pkg/minikube/command" ) @@ -116,13 +118,17 @@ func NewFakeRunner(t *testing.T) *FakeRunner { // Run a fake command! func (f *FakeRunner) RunCmd(cmd *exec.Cmd) (*command.RunResult, error) { - f.cmds = append(f.cmds, cmd.Args...) + xargs, err := shellquote.Split(cmd.Args[2]) + if err != nil { + glog.Infof("FakeRunner shellquote.Split error %v", err) + } + f.cmds = append(f.cmds, xargs...) root := false - bin, args := cmd.Args[2], cmd.Args[3:] + bin, args := xargs[0], xargs[1:] f.t.Logf("bin=%s args=%v", bin, args) if bin == "sudo" { root = true - bin, args = args[3], args[4:] + bin, args = xargs[1], xargs[2:] } switch bin { case "systemctl": @@ -148,7 +154,7 @@ func (f *FakeRunner) RunCmd(cmd *exec.Cmd) (*command.RunResult, error) { buf := new(bytes.Buffer) _, err = buf.WriteString(s) if err != nil { - return rr, errors.Wrap(err, "Writing FakeRunner's buffer") + return rr, errors.Wrap(err, "Writing FakeRunner's buffer") } rr.Stdout = buf rr.Stderr = buf @@ -209,8 +215,8 @@ func (f *FakeRunner) docker(args []string, _ bool) (string, error) { case "ps": // ps -a --filter="name=apiserver" --format="{{.ID}}" if args[1] == "-a" && strings.HasPrefix(args[2], "--filter") { - filter := strings.Split(args[2], `"`)[1] - fname := strings.Split(filter, "=")[1] + filter := strings.Split(args[2], `"`)[0] + fname := strings.Split(filter, "=")[2] ids := []string{} f.t.Logf("fake docker: Looking for containers matching %q", fname) for id, cname := range f.containers { @@ -240,10 +246,10 @@ func (f *FakeRunner) docker(args []string, _ bool) (string, error) { } case "version": - if args[1] == "--format" && args[2] == "'{{.Server.Version}}'" { + + if args[1] == "--format" && args[2] == "{{.Server.Version}}" { return "18.06.2-ce", nil } - } return "", nil } @@ -413,9 +419,9 @@ func TestDisable(t *testing.T) { runtime string want []string }{ - {"docker", []string{"/bin/bash -c sudo systemctl stop docker docker.socket"}}, - {"crio", []string{"/bin/bash -c sudo systemctl stop crio"}}, - {"containerd", []string{"/bin/bash -c sudo systemctl stop containerd"}}, + {"docker", []string{"sudo", "systemctl", "stop", "docker", "docker.socket"}}, + {"crio", []string{"sudo", "systemctl", "stop", "crio"}}, + {"containerd", []string{"sudo", "systemctl", "stop", "containerd"}}, } for _, tc := range tests { t.Run(tc.runtime, func(t *testing.T) { From 749c34ae6c05a6ce77cc507201154ba25f8bf2b9 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Sat, 12 Oct 2019 10:30:54 -0700 Subject: [PATCH 33/59] adding a logging to make sure jenkins is running right thing --- cmd/minikube/cmd/start.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index 21b522eddb2e..40f8f738ed33 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -1012,7 +1012,7 @@ func setupKubeAdm(mAPI libmachine.API, kc cfg.KubernetesConfig) bootstrapper.Boo } // Loads cached images, generates config files, download binaries if err := bs.UpdateCluster(kc); err != nil { - exit.WithError("Failed to update cluster", err) + exit.WithError("Failed to update cluster<--Temproary logging-->", err) } if err := bs.SetupCerts(kc); err != nil { exit.WithError("Failed to setup certs", err) From 1da56c571cc5daacdcd83e29edba92d4c2a8e5ee Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Sat, 12 Oct 2019 10:59:20 -0700 Subject: [PATCH 34/59] printing minikube version and commit id before test --- hack/jenkins/common.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hack/jenkins/common.sh b/hack/jenkins/common.sh index e48f34e044b7..991b528341a9 100755 --- a/hack/jenkins/common.sh +++ b/hack/jenkins/common.sh @@ -235,6 +235,9 @@ fi echo "" echo ">> Starting ${E2E_BIN} at $(date)" +echo ">> The version and commit id of minikube binary in this test" +echo out/minikube-${OS_ARCH} version + ${SUDO_PREFIX}${E2E_BIN} \ -minikube-start-args="--vm-driver=${VM_DRIVER} ${EXTRA_START_ARGS}" \ -test.timeout=60m \ From 5c9d98f9e4ed0688cfd9233815e1828f019719f3 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Sat, 12 Oct 2019 11:06:49 -0700 Subject: [PATCH 35/59] echo minikube version in integration script --- hack/jenkins/common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/jenkins/common.sh b/hack/jenkins/common.sh index 991b528341a9..f132a11a2ede 100755 --- a/hack/jenkins/common.sh +++ b/hack/jenkins/common.sh @@ -236,7 +236,7 @@ fi echo "" echo ">> Starting ${E2E_BIN} at $(date)" echo ">> The version and commit id of minikube binary in this test" -echo out/minikube-${OS_ARCH} version +echo $(out/minikube-${OS_ARCH} version) ${SUDO_PREFIX}${E2E_BIN} \ -minikube-start-args="--vm-driver=${VM_DRIVER} ${EXTRA_START_ARGS}" \ From a7de6c70eb5fbc2ce726e935c409a9e4c720e7bb Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Sat, 12 Oct 2019 11:18:19 -0700 Subject: [PATCH 36/59] add minikube binary version --- hack/jenkins/common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/jenkins/common.sh b/hack/jenkins/common.sh index f132a11a2ede..28364d16140e 100755 --- a/hack/jenkins/common.sh +++ b/hack/jenkins/common.sh @@ -235,7 +235,7 @@ fi echo "" echo ">> Starting ${E2E_BIN} at $(date)" -echo ">> The version and commit id of minikube binary in this test" +echo ">> The minikube version & commit id:" echo $(out/minikube-${OS_ARCH} version) ${SUDO_PREFIX}${E2E_BIN} \ From aace212e15b376bb5e972f2e4ed837ecf0e9119d Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Mon, 14 Oct 2019 15:49:11 -0700 Subject: [PATCH 37/59] fix unit test, remove mount fake runner --- pkg/minikube/cluster/mount.go | 7 +-- pkg/minikube/cluster/mount_test.go | 69 ++++-------------------------- 2 files changed, 13 insertions(+), 63 deletions(-) diff --git a/pkg/minikube/cluster/mount.go b/pkg/minikube/cluster/mount.go index 5d7755af072b..8c45fe65082f 100644 --- a/pkg/minikube/cluster/mount.go +++ b/pkg/minikube/cluster/mount.go @@ -64,7 +64,8 @@ func Mount(r mountRunner, source string, target string, c *MountConfig) error { glog.Infof("Failed to create folder pre-mount: err=%v, output: %q", err, rr.Output()) return errors.Wrap(err, "create folder pre-mount") } - rr, err = r.RunCmd(mntCmd(source, target, c)) + + rr, err = r.RunCmd(exec.Command("/bin/bash", "-c", mntCmd(source, target, c))) if err != nil { glog.Infof("Failed to create folder before mount: err=%s, output: %q", err, rr.Output()) return errors.Wrap(err, rr.Output()) @@ -102,7 +103,7 @@ func resolveGID(id string) string { } // mntCmd returns a mount command based on a config. -func mntCmd(source string, target string, c *MountConfig) *exec.Cmd { +func mntCmd(source string, target string, c *MountConfig) string { options := map[string]string{ "dfltgid": resolveGID(c.GID), "dfltuid": resolveUID(c.UID), @@ -133,7 +134,7 @@ func mntCmd(source string, target string, c *MountConfig) *exec.Cmd { opts = append(opts, fmt.Sprintf("%s=%s", k, v)) } sort.Strings(opts) - return exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo mount -t %s -o %s %s %s", c.Type, strings.Join(opts, ","), source, target)) + return fmt.Sprintf("sudo mount -t %s -o %s %s %s", c.Type, strings.Join(opts, ","), source, target) } // Unmount unmounts a path diff --git a/pkg/minikube/cluster/mount_test.go b/pkg/minikube/cluster/mount_test.go index ae7671bbf66e..bb1890069c24 100644 --- a/pkg/minikube/cluster/mount_test.go +++ b/pkg/minikube/cluster/mount_test.go @@ -17,61 +17,33 @@ limitations under the License. package cluster import ( - "bytes" "os" - "os/exec" - "strings" "testing" "github.com/google/go-cmp/cmp" - "k8s.io/minikube/pkg/minikube/command" ) -type mockMountRunner struct { - cmds []string - T *testing.T -} - -func newMockMountRunner(t *testing.T) *mockMountRunner { - return &mockMountRunner{ - T: t, - cmds: []string{}, - } -} - -func (m *mockMountRunner) RunCmd(cmd *exec.Cmd) (*command.RunResult, error) { - m.cmds = append(m.cmds, strings.Join(cmd.Args, " ")) - buf := new(bytes.Buffer) - return &command.RunResult{Stdout: buf, Stderr: buf}, nil -} - -func TestMount(t *testing.T) { +func TestMntCmd(t *testing.T) { var tests = []struct { name string source string target string cfg *MountConfig - want []string + want string }{ { name: "simple", source: "src", target: "target", cfg: &MountConfig{Type: "9p", Mode: os.FileMode(0700)}, - want: []string{ - "/bin/bash -c [ \"x$(findmnt -T target | grep target)\" != \"x\" ] && /bin/bash -c sudo umount -f target || echo ", - "/bin/bash -c sudo mkdir -m 700 -p target && /bin/bash -c sudo mount -t 9p -o dfltgid=0,dfltuid=0 src target /bin/bash -c sudo mount -t 9p -o dfltgid=0,dfltuid=0 src target", - }, + want: "sudo mount -t 9p -o dfltgid=0,dfltuid=0 src target", }, { name: "named uid", source: "src", target: "target", cfg: &MountConfig{Type: "9p", Mode: os.FileMode(0700), UID: "docker", GID: "docker"}, - want: []string{ - "/bin/bash -c [ \"x$(findmnt -T target | grep target)\" != \"x\" ] && /bin/bash -c sudo umount -f target || echo ", - "/bin/bash -c sudo mkdir -m 700 -p target && /bin/bash -c sudo mount -t 9p -o dfltgid=$(grep ^docker: /etc/group | cut -d: -f3),dfltuid=$(id -u docker) src target", - }, + want: "sudo mount -t 9p -o dfltgid=$(grep ^docker: /etc/group | cut -d: -f3),dfltuid=$(id -u docker) src target", }, { name: "everything", @@ -81,10 +53,7 @@ func TestMount(t *testing.T) { "noextend": "", "cache": "fscache", }}, - want: []string{ - "[ \"x$(findmnt -T /target | grep /target)\" != \"x\" ] && /bin/bash -c sudo umount -f /target || echo ", - "sudo mkdir -m 777 -p /target && sudo mount -t 9p -o cache=fscache,dfltgid=72,dfltuid=82,noextend,version=9p2000.u 10.0.0.1 /target", - }, + want: "sudo mount -t 9p -o cache=fscache,dfltgid=72,dfltuid=82,noextend,version=9p2000.u 10.0.0.1 /target", }, { name: "version-conflict", @@ -93,37 +62,17 @@ func TestMount(t *testing.T) { cfg: &MountConfig{Type: "9p", Mode: os.FileMode(0700), Version: "9p2000.u", Options: map[string]string{ "version": "9p2000.L", }}, - want: []string{ - "/bin/bash -c [ \"x$(findmnt -T tgt | grep tgt)\" != \"x\" ] && /bin/bash -c sudo umount -f tgt || echo ", - "/bin/bash -c sudo mkdir -m 700 -p tgt && sudo mount -t 9p -o dfltgid=0,dfltuid=0,version=9p2000.L src tgt", - }, + want: "sudo mount -t 9p -o dfltgid=0,dfltuid=0,version=9p2000.L src tgt", }, } + for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - r := newMockMountRunner(t) - err := Mount(r, tc.source, tc.target, tc.cfg) - if err != nil { - t.Fatalf("Mount(%s, %s, %+v): %v", tc.source, tc.target, tc.cfg, err) - } - got := strings.Join(r.cmds, " ") - want := strings.Join(tc.want, " ") + got := mntCmd(tc.source, tc.target, tc.cfg) + want := tc.want if diff := cmp.Diff(got, want); diff != "" { t.Errorf("command diff (-want +got): %s", diff) } }) } } - -func TestUnmount(t *testing.T) { - r := newMockMountRunner(t) - err := Unmount(r, "/mnt") - if err != nil { - t.Fatalf("Unmount(/mnt): %v", err) - } - - want := []string{"[ \"x$(findmnt -T /mnt | grep /mnt)\" != \"x\" ] && /bin/bash -c sudo umount -f /mnt || echo "} - if diff := cmp.Diff(r.cmds, want); diff != "" { - t.Errorf("command diff (-want +got): %s", diff) - } -} From 74b7054b4adcbccbe3499ea292936c07d56dfef7 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Tue, 15 Oct 2019 12:59:51 -0700 Subject: [PATCH 38/59] fixing logs --- pkg/minikube/logs/logs.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/minikube/logs/logs.go b/pkg/minikube/logs/logs.go index 671dbf7fc4e5..418bf7b710fa 100644 --- a/pkg/minikube/logs/logs.go +++ b/pkg/minikube/logs/logs.go @@ -147,8 +147,7 @@ func Output(r cruntime.Manager, bs bootstrapper.Bootstrapper, runner command.Run } out.T(out.Empty, "==> {{.name}} <==", out.V{"name": name}) var b bytes.Buffer - - c := exec.Command(cmds[name]) + c := exec.Command("/bin/bash", "-c", cmds[name]) c.Stdin = &b c.Stdout = &b if rr, err := runner.RunCmd(c); err != nil { From 48cd8620f2eab88fe8f6b50fa2573d67d8c8e11e Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Mon, 21 Oct 2019 10:59:33 -0700 Subject: [PATCH 39/59] fix stdout,stderr --- pkg/minikube/command/exec_runner.go | 15 +++++++++++++-- pkg/minikube/command/ssh_runner.go | 13 +++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/pkg/minikube/command/exec_runner.go b/pkg/minikube/command/exec_runner.go index 311518a13da9..a4e401b082db 100644 --- a/pkg/minikube/command/exec_runner.go +++ b/pkg/minikube/command/exec_runner.go @@ -42,8 +42,19 @@ func (*ExecRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { glog.Infof("(ExecRunner) Run: %v", rr.Command()) var outb, errb bytes.Buffer - cmd.Stdout, rr.Stdout = &outb, &outb - cmd.Stderr, rr.Stderr = &errb, &errb + if cmd.Stdout == nil { + cmd.Stdout, rr.Stdout = &outb, &outb + } else { + io.MultiWriter(rr.Stdout, &outb) + rr.Stdout = &outb + } + if cmd.Stderr == nil { + cmd.Stderr, rr.Stderr = &errb, &errb + } else { + io.MultiWriter(rr.Stderr, &errb) + rr.Stdout = &errb + } + start := time.Now() err := cmd.Run() elapsed := time.Since(start) diff --git a/pkg/minikube/command/ssh_runner.go b/pkg/minikube/command/ssh_runner.go index ee8ea16f1266..edfa54d2d531 100644 --- a/pkg/minikube/command/ssh_runner.go +++ b/pkg/minikube/command/ssh_runner.go @@ -111,6 +111,19 @@ func (s *SSHRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { rr.Stderr = &errb.b start := time.Now() + if cmd.Stdout == nil { + cmd.Stdout, rr.Stdout = &outb, &outb.b + } else { + io.MultiWriter(rr.Stdout, &outb) + rr.Stdout = &outb.b + } + if cmd.Stderr == nil { + cmd.Stderr, rr.Stderr = &errb, &errb.b + } else { + io.MultiWriter(rr.Stderr, &errb) + rr.Stdout = &errb.b + } + sess, err := s.c.NewSession() if err != nil { return rr, errors.Wrap(err, "NewSession") From 342397ab4602c3bc62e4bf5d7d9526dbbc89ce88 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Mon, 21 Oct 2019 11:40:10 -0700 Subject: [PATCH 40/59] convert more to exec.Command --- cmd/minikube/cmd/start.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index 32c545caba23..bcdfd1675be1 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -1007,12 +1007,12 @@ Suggested workarounds: defer conn.Close() } - if err := r.Run("nslookup kubernetes.io"); err != nil { + if _, err := r.RunCmd(exec.Command("/bin/bash", "-c", "nslookup kubernetes.io")); err != nil { out.WarningT("VM is unable to resolve DNS hosts: {[.error}}", out.V{"error": err}) } // Try both UDP and ICMP to assert basic external connectivity - if err := r.Run("nslookup k8s.io 8.8.8.8 || nslookup k8s.io 1.1.1.1 || ping -c1 8.8.8.8"); err != nil { + if _, err := r.RunCmd(exec.Command("/bin/bash", "-c", "nslookup k8s.io 8.8.8.8 || nslookup k8s.io 1.1.1.1 || ping -c1 8.8.8.8")); err != nil { out.WarningT("VM is unable to directly connect to the internet: {{.error}}", out.V{"error": err}) } @@ -1027,7 +1027,8 @@ Suggested workarounds: if repo == "" { repo = images.DefaultImageRepo } - if err := r.Run(fmt.Sprintf("curl %s https://%s/", opts, repo)); err != nil { + + if _, err := r.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("curl %s https://%s/", opts, repo))); err != nil { out.WarningT("VM is unable to connect to the selected image repository: {{.error}}", out.V{"error": err}) } return ip From 6faf9cdbe76abfe030ddec954f4c5fba491a0799 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Mon, 21 Oct 2019 13:01:06 -0700 Subject: [PATCH 41/59] lint and code review --- .travis.yml | 3 --- cmd/minikube/cmd/start.go | 2 +- hack/jenkins/common.sh | 3 --- pkg/drivers/none/none.go | 2 +- pkg/minikube/bootstrapper/certs.go | 2 +- pkg/minikube/cluster/mount.go | 1 - pkg/minikube/command/command_runner.go | 3 ++- pkg/minikube/command/ssh_runner.go | 8 +------ pkg/minikube/command/ssh_runner_test.go | 32 ------------------------- pkg/minikube/cruntime/cruntime_test.go | 5 +--- test/integration/Untitled-1 | 0 11 files changed, 7 insertions(+), 54 deletions(-) delete mode 100644 test/integration/Untitled-1 diff --git a/.travis.yml b/.travis.yml index a8afe7095a9f..39089ee1503c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,9 +36,6 @@ matrix: script: make test after_success: - bash <(curl -s https://codecov.io/bash) -travisBuddy: - regex: (FAIL:|\.go:\d+:|^panic:|failed$) - regexOptions: "g" notifications: webhooks: urls: diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index bcdfd1675be1..6fe437d61eb9 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -1102,7 +1102,7 @@ func setupKubeAdm(mAPI libmachine.API, kc cfg.KubernetesConfig) bootstrapper.Boo } // Loads cached images, generates config files, download binaries if err := bs.UpdateCluster(kc); err != nil { - exit.WithError("Failed to update cluster<--Temproary logging-->", err) + exit.WithError("Failed to update cluster", err) } if err := bs.SetupCerts(kc); err != nil { exit.WithError("Failed to setup certs", err) diff --git a/hack/jenkins/common.sh b/hack/jenkins/common.sh index 72c816684543..ccd921616037 100755 --- a/hack/jenkins/common.sh +++ b/hack/jenkins/common.sh @@ -256,9 +256,6 @@ fi echo "" echo ">> Starting ${E2E_BIN} at $(date)" -echo ">> The minikube version & commit id:" -echo $(out/minikube-${OS_ARCH} version) - ${SUDO_PREFIX}${E2E_BIN} \ -minikube-start-args="--vm-driver=${VM_DRIVER} ${EXTRA_START_ARGS}" \ -test.timeout=60m \ diff --git a/pkg/drivers/none/none.go b/pkg/drivers/none/none.go index 2dde1ff0f855..0c24ddb840d7 100644 --- a/pkg/drivers/none/none.go +++ b/pkg/drivers/none/none.go @@ -225,7 +225,7 @@ func (d *Driver) RunSSHCommandFromDriver() error { func stopKubelet(cr command.Runner) error { glog.Infof("stopping kubelet.service ...") stop := func() error { - cmdStop := exec.Command("/bin/bash", "-c", "sudo systemctl stop kubelet.service") + cmdStop := exec.Command("/bin/bash", "sudo systemctl stop kubelet.service") if rr, err := cr.RunCmd(cmdStop); err != nil { glog.Errorf("temporary error for %q : %v", rr.Command(), err) } diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index 783412b69aac..636b43ec95c5 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -332,7 +332,7 @@ func getSubjectHash(cr command.Runner, filePath string) (string, error) { // OpenSSL binary required in minikube ISO func configureCACerts(cr command.Runner, caCerts map[string]string) error { hasSSLBinary := true - c := exec.Command("/bin/bash", "-c", "which openssl") + c := exec.Command("/bin/bash", "-c", "openssl version") _, err := cr.RunCmd(c) if err != nil { hasSSLBinary = false diff --git a/pkg/minikube/cluster/mount.go b/pkg/minikube/cluster/mount.go index 8c45fe65082f..6d97d4873fc1 100644 --- a/pkg/minikube/cluster/mount.go +++ b/pkg/minikube/cluster/mount.go @@ -142,7 +142,6 @@ func Unmount(r mountRunner, target string) error { // grep because findmnt will also display the parent! c := exec.Command("/bin/bash", "-c", fmt.Sprintf("[ \"x$(findmnt -T %s | grep %s)\" != \"x\" ] && sudo umount -f %s || echo ", target, target, target)) if rr, err := r.RunCmd(c); err != nil { - glog.Infof("unmount force err=%v, out=%s", err, rr.Output()) return errors.Wrap(err, rr.Output()) } glog.Infof("unmount for %s ran successfully", target) diff --git a/pkg/minikube/command/command_runner.go b/pkg/minikube/command/command_runner.go index 3c63e3956d8a..c57d85f363ff 100644 --- a/pkg/minikube/command/command_runner.go +++ b/pkg/minikube/command/command_runner.go @@ -26,11 +26,12 @@ import ( "k8s.io/minikube/pkg/minikube/assets" ) +// RunResult holds the results of a Runner type RunResult struct { Stdout *bytes.Buffer Stderr *bytes.Buffer ExitCode int - Args []string + Args []string // the args that was passed to Runner } // Runner represents an interface to run commands. diff --git a/pkg/minikube/command/ssh_runner.go b/pkg/minikube/command/ssh_runner.go index edfa54d2d531..6a5a8f7a06e0 100644 --- a/pkg/minikube/command/ssh_runner.go +++ b/pkg/minikube/command/ssh_runner.go @@ -138,7 +138,7 @@ func (s *SSHRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { }() elapsed := time.Since(start) - err = teeSSH(sess, cmdToStr(cmd), &outb, &errb) + err = teeSSH(sess, shellquote.Join(cmd.Args...), &outb, &errb) if err == nil { // Reduce log spam if elapsed > (1 * time.Second) { @@ -153,12 +153,6 @@ func (s *SSHRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { return rr, err } -// converts a exec.Cmd to string to be used by ssh runner -func cmdToStr(cmd *exec.Cmd) string { - //strings.Join(cmd.Args, " ") - return shellquote.Join(cmd.Args...) -} - // Copy copies a file to the remote over SSH. func (s *SSHRunner) Copy(f assets.CopyableFile) error { sess, err := s.c.NewSession() diff --git a/pkg/minikube/command/ssh_runner_test.go b/pkg/minikube/command/ssh_runner_test.go index 32500cd59620..df9e7d509e60 100644 --- a/pkg/minikube/command/ssh_runner_test.go +++ b/pkg/minikube/command/ssh_runner_test.go @@ -19,7 +19,6 @@ package command import ( "bytes" "fmt" - "os/exec" "strings" "sync" "testing" @@ -62,34 +61,3 @@ func TestTeePrefix(t *testing.T) { t.Errorf("log=%q, want: %q", gotLog, wantLog) } } - -func TestCmdToStr(t *testing.T) { - tests := []struct { - name string - cmd *exec.Cmd - expected string - }{ - { - name: "simple ls no bin/bash", - cmd: exec.Command("ls", "-la"), - expected: "ls -la", - }, - { - name: "with /bin/bash and with &", - cmd: exec.Command("/bin/bash", "-c", "ls -lah && pwd"), - expected: "/bin/bash -c 'ls -lah && pwd'", - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - got := cmdToStr((tc.cmd)) - if got != tc.expected { - t.Errorf("Expected %s but got %s ", tc.expected, got) - } - - }) - } - -} diff --git a/pkg/minikube/cruntime/cruntime_test.go b/pkg/minikube/cruntime/cruntime_test.go index 0cf963c337e2..678a544226f5 100644 --- a/pkg/minikube/cruntime/cruntime_test.go +++ b/pkg/minikube/cruntime/cruntime_test.go @@ -255,13 +255,10 @@ func (f *FakeRunner) docker(args []string, _ bool) (string, error) { } // crio is a fake implementation of crio -func (f *FakeRunner) crio(args []string, _ bool) (string, error) { +func (f *FakeRunner) crio(args []string, _ bool) (string, error) { //nolint (result 1 (error) is always nil) if args[0] == "--version" { return "crio version 1.13.0", nil } - if args[0] == "something" { // doing this to suppress lint "result 1 (error) is always nil" - return "", fmt.Errorf("unknown args[0]") - } return "", nil } diff --git a/test/integration/Untitled-1 b/test/integration/Untitled-1 deleted file mode 100644 index e69de29bb2d1..000000000000 From 6e1c4f62caef0f0d6f220270ff799922b84c6562 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Mon, 21 Oct 2019 13:50:00 -0700 Subject: [PATCH 42/59] trying to fix logs --- pkg/minikube/logs/logs.go | 2 +- pkg/minikube/problem/err_map.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/minikube/logs/logs.go b/pkg/minikube/logs/logs.go index 418bf7b710fa..2400a595fe1e 100644 --- a/pkg/minikube/logs/logs.go +++ b/pkg/minikube/logs/logs.go @@ -148,8 +148,8 @@ func Output(r cruntime.Manager, bs bootstrapper.Bootstrapper, runner command.Run out.T(out.Empty, "==> {{.name}} <==", out.V{"name": name}) var b bytes.Buffer c := exec.Command("/bin/bash", "-c", cmds[name]) - c.Stdin = &b c.Stdout = &b + c.Stderr = &b if rr, err := runner.RunCmd(c); err != nil { glog.Errorf("command %s failed with error: %v output: %q", rr.Command(), err, rr.Output()) failed = append(failed, name) diff --git a/pkg/minikube/problem/err_map.go b/pkg/minikube/problem/err_map.go index f2bb49c5e941..bad986cdcf0d 100644 --- a/pkg/minikube/problem/err_map.go +++ b/pkg/minikube/problem/err_map.go @@ -56,7 +56,7 @@ var vmProblems = map[string]match{ Issues: []int{1926, 4206}, }, "HYPERKIT_NOT_FOUND": { - Regexp: re(`Driver "hyperkit" not found. Do you have the plugin binary .* accessible in your PATH?`), + Regexp: re(`Driver "hyperkit" not found.`), Advice: "Please install the minikube hyperkit VM driver, or select an alternative --vm-driver", URL: "https://minikube.sigs.k8s.io/docs/reference/drivers/hyperkit/", HideCreateLink: true, From 05bbcf733ac04203dab703184ac0787e5c89d0f0 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Mon, 21 Oct 2019 15:18:04 -0700 Subject: [PATCH 43/59] remove uneeded wrap output --- pkg/drivers/none/none.go | 14 ++++++------ pkg/minikube/bootstrapper/certs.go | 8 +++---- pkg/minikube/bootstrapper/kubeadm/kubeadm.go | 24 ++++++++++---------- pkg/minikube/cluster/mount.go | 10 ++++---- pkg/minikube/command/exec_runner.go | 2 ++ pkg/minikube/cruntime/containerd.go | 22 +++++++++--------- pkg/minikube/cruntime/cri.go | 20 ++++++++-------- pkg/minikube/cruntime/crio.go | 18 +++++++-------- pkg/minikube/cruntime/cruntime.go | 8 +++---- pkg/minikube/cruntime/docker.go | 22 +++++++++--------- pkg/minikube/logs/logs.go | 5 ++-- 11 files changed, 75 insertions(+), 78 deletions(-) diff --git a/pkg/drivers/none/none.go b/pkg/drivers/none/none.go index 0c24ddb840d7..3013e0703f2b 100644 --- a/pkg/drivers/none/none.go +++ b/pkg/drivers/none/none.go @@ -174,8 +174,8 @@ func (d *Driver) Remove() error { } glog.Infof("Removing: %s", cleanupPaths) c := exec.Command("sudo", "rm", "-rf", shellquote.Join(cleanupPaths...)) - if rr, err := d.exec.RunCmd(c); err != nil { - glog.Errorf("cleanup incomplete: %v , output: %s", err, rr.Output()) + if _, err := d.exec.RunCmd(c); err != nil { + glog.Errorf("cleanup incomplete: %v", err) } return nil } @@ -234,7 +234,7 @@ func stopKubelet(cr command.Runner) error { cmdCheck.Stdout = &out cmdCheck.Stderr = &out if rr, err := cr.RunCmd(cmdCheck); err != nil { - glog.Errorf("temporary error: for %q : %v output: %q", rr.Command(), err, rr.Output()) + glog.Errorf("temporary error: for %q : %v", rr.Command(), err) } if !strings.Contains(out.String(), "dead") && !strings.Contains(out.String(), "failed") { return fmt.Errorf("unexpected kubelet state: %q", out) @@ -253,8 +253,8 @@ func stopKubelet(cr command.Runner) error { func restartKubelet(cr command.Runner) error { glog.Infof("restarting kubelet.service ...") c := exec.Command("/bin/bash", "-c", "sudo systemctl restart kubelet.service") - if rr, err := cr.RunCmd(c); err != nil { - return errors.Wrapf(err, "restartKubelet output: %s", rr.Output()) + if _, err := cr.RunCmd(c); err != nil { + return errors.Wrapf(err, "restartKubelet") } return nil } @@ -263,8 +263,8 @@ func restartKubelet(cr command.Runner) error { func checkKubelet(cr command.Runner) error { glog.Infof("checking for running kubelet ...") c := exec.Command("/bin/bash", "-c", "systemctl is-active --quiet service kubelet") - if rr, err := cr.RunCmd(c); err != nil { - return errors.Wrapf(err, "checkKubelet output: %s", rr.Output()) + if _, err := cr.RunCmd(c); err != nil { + return errors.Wrap(err, "checkKubelet") } return nil } diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index 636b43ec95c5..484a51e02806 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -350,8 +350,8 @@ func configureCACerts(cr command.Runner, caCerts map[string]string) error { if err != nil { c = exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ln -s '%s' '%s'", caCertFile, certStorePath)) - if rr, err := cr.RunCmd(c); err != nil { - return errors.Wrapf(err, "error making symbol link for certificate %s output: %s", caCertFile, rr.Output()) + if _, err := cr.RunCmd(c); err != nil { + return errors.Wrapf(err, "error making symbol link for certificate %s", caCertFile) } } if hasSSLBinary { @@ -363,8 +363,8 @@ func configureCACerts(cr command.Runner, caCerts map[string]string) error { _, err = cr.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo test -f %s", subjectHashLink))) if err != nil { - if rr, err := cr.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ln -s '%s' '%s'", certStorePath, subjectHashLink))); err != nil { - return errors.Wrapf(err, "error making subject hash symbol %s link for certificate %s. output: %q", subjectHash, caCertFile, rr.Output()) + if _, err := cr.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ln -s '%s' '%s'", certStorePath, subjectHashLink))); err != nil { + return errors.Wrapf(err, "error making subject hash symbol %s link for certificate %s.", subjectHash, caCertFile) } } } diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index bcfbdbf01aa7..ea192f26c797 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -139,7 +139,7 @@ func NewKubeadmBootstrapper(api libmachine.API) (*Bootstrapper, error) { func (k *Bootstrapper) GetKubeletStatus() (string, error) { rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "sudo systemctl is-active kubelet")) if err != nil { - return "", errors.Wrapf(err, "getting kublet status. command: %q output: %q", rr.Command(), rr.Output()) + return "", errors.Wrapf(err, "getting kublet status. command: %q", rr.Command()) } s := strings.TrimSpace(rr.Stdout.String() + rr.Stderr.String()) switch s { @@ -224,14 +224,14 @@ func (k *Bootstrapper) createCompatSymlinks() error { legacyEtcd := "/data/minikube" rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo test -d %s", legacyEtcd))) if err != nil { - glog.Infof("%s check failed, skipping compat symlinks: %v %q", legacyEtcd, err, rr.Output()) + glog.Infof("%s check failed, skipping compat symlinks: %v", legacyEtcd, err) return nil } glog.Infof("Found %s, creating compatibility symlinks ...", legacyEtcd) c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ln -s %s %s", legacyEtcd, etcdDataDir())) if rr, err = k.c.RunCmd(c); err != nil { - return errors.Wrapf(err, "create symlink failed: %s\n%q\n", rr.Command(), rr.Output()) + return errors.Wrapf(err, "create symlink failed: %s", rr.Command()) } return nil } @@ -275,7 +275,7 @@ func (k *Bootstrapper) StartCluster(k8s config.KubernetesConfig) error { c := exec.Command("/bin/bash", "-c", fmt.Sprintf("%s init --config %s %s --ignore-preflight-errors=%s", invokeKubeadm(k8s.KubernetesVersion), yamlConfigPath, extraFlags, strings.Join(ignore, ","))) if rr, err := k.c.RunCmd(c); err != nil { - return errors.Wrapf(err, "init failed. cmd: %q output:%q", rr.Command(), rr.Output()) + return errors.Wrapf(err, "init failed. cmd: %q", rr.Command()) } glog.Infof("Configuring cluster permissions ...") @@ -314,7 +314,7 @@ func (k *Bootstrapper) adjustResourceLimits() error { // Prevent the apiserver from OOM'ing before other pods, as it is our gateway into the cluster. // It'd be preferable to do this via Kubernetes, but kubeadm doesn't have a way to set pod QoS. if rr, err = k.c.RunCmd(exec.Command("/bin/bash", "-c", "echo -10 | sudo tee /proc/$(pgrep kube-apiserver)/oom_adj")); err != nil { - return errors.Wrap(err, fmt.Sprintf("oom_adj adjust: %s", rr.Output())) + return errors.Wrap(err, fmt.Sprintf("oom_adj adjust")) } return nil @@ -436,7 +436,7 @@ func (k *Bootstrapper) RestartCluster(k8s config.KubernetesConfig) error { for _, c := range cmds { rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", c)) if err != nil { - return errors.Wrapf(err, "running cmd: %s , output: %s", rr.Command(), rr.Output()) + return errors.Wrapf(err, "running cmd: %s", rr.Command()) } } @@ -446,7 +446,7 @@ func (k *Bootstrapper) RestartCluster(k8s config.KubernetesConfig) error { // restart the proxy and coredns if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("%s phase addon all --config %s", baseCmd, yamlConfigPath))); err != nil { - return errors.Wrapf(err, fmt.Sprintf("addon phase cmd:%q output:%q", rr.Command(), rr.Output())) + return errors.Wrapf(err, fmt.Sprintf("addon phase cmd:%q", rr.Command())) } if err := k.adjustResourceLimits(); err != nil { @@ -468,7 +468,7 @@ func (k *Bootstrapper) waitForAPIServer(k8s config.KubernetesConfig) error { err := wait.PollImmediate(time.Millisecond*300, time.Minute*3, func() (bool, error) { rr, ierr := k.c.RunCmd(exec.Command("/bin/bash", "-c", "sudo pgrep kube-apiserver")) if ierr != nil { - glog.Warningf("pgrep apiserver: %v cmd: %s output: %s", ierr, rr.Command(), rr.Output()) + glog.Warningf("pgrep apiserver: %v cmd: %s", ierr, rr.Command()) return false, nil } return true, nil @@ -511,7 +511,7 @@ func (k *Bootstrapper) DeleteCluster(k8s config.KubernetesConfig) error { } if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", cmd)); err != nil { - return errors.Wrapf(err, "kubeadm reset: cmd: %q\noutput:%q\n", rr.Command(), rr.Output()) + return errors.Wrapf(err, "kubeadm reset: cmd: %q", rr.Command()) } return nil @@ -529,7 +529,7 @@ func (k *Bootstrapper) PullImages(k8s config.KubernetesConfig) error { rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("%s config images pull --config %s", invokeKubeadm(k8s.KubernetesVersion), yamlConfigPath))) if err != nil { - return errors.Wrapf(err, "running cmd: %q output: %q", rr.Command(), rr.Output()) + return errors.Wrapf(err, "running cmd: %q", rr.Command()) } return nil } @@ -642,8 +642,8 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error { } } - if rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "set -x;sudo systemctl daemon-reload && sudo systemctl start kubelet")); err != nil { - return errors.Wrapf(err, "starting kubelet, output: %s", rr.Output()) + if _, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "set -x;sudo systemctl daemon-reload && sudo systemctl start kubelet")); err != nil { + return errors.Wrap(err, "starting kubelet.") } return nil } diff --git a/pkg/minikube/cluster/mount.go b/pkg/minikube/cluster/mount.go index 6d97d4873fc1..d9b30ef8fb5b 100644 --- a/pkg/minikube/cluster/mount.go +++ b/pkg/minikube/cluster/mount.go @@ -61,17 +61,15 @@ func Mount(r mountRunner, source string, target string, c *MountConfig) error { } rr, err := r.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo mkdir -m %o -p %s && %s", c.Mode, target, mntCmd(source, target, c)))) if err != nil { - glog.Infof("Failed to create folder pre-mount: err=%v, output: %q", err, rr.Output()) return errors.Wrap(err, "create folder pre-mount") } rr, err = r.RunCmd(exec.Command("/bin/bash", "-c", mntCmd(source, target, c))) if err != nil { - glog.Infof("Failed to create folder before mount: err=%s, output: %q", err, rr.Output()) - return errors.Wrap(err, rr.Output()) + return errors.Wrap(err, "mount") } - glog.Infof("output: %q", rr.Output()) + glog.Infof("mount successful: %q", rr.Output()) return nil } @@ -141,8 +139,8 @@ func mntCmd(source string, target string, c *MountConfig) string { func Unmount(r mountRunner, target string) error { // grep because findmnt will also display the parent! c := exec.Command("/bin/bash", "-c", fmt.Sprintf("[ \"x$(findmnt -T %s | grep %s)\" != \"x\" ] && sudo umount -f %s || echo ", target, target, target)) - if rr, err := r.RunCmd(c); err != nil { - return errors.Wrap(err, rr.Output()) + if _, err := r.RunCmd(c); err != nil { + return errors.Wrap(err, "unmount") } glog.Infof("unmount for %s ran successfully", target) return nil diff --git a/pkg/minikube/command/exec_runner.go b/pkg/minikube/command/exec_runner.go index a4e401b082db..bcb53ab47b4b 100644 --- a/pkg/minikube/command/exec_runner.go +++ b/pkg/minikube/command/exec_runner.go @@ -18,6 +18,7 @@ package command import ( "bytes" + "fmt" "io" "os" "os/exec" @@ -68,6 +69,7 @@ func (*ExecRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { rr.ExitCode = exitError.ExitCode() } glog.Infof("(ExecRunner) Non-zero exit: %v: %v (%s)\n%s", rr.Command(), err, elapsed, rr.Output()) + err = errors.Wrapf(err, fmt.Sprintf("stderr: %s", rr.Stderr)) } return rr, err } diff --git a/pkg/minikube/cruntime/containerd.go b/pkg/minikube/cruntime/containerd.go index ac99f6f16247..6be7030fcacf 100644 --- a/pkg/minikube/cruntime/containerd.go +++ b/pkg/minikube/cruntime/containerd.go @@ -129,7 +129,7 @@ func (r *Containerd) Version() (string, error) { c := exec.Command("/bin/bash", "-c", "containerd --version") rr, err := r.Runner.RunCmd(c) if err != nil { - return "", errors.Wrapf(err, "containerd check version. output: %s", rr.Output()) + return "", errors.Wrapf(err, "containerd check version.") } // containerd github.com/containerd/containerd v1.2.0 c4446665cb9c30056f4998ed953e6d4ff22c7c39 words := strings.Split(rr.Stdout.String(), " ") @@ -162,8 +162,8 @@ func (r *Containerd) Active() bool { // Available returns an error if it is not possible to use this runtime on a host func (r *Containerd) Available() error { c := exec.Command("/bin/bash", "-c", "command -v containerd") - if rr, err := r.Runner.RunCmd(c); err != nil { - return errors.Wrapf(err, "check containerd availability. output: %s", rr.Output()) + if _, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrap(err, "check containerd availability.") } return nil } @@ -182,8 +182,8 @@ func generateContainerdConfig(cr CommandRunner, imageRepository string, k8sVersi return err } c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo mkdir -p %s && printf %%s \"%s\" | base64 -d | sudo tee %s", path.Dir(cPath), base64.StdEncoding.EncodeToString(b.Bytes()), cPath)) - if rr, err := cr.RunCmd(c); err != nil { - return errors.Wrapf(err, "generate containerd cfg. ouptut: %s", rr.Output()) + if _, err := cr.RunCmd(c); err != nil { + return errors.Wrap(err, "generate containerd cfg.") } return nil } @@ -206,8 +206,8 @@ func (r *Containerd) Enable(disOthers bool) error { } // Otherwise, containerd will fail API requests with 'Unimplemented' c := exec.Command("/bin/bash", "-c", "sudo systemctl restart containerd") - if rr, err := r.Runner.RunCmd(c); err != nil { - return errors.Wrapf(err, "enable containrd. output: %q", rr.Output()) + if _, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrap(err, "enable containrd.") } return nil } @@ -215,8 +215,8 @@ func (r *Containerd) Enable(disOthers bool) error { // Disable idempotently disables containerd on a host func (r *Containerd) Disable() error { c := exec.Command("/bin/bash", "-c", "sudo systemctl stop containerd") - if rr, err := r.Runner.RunCmd(c); err != nil { - return errors.Wrapf(err, "disable containrd. output: %q", rr.Output()) + if _, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrapf(err, "disable containrd.") } return nil } @@ -225,8 +225,8 @@ func (r *Containerd) Disable() error { func (r *Containerd) LoadImage(path string) error { glog.Infof("Loading image: %s", path) c := exec.Command("/bin/bash", "-c", fmt.Sprintf("ctr -n=k8s.io images import %s", path)) - if rr, err := r.Runner.RunCmd(c); err != nil { - return errors.Wrapf(err, "disable containrd. output: %q", rr.Output()) + if _, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrapf(err, "disable containrd.") } return nil } diff --git a/pkg/minikube/cruntime/cri.go b/pkg/minikube/cruntime/cri.go index c90e66bc3fcc..984556ec83fd 100644 --- a/pkg/minikube/cruntime/cri.go +++ b/pkg/minikube/cruntime/cri.go @@ -344,7 +344,7 @@ func listCRIContainers(cr CommandRunner, filter string) ([]string, error) { rr, err = cr.RunCmd(c) } if err != nil { - return nil, errors.Wrap(err, rr.Output()) + return nil, err } var ids []string for _, line := range strings.Split(rr.Stderr.String(), "\n") { @@ -362,9 +362,8 @@ func killCRIContainers(cr CommandRunner, ids []string) error { } glog.Infof("Killing containers: %s", ids) c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo crictl rm %s", strings.Join(ids, " "))) - rr, err := cr.RunCmd(c) - if err != nil { - return errors.Wrapf(err, "kill cri containers. output %s", rr.Output()) + if _, err := cr.RunCmd(c); err != nil { + return errors.Wrap(err, "kill cri containers.") } return nil } @@ -376,9 +375,8 @@ func stopCRIContainers(cr CommandRunner, ids []string) error { } glog.Infof("Stopping containers: %s", ids) c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo crictl rm %s", strings.Join(ids, " "))) - rr, err := cr.RunCmd(c) - if err != nil { - return errors.Wrapf(err, "stop cri containers. output %s", rr.Output()) + if _, err := cr.RunCmd(c); err != nil { + return errors.Wrap(err, "stop cri containers") } return nil @@ -400,8 +398,8 @@ image-endpoint: unix://{{.Socket}} return err } c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo mkdir -p %s && printf %%s \"%s\" | sudo tee %s", path.Dir(cPath), b.String(), cPath)) - if rr, err := cr.RunCmd(c); err != nil { - return errors.Wrapf(err, "populateCRIConfig %s", rr.Output()) + if _, err := cr.RunCmd(c); err != nil { + return errors.Wrap(err, "populateCRIConfig") } return nil } @@ -421,8 +419,8 @@ func generateCRIOConfig(cr CommandRunner, imageRepository string, k8sVersion str } c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo mkdir -p %s && printf %%s \"%s\" | base64 -d | sudo tee %s", path.Dir(cPath), base64.StdEncoding.EncodeToString(b.Bytes()), cPath)) - if rr, err := cr.RunCmd(c); err != nil { - return errors.Wrapf(err, "generateCRIOConfig. %s", rr.Output()) + if _, err := cr.RunCmd(c); err != nil { + return errors.Wrap(err, "generateCRIOConfig.") } return nil } diff --git a/pkg/minikube/cruntime/crio.go b/pkg/minikube/cruntime/crio.go index 37a5f8f7d039..70a6cb51adad 100644 --- a/pkg/minikube/cruntime/crio.go +++ b/pkg/minikube/cruntime/crio.go @@ -49,7 +49,7 @@ func (r *CRIO) Version() (string, error) { c := exec.Command("/bin/bash", "-c", "crio --version") rr, err := r.Runner.RunCmd(c) if err != nil { - return "", errors.Wrapf(err, "crio version. output: %s", rr.Output()) + return "", errors.Wrap(err, "crio version.") } // crio version 1.13.0 @@ -74,8 +74,8 @@ func (r *CRIO) DefaultCNI() bool { // Available returns an error if it is not possible to use this runtime on a host func (r *CRIO) Available() error { c := exec.Command("/bin/bash", "-c", "command -v crio") - if rr, err := r.Runner.RunCmd(c); err != nil { - return errors.Wrapf(err, "check crio available. output: %s", rr.Output()) + if _, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrapf(err, "check crio available.") } return nil @@ -105,16 +105,16 @@ func (r *CRIO) Enable(disOthers bool) error { return err } - if rr, err := r.Runner.RunCmd(exec.Command("/bin/bash", "-c", "sudo systemctl restart crio")); err != nil { - return errors.Wrapf(err, "enable crio. output: %s", rr.Output()) + if _, err := r.Runner.RunCmd(exec.Command("/bin/bash", "-c", "sudo systemctl restart crio")); err != nil { + return errors.Wrapf(err, "enable crio.") } return nil } // Disable idempotently disables CRIO on a host func (r *CRIO) Disable() error { - if rr, err := r.Runner.RunCmd(exec.Command("/bin/bash", "-c", "sudo systemctl stop crio")); err != nil { - return errors.Wrapf(err, "disable crio. output: %s", rr.Output()) + if _, err := r.Runner.RunCmd(exec.Command("/bin/bash", "-c", "sudo systemctl stop crio")); err != nil { + return errors.Wrapf(err, "disable crio.") } return nil } @@ -123,8 +123,8 @@ func (r *CRIO) Disable() error { func (r *CRIO) LoadImage(path string) error { glog.Infof("Loading image: %s", path) c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo podman load -i %s", path)) - if rr, err := r.Runner.RunCmd(c); err != nil { - return errors.Wrapf(err, "LoadImage crio. output: %s", rr.Output()) + if _, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrap(err, "LoadImage crio.") } return nil } diff --git a/pkg/minikube/cruntime/cruntime.go b/pkg/minikube/cruntime/cruntime.go index ddabd4a6fcf2..ac36f35b04f1 100644 --- a/pkg/minikube/cruntime/cruntime.go +++ b/pkg/minikube/cruntime/cruntime.go @@ -132,13 +132,13 @@ func disableOthers(me Manager, cr CommandRunner) error { // Context: https://github.com/kubernetes/kubeadm/issues/1062 func enableIPForwarding(cr CommandRunner) error { c := exec.Command("/bin/bash", "-c", "sudo modprobe br_netfilter") - if rr, err := cr.RunCmd(c); err != nil { - return errors.Wrapf(err, "br_netfilter. output:%s", rr.Output()) + if _, err := cr.RunCmd(c); err != nil { + return errors.Wrap(err, "br_netfilter.") } c = exec.Command("/bin/bash", "-c", "sudo sh -c \"echo 1 > /proc/sys/net/ipv4/ip_forward\"") - if rr, err := cr.RunCmd(c); err != nil { - return errors.Wrapf(err, "ip_forward. output:%s", rr.Output()) + if _, err := cr.RunCmd(c); err != nil { + return errors.Wrapf(err, "ip_forward.") } return nil } diff --git a/pkg/minikube/cruntime/docker.go b/pkg/minikube/cruntime/docker.go index d43156da35c0..c857c8406f7a 100644 --- a/pkg/minikube/cruntime/docker.go +++ b/pkg/minikube/cruntime/docker.go @@ -87,8 +87,8 @@ func (r *Docker) Enable(disOthers bool) error { } } c := exec.Command("/bin/bash", "-c", "sudo systemctl start docker") - if rr, err := r.Runner.RunCmd(c); err != nil { - return errors.Wrapf(err, "enable docker. output: %q", rr.Output()) + if _, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrap(err, "enable docker.") } return nil } @@ -96,8 +96,8 @@ func (r *Docker) Enable(disOthers bool) error { // Disable idempotently disables Docker on a host func (r *Docker) Disable() error { c := exec.Command("/bin/bash", "-c", "sudo systemctl stop docker docker.socket") - if rr, err := r.Runner.RunCmd(c); err != nil { - return errors.Wrapf(err, "disable docker. output: %q", rr.Output()) + if _, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrap(err, "disable docker") } return nil } @@ -106,8 +106,8 @@ func (r *Docker) Disable() error { func (r *Docker) LoadImage(path string) error { glog.Infof("Loading image: %s", path) c := exec.Command("/bin/bash", "-c", fmt.Sprintf("docker load -i %s", path)) - if rr, err := r.Runner.RunCmd(c); err != nil { - return errors.Wrapf(err, "loadimage docker. output: %q", rr.Output()) + if _, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrap(err, "loadimage docker.") } return nil @@ -126,7 +126,7 @@ func (r *Docker) ListContainers(filter string) ([]string, error) { c := exec.Command("/bin/bash", "-c", fmt.Sprintf(`docker ps -a --filter="name=%s" --format="{{.ID}}"`, filter)) rr, err := r.Runner.RunCmd(c) if err != nil { - return nil, errors.Wrapf(err, "docker ListContainers. output: %q", rr.Output()) + return nil, errors.Wrapf(err, "docker ListContainers. ") } var ids []string @@ -145,8 +145,8 @@ func (r *Docker) KillContainers(ids []string) error { } glog.Infof("Killing containers: %s", ids) c := exec.Command("/bin/bash", "-c", fmt.Sprintf("docker rm -f %s", strings.Join(ids, " "))) - if rr, err := r.Runner.RunCmd(c); err != nil { - return errors.Wrapf(err, "Killing containers docker. output: %q", rr.Output()) + if _, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrap(err, "Killing containers docker.") } return nil } @@ -158,8 +158,8 @@ func (r *Docker) StopContainers(ids []string) error { } glog.Infof("Stopping containers: %s", ids) c := exec.Command("/bin/bash", "-c", fmt.Sprintf("docker stop %s", strings.Join(ids, " "))) - if rr, err := r.Runner.RunCmd(c); err != nil { - return errors.Wrapf(err, "stopping containers docker. output: %q", rr.Output()) + if _, err := r.Runner.RunCmd(c); err != nil { + return errors.Wrap(err, "stopping containers docker.") } return nil } diff --git a/pkg/minikube/logs/logs.go b/pkg/minikube/logs/logs.go index 2400a595fe1e..f56230261900 100644 --- a/pkg/minikube/logs/logs.go +++ b/pkg/minikube/logs/logs.go @@ -73,9 +73,8 @@ func Follow(r cruntime.Manager, bs bootstrapper.Bootstrapper, cr logRunner) erro cmd := exec.Command("/bin/bash", "-c", strings.Join(cs, " ")) cmd.Stdout = os.Stdout cmd.Stderr = os.Stdout - rr, err := cr.RunCmd(cmd) - if err != nil { - return errors.Wrapf(err, "log follow with output %q", rr.Output()) + if _, err := cr.RunCmd(cmd); err != nil { + return errors.Wrapf(err, "log follow") } return nil } From 45e5bebdb4c036781730b531d5efed6ce46f3ae9 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Mon, 21 Oct 2019 17:44:03 -0700 Subject: [PATCH 44/59] fixing pointer and teeSSH --- Makefile | 2 +- pkg/minikube/command/command_runner.go | 4 +-- pkg/minikube/command/exec_runner.go | 12 +++---- pkg/minikube/command/fake_runner.go | 2 +- pkg/minikube/command/ssh_runner.go | 45 +++++++++++++------------- 5 files changed, 33 insertions(+), 32 deletions(-) diff --git a/Makefile b/Makefile index 0b159ac3ee3f..1daf445636a9 100755 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ # Bump these on release - and please check ISO_VERSION for correctness. VERSION_MAJOR ?= 1 VERSION_MINOR ?= 4 -VERSION_BUILD ?= 1 +VERSION_BUILD ?= 0 RAW_VERSION=$(VERSION_MAJOR).$(VERSION_MINOR).${VERSION_BUILD} VERSION ?= v$(RAW_VERSION) diff --git a/pkg/minikube/command/command_runner.go b/pkg/minikube/command/command_runner.go index c57d85f363ff..fdfa87d41797 100644 --- a/pkg/minikube/command/command_runner.go +++ b/pkg/minikube/command/command_runner.go @@ -28,8 +28,8 @@ import ( // RunResult holds the results of a Runner type RunResult struct { - Stdout *bytes.Buffer - Stderr *bytes.Buffer + Stdout bytes.Buffer + Stderr bytes.Buffer ExitCode int Args []string // the args that was passed to Runner } diff --git a/pkg/minikube/command/exec_runner.go b/pkg/minikube/command/exec_runner.go index bcb53ab47b4b..1f4adc39c24c 100644 --- a/pkg/minikube/command/exec_runner.go +++ b/pkg/minikube/command/exec_runner.go @@ -44,16 +44,16 @@ func (*ExecRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { var outb, errb bytes.Buffer if cmd.Stdout == nil { - cmd.Stdout, rr.Stdout = &outb, &outb + cmd.Stdout, rr.Stdout = &outb, outb } else { - io.MultiWriter(rr.Stdout, &outb) - rr.Stdout = &outb + cmd.Stdout = io.MultiWriter(cmd.Stdout, &outb) + rr.Stdout = outb } if cmd.Stderr == nil { - cmd.Stderr, rr.Stderr = &errb, &errb + cmd.Stderr, rr.Stderr = &errb, errb } else { - io.MultiWriter(rr.Stderr, &errb) - rr.Stdout = &errb + cmd.Stderr = io.MultiWriter(cmd.Stderr, &errb) + rr.Stderr = errb } start := time.Now() diff --git a/pkg/minikube/command/fake_runner.go b/pkg/minikube/command/fake_runner.go index 553aacb8bc40..fbdd40ca4007 100644 --- a/pkg/minikube/command/fake_runner.go +++ b/pkg/minikube/command/fake_runner.go @@ -55,7 +55,7 @@ func (f *FakeCommandRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { start := time.Now() out, ok := f.cmdMap.Load(strings.Join(rr.Args, " ")) - buf := new(bytes.Buffer) // creating a buffer reader to convert out to rr.stdout + var buf bytes.Buffer outStr := "" if out != nil { outStr = out.(string) diff --git a/pkg/minikube/command/ssh_runner.go b/pkg/minikube/command/ssh_runner.go index 6a5a8f7a06e0..ce8d621b63e6 100644 --- a/pkg/minikube/command/ssh_runner.go +++ b/pkg/minikube/command/ssh_runner.go @@ -59,17 +59,6 @@ func (s *SSHRunner) Remove(f assets.CopyableFile) error { return sess.Run(cmd) } -type singleWriter struct { - b bytes.Buffer - mu sync.Mutex -} - -func (w *singleWriter) Write(p []byte) (int, error) { - w.mu.Lock() - defer w.mu.Unlock() - return w.b.Write(p) -} - // teeSSH runs an SSH command, streaming stdout, stderr to logs func teeSSH(s *ssh.Session, cmd string, outB io.Writer, errB io.Writer) error { outPipe, err := s.StdoutPipe() @@ -106,22 +95,28 @@ func (s *SSHRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { rr := &RunResult{Args: cmd.Args} glog.Infof("(SSHRunner) Run: %v", rr.Command()) - var outb, errb singleWriter - rr.Stdout = &outb.b - rr.Stderr = &errb.b + var outb, errb io.Writer + start := time.Now() + glog.Infof("cmd: %+v", cmd) + glog.Infof("stdout: %v", cmd.Stdout) + glog.Infof("stderr: %v", cmd.Stderr) + if cmd.Stdout == nil { - cmd.Stdout, rr.Stdout = &outb, &outb.b + var so bytes.Buffer + glog.Infof("makin a stdout buffer: %T %v %p", so, so, &so) + outb = io.MultiWriter(&so, &rr.Stdout) } else { - io.MultiWriter(rr.Stdout, &outb) - rr.Stdout = &outb.b + outb = io.MultiWriter(cmd.Stdout, &rr.Stdout) } + if cmd.Stderr == nil { - cmd.Stderr, rr.Stderr = &errb, &errb.b + var se bytes.Buffer + glog.Infof("makin a stderr buffer: %T %v %p", se, se, &se) + errb = io.MultiWriter(&se, &rr.Stderr) } else { - io.MultiWriter(rr.Stderr, &errb) - rr.Stdout = &errb.b + errb = io.MultiWriter(cmd.Stderr, &rr.Stderr) } sess, err := s.c.NewSession() @@ -138,7 +133,8 @@ func (s *SSHRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { }() elapsed := time.Since(start) - err = teeSSH(sess, shellquote.Join(cmd.Args...), &outb, &errb) + glog.Infof("%s out=%T %v err=%T %v", cmd, outb, outb, errb, errb) + err = teeSSH(sess, shellquote.Join(cmd.Args...), outb, errb) if err == nil { // Reduce log spam if elapsed > (1 * time.Second) { @@ -203,16 +199,19 @@ func (s *SSHRunner) Copy(f assets.CopyableFile) error { // teePrefix copies bytes from a reader to writer, logging each new line. func teePrefix(prefix string, r io.Reader, w io.Writer, logger func(format string, args ...interface{})) error { + glog.Infof("prefix=%s, writer=%T %v", prefix, w, w) scanner := bufio.NewScanner(r) scanner.Split(bufio.ScanBytes) var line bytes.Buffer for scanner.Scan() { + glog.Infof("%s scan start ------", prefix) b := scanner.Bytes() + glog.Infof("writing %d bytes to %T %v: %s", len(b), w, w, b) if _, err := w.Write(b); err != nil { return err } - + glog.Infof("written!") if bytes.IndexAny(b, "\r\n") == 0 { if line.Len() > 0 { logger("%s%s", prefix, line.String()) @@ -220,7 +219,9 @@ func teePrefix(prefix string, r io.Reader, w io.Writer, logger func(format strin } continue } + glog.Infof("copying to line...") line.Write(b) + glog.Infof("%s scan end ------", prefix) } // Catch trailing output in case stream does not end with a newline if line.Len() > 0 { From 900123bcf2eec4c12a9a94da2eea0a4097e31491 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 24 Oct 2019 13:17:52 -0700 Subject: [PATCH 45/59] Fixing pointer and unit test --- pkg/minikube/cruntime/cruntime_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/minikube/cruntime/cruntime_test.go b/pkg/minikube/cruntime/cruntime_test.go index 678a544226f5..a1c081817421 100644 --- a/pkg/minikube/cruntime/cruntime_test.go +++ b/pkg/minikube/cruntime/cruntime_test.go @@ -137,7 +137,7 @@ func (f *FakeRunner) RunCmd(cmd *exec.Cmd) (*command.RunResult, error) { if err != nil { return rr, err } - buf := new(bytes.Buffer) + var buf bytes.Buffer _, err = buf.WriteString(s) if err != nil { return rr, errors.Wrap(err, "Writing outStr to FakeRunner's buffer") @@ -151,7 +151,7 @@ func (f *FakeRunner) RunCmd(cmd *exec.Cmd) (*command.RunResult, error) { if err != nil { return rr, err } - buf := new(bytes.Buffer) + var buf bytes.Buffer _, err = buf.WriteString(s) if err != nil { return rr, errors.Wrap(err, "Writing FakeRunner's buffer") @@ -166,7 +166,7 @@ func (f *FakeRunner) RunCmd(cmd *exec.Cmd) (*command.RunResult, error) { if err != nil { return rr, err } - buf := new(bytes.Buffer) + var buf bytes.Buffer _, err = buf.WriteString(s) if err != nil { return rr, errors.Wrap(err, "Writing to FakeRunner's buffer") @@ -180,7 +180,7 @@ func (f *FakeRunner) RunCmd(cmd *exec.Cmd) (*command.RunResult, error) { if err != nil { return rr, err } - buf := new(bytes.Buffer) + var buf bytes.Buffer _, err = buf.WriteString(s) if err != nil { return rr, errors.Wrap(err, "Writing to FakeRunner's buffer") @@ -195,7 +195,7 @@ func (f *FakeRunner) RunCmd(cmd *exec.Cmd) (*command.RunResult, error) { return rr, err } - buf := new(bytes.Buffer) + var buf bytes.Buffer _, err = buf.WriteString(s) if err != nil { return rr, errors.Wrap(err, "Writing to FakeRunner's buffer") From 415f0ca659f39934acc8e90330691492c8c094db Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 24 Oct 2019 13:28:18 -0700 Subject: [PATCH 46/59] makefile conflict --- Makefile | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 1daf445636a9..07256051968c 100755 --- a/Makefile +++ b/Makefile @@ -14,13 +14,13 @@ # Bump these on release - and please check ISO_VERSION for correctness. VERSION_MAJOR ?= 1 -VERSION_MINOR ?= 4 -VERSION_BUILD ?= 0 +VERSION_MINOR ?= 5 +VERSION_BUILD ?= 0-beta.0 RAW_VERSION=$(VERSION_MAJOR).$(VERSION_MINOR).${VERSION_BUILD} VERSION ?= v$(RAW_VERSION) # Default to .0 for higher cache hit rates, as build increments typically don't require new ISO versions -ISO_VERSION ?= v$(VERSION_MAJOR).$(VERSION_MINOR).0 +ISO_VERSION ?= v$(VERSION_MAJOR).$(VERSION_MINOR).0-beta.0 # Dashes are valid in semver, but not Linux packaging. Use ~ to delimit alpha/beta DEB_VERSION ?= $(subst -,~,$(RAW_VERSION)) RPM_VERSION ?= $(DEB_VERSION) @@ -51,7 +51,7 @@ MINIKUBE_RELEASES_URL=https://github.com/kubernetes/minikube/releases/download KERNEL_VERSION ?= 4.19.76 # latest from https://github.com/golangci/golangci-lint/releases -GOLINT_VERSION ?= v1.20.0 +GOLINT_VERSION ?= v1.21.0 # Limit number of default jobs, to avoid the CI builds running out of memory GOLINT_JOBS ?= 4 # see https://github.com/golangci/golangci-lint#memory-usage-of-golangci-lint @@ -59,7 +59,7 @@ GOLINT_GOGC ?= 100 # options for lint (golangci-lint) GOLINT_OPTIONS = --timeout 4m \ --build-tags "${MINIKUBE_INTEGRATION_BUILD_TAGS}" \ - --enable goimports,gocritic,golint,gocyclo,misspell,nakedret,stylecheck,unconvert,unparam \ + --enable goimports,gocritic,golint,gocyclo,misspell,nakedret,stylecheck,unconvert,unparam,dogsled \ --exclude 'variable on range scope.*in function literal|ifElseChain' @@ -136,16 +136,16 @@ else endif -out/minikube-linux-x86_64: out/minikube-linux-amd64 +out/minikube$(IS_EXE): out/minikube-$(GOOS)-$(GOARCH)$(IS_EXE) cp $< $@ -out/minikube-linux-aarch64: out/minikube-linux-arm64 +out/minikube-windows-amd64.exe: out/minikube-windows-amd64 cp $< $@ -out/minikube$(IS_EXE): out/minikube-$(GOOS)-$(GOARCH)$(IS_EXE) +out/minikube-linux-x86_64: out/minikube-linux-amd64 cp $< $@ -out/minikube-windows-amd64.exe: out/minikube-windows-amd64 +out/minikube-linux-aarch64: out/minikube-linux-arm64 cp $< $@ .PHONY: minikube-linux-amd64 minikube-linux-arm64 minikube-darwin-amd64 minikube-windows-amd64.exe @@ -570,4 +570,4 @@ site: site/themes/docsy/assets/vendor/bootstrap/package.js out/hugo/hugo .PHONY: out/mkcmp out/mkcmp: - GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $@ cmd/performance/main.go + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $@ cmd/performance/main.go \ No newline at end of file From 187dfe29f80f12acfe971b5d091d6280da7431b2 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 24 Oct 2019 14:13:51 -0700 Subject: [PATCH 47/59] getting rid of some of bin bash -c --- cmd/minikube/cmd/start.go | 4 ++-- pkg/drivers/none/none.go | 8 ++++---- pkg/minikube/bootstrapper/certs.go | 6 ++---- pkg/minikube/bootstrapper/kubeadm/kubeadm.go | 18 +++++++++--------- pkg/minikube/cruntime/containerd.go | 10 +++++----- pkg/minikube/cruntime/crio.go | 12 ++++++------ pkg/minikube/cruntime/cruntime.go | 2 +- pkg/minikube/cruntime/docker.go | 10 +++++----- test/integration/fn_tunnel_cmd.go | 2 +- 9 files changed, 35 insertions(+), 37 deletions(-) diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index 6fe437d61eb9..365d4b04e8be 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -1006,8 +1006,8 @@ Suggested workarounds: } defer conn.Close() } - - if _, err := r.RunCmd(exec.Command("/bin/bash", "-c", "nslookup kubernetes.io")); err != nil { + w + if _, err := r.RunCmd(exec.Command("nslookup", "kubernetes.io")); err != nil { out.WarningT("VM is unable to resolve DNS hosts: {[.error}}", out.V{"error": err}) } diff --git a/pkg/drivers/none/none.go b/pkg/drivers/none/none.go index 3013e0703f2b..236fa970346d 100644 --- a/pkg/drivers/none/none.go +++ b/pkg/drivers/none/none.go @@ -225,12 +225,12 @@ func (d *Driver) RunSSHCommandFromDriver() error { func stopKubelet(cr command.Runner) error { glog.Infof("stopping kubelet.service ...") stop := func() error { - cmdStop := exec.Command("/bin/bash", "sudo systemctl stop kubelet.service") + cmdStop := exec.Command("sudo", "systemctl", "stop", "kubelet.service") if rr, err := cr.RunCmd(cmdStop); err != nil { glog.Errorf("temporary error for %q : %v", rr.Command(), err) } var out bytes.Buffer - cmdCheck := exec.Command("/bin/bash", "-c", "sudo systemctl show -p SubState kubelet") + cmdCheck := exec.Command("sudo", "systemctl", "show", "-p", "SubState", "kubelet") cmdCheck.Stdout = &out cmdCheck.Stderr = &out if rr, err := cr.RunCmd(cmdCheck); err != nil { @@ -252,7 +252,7 @@ func stopKubelet(cr command.Runner) error { // restartKubelet restarts the kubelet func restartKubelet(cr command.Runner) error { glog.Infof("restarting kubelet.service ...") - c := exec.Command("/bin/bash", "-c", "sudo systemctl restart kubelet.service") + c := exec.Command("sudo", "systemctl", "restart", "kubelet.service") if _, err := cr.RunCmd(c); err != nil { return errors.Wrapf(err, "restartKubelet") } @@ -262,7 +262,7 @@ func restartKubelet(cr command.Runner) error { // checkKubelet returns an error if the kubelet is not running. func checkKubelet(cr command.Runner) error { glog.Infof("checking for running kubelet ...") - c := exec.Command("/bin/bash", "-c", "systemctl is-active --quiet service kubelet") + c := exec.Command("systemctl", "is-active", "--quiet", "service", "kubelet") if _, err := cr.RunCmd(c); err != nil { return errors.Wrap(err, "checkKubelet") } diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index 484a51e02806..c651f0e85c29 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -332,8 +332,7 @@ func getSubjectHash(cr command.Runner, filePath string) (string, error) { // OpenSSL binary required in minikube ISO func configureCACerts(cr command.Runner, caCerts map[string]string) error { hasSSLBinary := true - c := exec.Command("/bin/bash", "-c", "openssl version") - _, err := cr.RunCmd(c) + _, err := cr.RunCmd(exec.Command("openssl version")) if err != nil { hasSSLBinary = false } @@ -348,8 +347,7 @@ func configureCACerts(cr command.Runner, caCerts map[string]string) error { _, err := cr.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo test -f %s", certStorePath))) if err != nil { - c = exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ln -s '%s' '%s'", caCertFile, certStorePath)) - + c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ln -s '%s' '%s'", caCertFile, certStorePath)) if _, err := cr.RunCmd(c); err != nil { return errors.Wrapf(err, "error making symbol link for certificate %s", caCertFile) } diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index ea192f26c797..1b54a023f622 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -137,7 +137,7 @@ func NewKubeadmBootstrapper(api libmachine.API) (*Bootstrapper, error) { // GetKubeletStatus returns the kubelet status func (k *Bootstrapper) GetKubeletStatus() (string, error) { - rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "sudo systemctl is-active kubelet")) + rr, err := k.c.RunCmd(exec.Command("sudo", "systemctl", "is-active", "kubelet")) if err != nil { return "", errors.Wrapf(err, "getting kublet status. command: %q", rr.Command()) } @@ -222,15 +222,15 @@ func etcdDataDir() string { // createCompatSymlinks creates compatibility symlinks to transition running services to new directory structures func (k *Bootstrapper) createCompatSymlinks() error { legacyEtcd := "/data/minikube" - rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo test -d %s", legacyEtcd))) - if err != nil { - glog.Infof("%s check failed, skipping compat symlinks: %v", legacyEtcd, err) + + if _, err := k.c.RunCmd(exec.Command("sudo", "test", "-d", legacyEtcd)); err != nil { + glog.Infof("%s skipping compat symlinks: %v", legacyEtcd, err) return nil } glog.Infof("Found %s, creating compatibility symlinks ...", legacyEtcd) - c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ln -s %s %s", legacyEtcd, etcdDataDir())) - if rr, err = k.c.RunCmd(c); err != nil { + c := exec.Command("sudo", "ln", "-s", legacyEtcd, etcdDataDir()) + if rr, err := k.c.RunCmd(c); err != nil { return errors.Wrapf(err, "create symlink failed: %s", rr.Command()) } return nil @@ -300,7 +300,7 @@ func (k *Bootstrapper) StartCluster(k8s config.KubernetesConfig) error { // adjustResourceLimits makes fine adjustments to pod resources that aren't possible via kubeadm config. func (k *Bootstrapper) adjustResourceLimits() error { - rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "cat /proc/$(pgrep kube-apiserver)/oom_adj")) + rr, err := k.c.RunCmd(exec.Command("cat", "/proc/$(pgrep kube-apiserver)/oom_adj")) if err != nil { return errors.Wrap(err, "oom_adj check. command: %q output: %q") } @@ -313,7 +313,7 @@ func (k *Bootstrapper) adjustResourceLimits() error { // Prevent the apiserver from OOM'ing before other pods, as it is our gateway into the cluster. // It'd be preferable to do this via Kubernetes, but kubeadm doesn't have a way to set pod QoS. - if rr, err = k.c.RunCmd(exec.Command("/bin/bash", "-c", "echo -10 | sudo tee /proc/$(pgrep kube-apiserver)/oom_adj")); err != nil { + if _, err = k.c.RunCmd(exec.Command("/bin/bash", "-c", "echo -10 | sudo tee /proc/$(pgrep kube-apiserver)/oom_adj")); err != nil { return errors.Wrap(err, fmt.Sprintf("oom_adj adjust")) } @@ -466,7 +466,7 @@ func (k *Bootstrapper) waitForAPIServer(k8s config.KubernetesConfig) error { // To give a better error message, first check for process existence via ssh // Needs minutes in case the image isn't cached (such as with v1.10.x) err := wait.PollImmediate(time.Millisecond*300, time.Minute*3, func() (bool, error) { - rr, ierr := k.c.RunCmd(exec.Command("/bin/bash", "-c", "sudo pgrep kube-apiserver")) + rr, ierr := k.c.RunCmd(exec.Command("sudo", "pgrep", "kube-apiserver")) if ierr != nil { glog.Warningf("pgrep apiserver: %v cmd: %s", ierr, rr.Command()) return false, nil diff --git a/pkg/minikube/cruntime/containerd.go b/pkg/minikube/cruntime/containerd.go index 6be7030fcacf..fab3d0a8df78 100644 --- a/pkg/minikube/cruntime/containerd.go +++ b/pkg/minikube/cruntime/containerd.go @@ -126,7 +126,7 @@ func (r *Containerd) Style() out.StyleEnum { // Version retrieves the current version of this runtime func (r *Containerd) Version() (string, error) { - c := exec.Command("/bin/bash", "-c", "containerd --version") + c := exec.Command("containerd", "--version") rr, err := r.Runner.RunCmd(c) if err != nil { return "", errors.Wrapf(err, "containerd check version.") @@ -154,14 +154,14 @@ func (r *Containerd) DefaultCNI() bool { // Active returns if containerd is active on the host func (r *Containerd) Active() bool { - c := exec.Command("/bin/bash", "-c", "systemctl is-active --quiet service containerd") + c := exec.Command("systemctl", "is-active", "--quiet", "service", "containerd") _, err := r.Runner.RunCmd(c) return err == nil } // Available returns an error if it is not possible to use this runtime on a host func (r *Containerd) Available() error { - c := exec.Command("/bin/bash", "-c", "command -v containerd") + c := exec.Command("command", "-v", "containerd") if _, err := r.Runner.RunCmd(c); err != nil { return errors.Wrap(err, "check containerd availability.") } @@ -205,7 +205,7 @@ func (r *Containerd) Enable(disOthers bool) error { return err } // Otherwise, containerd will fail API requests with 'Unimplemented' - c := exec.Command("/bin/bash", "-c", "sudo systemctl restart containerd") + c := exec.Command("sudo", "systemctl", "restart", "containerd") if _, err := r.Runner.RunCmd(c); err != nil { return errors.Wrap(err, "enable containrd.") } @@ -214,7 +214,7 @@ func (r *Containerd) Enable(disOthers bool) error { // Disable idempotently disables containerd on a host func (r *Containerd) Disable() error { - c := exec.Command("/bin/bash", "-c", "sudo systemctl stop containerd") + c := exec.Command("sudo", "systemctl", "stop", "containerd") if _, err := r.Runner.RunCmd(c); err != nil { return errors.Wrapf(err, "disable containrd.") } diff --git a/pkg/minikube/cruntime/crio.go b/pkg/minikube/cruntime/crio.go index 70a6cb51adad..0b7b26b3599d 100644 --- a/pkg/minikube/cruntime/crio.go +++ b/pkg/minikube/cruntime/crio.go @@ -46,7 +46,7 @@ func (r *CRIO) Style() out.StyleEnum { // Version retrieves the current version of this runtime func (r *CRIO) Version() (string, error) { - c := exec.Command("/bin/bash", "-c", "crio --version") + c := exec.Command("crio", "--version") rr, err := r.Runner.RunCmd(c) if err != nil { return "", errors.Wrap(err, "crio version.") @@ -73,7 +73,7 @@ func (r *CRIO) DefaultCNI() bool { // Available returns an error if it is not possible to use this runtime on a host func (r *CRIO) Available() error { - c := exec.Command("/bin/bash", "-c", "command -v crio") + c := exec.Command("command", "-v", "crio") if _, err := r.Runner.RunCmd(c); err != nil { return errors.Wrapf(err, "check crio available.") } @@ -83,7 +83,7 @@ func (r *CRIO) Available() error { // Active returns if CRIO is active on the host func (r *CRIO) Active() bool { - c := exec.Command("/bin/bash", "-c", "systemctl is-active --quiet service crio") + c := exec.Command("systemctl", "is-active", "--quiet", "service", "crio") _, err := r.Runner.RunCmd(c) return err == nil } @@ -105,7 +105,7 @@ func (r *CRIO) Enable(disOthers bool) error { return err } - if _, err := r.Runner.RunCmd(exec.Command("/bin/bash", "-c", "sudo systemctl restart crio")); err != nil { + if _, err := r.Runner.RunCmd(exec.Command("sudo", "systemctl", "restart", "crio")); err != nil { return errors.Wrapf(err, "enable crio.") } return nil @@ -113,7 +113,7 @@ func (r *CRIO) Enable(disOthers bool) error { // Disable idempotently disables CRIO on a host func (r *CRIO) Disable() error { - if _, err := r.Runner.RunCmd(exec.Command("/bin/bash", "-c", "sudo systemctl stop crio")); err != nil { + if _, err := r.Runner.RunCmd(exec.Command("sudo", "systemctl", "stop", "crio")); err != nil { return errors.Wrapf(err, "disable crio.") } return nil @@ -122,7 +122,7 @@ func (r *CRIO) Disable() error { // LoadImage loads an image into this runtime func (r *CRIO) LoadImage(path string) error { glog.Infof("Loading image: %s", path) - c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo podman load -i %s", path)) + c := exec.Command("sudo", "podman", "load", "-i", path) if _, err := r.Runner.RunCmd(c); err != nil { return errors.Wrap(err, "LoadImage crio.") } diff --git a/pkg/minikube/cruntime/cruntime.go b/pkg/minikube/cruntime/cruntime.go index ac36f35b04f1..09db37d162a0 100644 --- a/pkg/minikube/cruntime/cruntime.go +++ b/pkg/minikube/cruntime/cruntime.go @@ -131,7 +131,7 @@ func disableOthers(me Manager, cr CommandRunner) error { // enableIPForwarding configures IP forwarding, which is handled normally by Docker // Context: https://github.com/kubernetes/kubeadm/issues/1062 func enableIPForwarding(cr CommandRunner) error { - c := exec.Command("/bin/bash", "-c", "sudo modprobe br_netfilter") + c := exec.Command("sudo", "modprobe", "br_netfilter") if _, err := cr.RunCmd(c); err != nil { return errors.Wrap(err, "br_netfilter.") } diff --git a/pkg/minikube/cruntime/docker.go b/pkg/minikube/cruntime/docker.go index c857c8406f7a..abe00a6f6fe7 100644 --- a/pkg/minikube/cruntime/docker.go +++ b/pkg/minikube/cruntime/docker.go @@ -48,7 +48,7 @@ func (r *Docker) Style() out.StyleEnum { // Version retrieves the current version of this runtime func (r *Docker) Version() (string, error) { // Note: the server daemon has to be running, for this call to return successfully - c := exec.Command("/bin/bash", "-c", "docker version --format '{{.Server.Version}}'") + c := exec.Command("docker", "version", "--format", "'{{.Server.Version}}'") rr, err := r.Runner.RunCmd(c) if err != nil { return "", err @@ -74,7 +74,7 @@ func (r *Docker) Available() error { // Active returns if docker is active on the host func (r *Docker) Active() bool { - c := exec.Command("/bin/bash", "-c", "systemctl is-active --quiet service docker") + c := exec.Command("systemctl", "is-active", "--quiet", "service", "docker") _, err := r.Runner.RunCmd(c) return err == nil } @@ -86,7 +86,7 @@ func (r *Docker) Enable(disOthers bool) error { glog.Warningf("disableOthers: %v", err) } } - c := exec.Command("/bin/bash", "-c", "sudo systemctl start docker") + c := exec.Command("sudo", "systemctl", "start", "docker") if _, err := r.Runner.RunCmd(c); err != nil { return errors.Wrap(err, "enable docker.") } @@ -95,7 +95,7 @@ func (r *Docker) Enable(disOthers bool) error { // Disable idempotently disables Docker on a host func (r *Docker) Disable() error { - c := exec.Command("/bin/bash", "-c", "sudo systemctl stop docker docker.socket") + c := exec.Command("sudo", "systemctl", "stop", "docker", "docker.socket") if _, err := r.Runner.RunCmd(c); err != nil { return errors.Wrap(err, "disable docker") } @@ -105,7 +105,7 @@ func (r *Docker) Disable() error { // LoadImage loads an image into this runtime func (r *Docker) LoadImage(path string) error { glog.Infof("Loading image: %s", path) - c := exec.Command("/bin/bash", "-c", fmt.Sprintf("docker load -i %s", path)) + c := exec.Command("docker", "load", "-i", path) if _, err := r.Runner.RunCmd(c); err != nil { return errors.Wrap(err, "loadimage docker.") } diff --git a/test/integration/fn_tunnel_cmd.go b/test/integration/fn_tunnel_cmd.go index 56d97a922368..b9e43c8cc295 100644 --- a/test/integration/fn_tunnel_cmd.go +++ b/test/integration/fn_tunnel_cmd.go @@ -43,7 +43,7 @@ func validateTunnelCmd(ctx context.Context, t *testing.T, profile string) { if runtime.GOOS != "windows" { // Otherwise minikube fails waiting for a password. - if err := exec.Command("/bin/bash", "-c", "sudo -n route").Run(); err != nil { + if err := exec.Command("sudo", "-n", "route").Run(); err != nil { t.Skipf("password required to execute 'route', skipping testTunnel: %v", err) } } From ddabc9ef4746fad0cf17c2e2a02a901fd8b353ff Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 24 Oct 2019 14:20:07 -0700 Subject: [PATCH 48/59] remove extra error word --- cmd/minikube/cmd/start.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index 365d4b04e8be..4a04779a24c8 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -1006,7 +1006,7 @@ Suggested workarounds: } defer conn.Close() } - w + if _, err := r.RunCmd(exec.Command("nslookup", "kubernetes.io")); err != nil { out.WarningT("VM is unable to resolve DNS hosts: {[.error}}", out.V{"error": err}) } From 0d8c894e6ebc9c81fe54055bbd4281ed779ab996 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 24 Oct 2019 16:09:41 -0700 Subject: [PATCH 49/59] fix unit test and remove more bin bash c --- pkg/minikube/bootstrapper/certs.go | 2 +- pkg/minikube/cluster/mount.go | 8 ++++---- pkg/minikube/command/exec_runner.go | 2 +- pkg/minikube/cruntime/containerd.go | 2 +- pkg/minikube/cruntime/cri.go | 12 +++++++----- pkg/minikube/cruntime/cruntime_test.go | 16 ++++++---------- pkg/minikube/cruntime/docker.go | 10 +++++----- 7 files changed, 25 insertions(+), 27 deletions(-) diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index c651f0e85c29..c6f4d10a8558 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -332,7 +332,7 @@ func getSubjectHash(cr command.Runner, filePath string) (string, error) { // OpenSSL binary required in minikube ISO func configureCACerts(cr command.Runner, caCerts map[string]string) error { hasSSLBinary := true - _, err := cr.RunCmd(exec.Command("openssl version")) + _, err := cr.RunCmd(exec.Command("openssl", "version")) if err != nil { hasSSLBinary = false } diff --git a/pkg/minikube/cluster/mount.go b/pkg/minikube/cluster/mount.go index d9b30ef8fb5b..eeba0a745254 100644 --- a/pkg/minikube/cluster/mount.go +++ b/pkg/minikube/cluster/mount.go @@ -59,14 +59,14 @@ func Mount(r mountRunner, source string, target string, c *MountConfig) error { if err := Unmount(r, target); err != nil { return errors.Wrap(err, "umount") } - rr, err := r.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo mkdir -m %o -p %s && %s", c.Mode, target, mntCmd(source, target, c)))) - if err != nil { + + if _, err := r.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo mkdir -m %o -p %s && %s", c.Mode, target, mntCmd(source, target, c)))); err != nil { return errors.Wrap(err, "create folder pre-mount") } - rr, err = r.RunCmd(exec.Command("/bin/bash", "-c", mntCmd(source, target, c))) + rr, err := r.RunCmd(exec.Command("/bin/bash", "-c", mntCmd(source, target, c))) if err != nil { - return errors.Wrap(err, "mount") + return errors.Wrapf(err, "mount with cmd %s ", rr.Command()) } glog.Infof("mount successful: %q", rr.Output()) diff --git a/pkg/minikube/command/exec_runner.go b/pkg/minikube/command/exec_runner.go index 1f4adc39c24c..84e5fcd0a04d 100644 --- a/pkg/minikube/command/exec_runner.go +++ b/pkg/minikube/command/exec_runner.go @@ -69,7 +69,7 @@ func (*ExecRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { rr.ExitCode = exitError.ExitCode() } glog.Infof("(ExecRunner) Non-zero exit: %v: %v (%s)\n%s", rr.Command(), err, elapsed, rr.Output()) - err = errors.Wrapf(err, fmt.Sprintf("stderr: %s", rr.Stderr)) + err = errors.Wrapf(err, fmt.Sprintf("stderr: %s", rr.Stderr.String())) } return rr, err } diff --git a/pkg/minikube/cruntime/containerd.go b/pkg/minikube/cruntime/containerd.go index fab3d0a8df78..85b214dd5d26 100644 --- a/pkg/minikube/cruntime/containerd.go +++ b/pkg/minikube/cruntime/containerd.go @@ -224,7 +224,7 @@ func (r *Containerd) Disable() error { // LoadImage loads an image into this runtime func (r *Containerd) LoadImage(path string) error { glog.Infof("Loading image: %s", path) - c := exec.Command("/bin/bash", "-c", fmt.Sprintf("ctr -n=k8s.io images import %s", path)) + c := exec.Command("ctr", "-n=k8s.io", "images", "import", path) if _, err := r.Runner.RunCmd(c); err != nil { return errors.Wrapf(err, "disable containrd.") } diff --git a/pkg/minikube/cruntime/cri.go b/pkg/minikube/cruntime/cri.go index 984556ec83fd..8bf5c53ea24e 100644 --- a/pkg/minikube/cruntime/cri.go +++ b/pkg/minikube/cruntime/cri.go @@ -337,11 +337,10 @@ func listCRIContainers(cr CommandRunner, filter string) ([]string, error) { var rr *command.RunResult state := "Running" if filter != "" { - c := exec.Command("/bin/bash/", "-c", fmt.Sprintf(`sudo crictl ps -a --name=%s --state=%s --quiet`, filter, state)) + c := exec.Command("sudo", "crictl", "ps", "-a", fmt.Sprintf("--name=%s", filter), fmt.Sprintf("--state=%s", state), "--quiet") rr, err = cr.RunCmd(c) } else { - c := exec.Command("/bin/bash/", "-c", fmt.Sprintf(`sudo crictl ps -a --state=%s --quiet`, state)) - rr, err = cr.RunCmd(c) + rr, err = cr.RunCmd(exec.Command("sudo", "crictl", "ps", "-a", fmt.Sprintf("--state=%s", state), "--quiet")) } if err != nil { return nil, err @@ -361,7 +360,9 @@ func killCRIContainers(cr CommandRunner, ids []string) error { return nil } glog.Infof("Killing containers: %s", ids) - c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo crictl rm %s", strings.Join(ids, " "))) + + args := append([]string{"crictl", "rm"}, ids...) + c := exec.Command("sudo", args...) if _, err := cr.RunCmd(c); err != nil { return errors.Wrap(err, "kill cri containers.") } @@ -374,7 +375,8 @@ func stopCRIContainers(cr CommandRunner, ids []string) error { return nil } glog.Infof("Stopping containers: %s", ids) - c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo crictl rm %s", strings.Join(ids, " "))) + args := append([]string{"crictl", "rm"}, ids...) + c := exec.Command("sudo", args...) if _, err := cr.RunCmd(c); err != nil { return errors.Wrap(err, "stop cri containers") } diff --git a/pkg/minikube/cruntime/cruntime_test.go b/pkg/minikube/cruntime/cruntime_test.go index a1c081817421..bb735849c041 100644 --- a/pkg/minikube/cruntime/cruntime_test.go +++ b/pkg/minikube/cruntime/cruntime_test.go @@ -23,10 +23,8 @@ import ( "strings" "testing" - "github.com/golang/glog" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - "github.com/kballard/go-shellquote" "github.com/pkg/errors" "k8s.io/minikube/pkg/minikube/command" ) @@ -118,10 +116,7 @@ func NewFakeRunner(t *testing.T) *FakeRunner { // Run a fake command! func (f *FakeRunner) RunCmd(cmd *exec.Cmd) (*command.RunResult, error) { - xargs, err := shellquote.Split(cmd.Args[2]) - if err != nil { - glog.Infof("FakeRunner shellquote.Split error %v", err) - } + xargs := cmd.Args f.cmds = append(f.cmds, xargs...) root := false bin, args := xargs[0], xargs[1:] @@ -215,8 +210,8 @@ func (f *FakeRunner) docker(args []string, _ bool) (string, error) { case "ps": // ps -a --filter="name=apiserver" --format="{{.ID}}" if args[1] == "-a" && strings.HasPrefix(args[2], "--filter") { - filter := strings.Split(args[2], `"`)[0] - fname := strings.Split(filter, "=")[2] + filter := strings.Split(args[2], `"`)[1] + fname := strings.Split(filter, "=")[1] ids := []string{} f.t.Logf("fake docker: Looking for containers matching %q", fname) for id, cname := range f.containers { @@ -228,7 +223,8 @@ func (f *FakeRunner) docker(args []string, _ bool) (string, error) { return strings.Join(ids, "\n"), nil } case "stop": - for _, id := range args[1:] { + ids := strings.Split(args[1], " ") + for _, id := range ids { f.t.Logf("fake docker: Stopping id %q", id) if f.containers[id] == "" { return "", fmt.Errorf("no such container") @@ -247,7 +243,7 @@ func (f *FakeRunner) docker(args []string, _ bool) (string, error) { } case "version": - if args[1] == "--format" && args[2] == "{{.Server.Version}}" { + if args[1] == "--format" && args[2] == "'{{.Server.Version}}'" { return "18.06.2-ce", nil } } diff --git a/pkg/minikube/cruntime/docker.go b/pkg/minikube/cruntime/docker.go index abe00a6f6fe7..2a80d160d418 100644 --- a/pkg/minikube/cruntime/docker.go +++ b/pkg/minikube/cruntime/docker.go @@ -22,6 +22,7 @@ import ( "strings" "github.com/golang/glog" + "github.com/kballard/go-shellquote" "github.com/pkg/errors" "k8s.io/minikube/pkg/minikube/out" ) @@ -123,12 +124,10 @@ func (r *Docker) KubeletOptions() map[string]string { // ListContainers returns a list of containers func (r *Docker) ListContainers(filter string) ([]string, error) { filter = KubernetesContainerPrefix + filter - c := exec.Command("/bin/bash", "-c", fmt.Sprintf(`docker ps -a --filter="name=%s" --format="{{.ID}}"`, filter)) - rr, err := r.Runner.RunCmd(c) + rr, err := r.Runner.RunCmd(exec.Command("docker", "ps", "-a", fmt.Sprintf(`--filter="name=%s"`, filter), "--format=\"{{.ID}}\"")) if err != nil { return nil, errors.Wrapf(err, "docker ListContainers. ") } - var ids []string for _, line := range strings.Split(rr.Stdout.String(), "\n") { if line != "" { @@ -144,7 +143,8 @@ func (r *Docker) KillContainers(ids []string) error { return nil } glog.Infof("Killing containers: %s", ids) - c := exec.Command("/bin/bash", "-c", fmt.Sprintf("docker rm -f %s", strings.Join(ids, " "))) + args := append([]string{"rm", "-f"}, ids...) + c := exec.Command("docker", args...) if _, err := r.Runner.RunCmd(c); err != nil { return errors.Wrap(err, "Killing containers docker.") } @@ -157,7 +157,7 @@ func (r *Docker) StopContainers(ids []string) error { return nil } glog.Infof("Stopping containers: %s", ids) - c := exec.Command("/bin/bash", "-c", fmt.Sprintf("docker stop %s", strings.Join(ids, " "))) + c := exec.Command("docker", "stop", shellquote.Join(ids...)) if _, err := r.Runner.RunCmd(c); err != nil { return errors.Wrap(err, "stopping containers docker.") } From 01573e4bda6457d5e86988abc9d67168a439e028 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 24 Oct 2019 17:07:52 -0700 Subject: [PATCH 50/59] removed more bin bash calls --- pkg/minikube/bootstrapper/certs.go | 16 +++++++--------- pkg/minikube/bootstrapper/certs_test.go | 6 +++--- pkg/minikube/command/ssh_runner.go | 1 - pkg/minikube/cruntime/cruntime.go | 2 +- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index c6f4d10a8558..549f74cd93bd 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -320,7 +320,8 @@ func collectCACerts() (map[string]string, error) { // getSubjectHash calculates Certificate Subject Hash for creating certificate symlinks func getSubjectHash(cr command.Runner, filePath string) (string, error) { - rr, err := cr.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("openssl x509 -hash -noout -in '%s'", filePath))) + c := exec.Command("openssl", "x509", "-hash", "-noout", "-in", filePath) + rr, err := cr.RunCmd(c) if err != nil { return "", errors.Wrapf(err, "getSubjectHash") } @@ -344,11 +345,9 @@ func configureCACerts(cr command.Runner, caCerts map[string]string) error { for _, caCertFile := range caCerts { dstFilename := path.Base(caCertFile) certStorePath := path.Join(SSLCertStoreDir, dstFilename) - - _, err := cr.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo test -f %s", certStorePath))) + _, err := cr.RunCmd(exec.Command("sudo", "test", "-f", certStorePath)) if err != nil { - c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ln -s '%s' '%s'", caCertFile, certStorePath)) - if _, err := cr.RunCmd(c); err != nil { + if _, err := cr.RunCmd(exec.Command("sudo", "ln", "-s", caCertFile, certStorePath)); err != nil { return errors.Wrapf(err, "error making symbol link for certificate %s", caCertFile) } } @@ -358,11 +357,10 @@ func configureCACerts(cr command.Runner, caCerts map[string]string) error { return errors.Wrapf(err, "error calculating subject hash for certificate %s", caCertFile) } subjectHashLink := path.Join(SSLCertStoreDir, fmt.Sprintf("%s.0", subjectHash)) - - _, err = cr.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo test -f %s", subjectHashLink))) + _, err = cr.RunCmd(exec.Command("sudo", "test", "-f", subjectHashLink)) if err != nil { - if _, err := cr.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo ln -s '%s' '%s'", certStorePath, subjectHashLink))); err != nil { - return errors.Wrapf(err, "error making subject hash symbol %s link for certificate %s.", subjectHash, caCertFile) + if _, err := cr.RunCmd(exec.Command("sudo", "ln", "-s", certStorePath, subjectHashLink)); err != nil { + return errors.Wrapf(err, "linking caCertFile %s.", caCertFile) } } } diff --git a/pkg/minikube/bootstrapper/certs_test.go b/pkg/minikube/bootstrapper/certs_test.go index d7083b7c8a4f..7d65e6c3af38 100644 --- a/pkg/minikube/bootstrapper/certs_test.go +++ b/pkg/minikube/bootstrapper/certs_test.go @@ -62,9 +62,9 @@ func TestSetupCerts(t *testing.T) { certStorePath := path.Join(SSLCertStoreDir, dst) certNameHash := "abcdef" remoteCertHashLink := path.Join(SSLCertStoreDir, fmt.Sprintf("%s.0", certNameHash)) - cmdMap[fmt.Sprintf("/bin/bash -c sudo ln -s '%s' '%s'", certFile, certStorePath)] = "1" - cmdMap[fmt.Sprintf("/bin/bash -c openssl x509 -hash -noout -in '%s'", certFile)] = certNameHash - cmdMap[fmt.Sprintf("/bin/bash -c sudo ln -s '%s' '%s'", certStorePath, remoteCertHashLink)] = "1" + cmdMap[fmt.Sprintf("sudo ln -s %s %s", certFile, certStorePath)] = "1" + cmdMap[fmt.Sprintf("openssl x509 -hash -noout -in %s", certFile)] = certNameHash + cmdMap[fmt.Sprintf("sudo ln -s %s %s", certStorePath, remoteCertHashLink)] = "1" } f := command.NewFakeCommandRunner() f.SetCommandToOutput(cmdMap) diff --git a/pkg/minikube/command/ssh_runner.go b/pkg/minikube/command/ssh_runner.go index ce8d621b63e6..2ae140201f46 100644 --- a/pkg/minikube/command/ssh_runner.go +++ b/pkg/minikube/command/ssh_runner.go @@ -133,7 +133,6 @@ func (s *SSHRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { }() elapsed := time.Since(start) - glog.Infof("%s out=%T %v err=%T %v", cmd, outb, outb, errb, errb) err = teeSSH(sess, shellquote.Join(cmd.Args...), outb, errb) if err == nil { // Reduce log spam diff --git a/pkg/minikube/cruntime/cruntime.go b/pkg/minikube/cruntime/cruntime.go index 09db37d162a0..e6bc2e753c75 100644 --- a/pkg/minikube/cruntime/cruntime.go +++ b/pkg/minikube/cruntime/cruntime.go @@ -136,7 +136,7 @@ func enableIPForwarding(cr CommandRunner) error { return errors.Wrap(err, "br_netfilter.") } - c = exec.Command("/bin/bash", "-c", "sudo sh -c \"echo 1 > /proc/sys/net/ipv4/ip_forward\"") + c = exec.Command("sudo", "sh", "-c", "echo 1 > /proc/sys/net/ipv4/ip_forward") if _, err := cr.RunCmd(c); err != nil { return errors.Wrapf(err, "ip_forward.") } From 69dba7c05215c92d22fb8fae6cf181426a31203a Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Fri, 25 Oct 2019 13:57:00 -0700 Subject: [PATCH 51/59] Fix exec runner and remove some debug logging --- pkg/minikube/bootstrapper/kubeadm/kubeadm.go | 2 +- pkg/minikube/command/exec_runner.go | 18 +++++++++++------- pkg/minikube/command/ssh_runner.go | 7 ------- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index 1b54a023f622..ba542742d062 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -141,7 +141,7 @@ func (k *Bootstrapper) GetKubeletStatus() (string, error) { if err != nil { return "", errors.Wrapf(err, "getting kublet status. command: %q", rr.Command()) } - s := strings.TrimSpace(rr.Stdout.String() + rr.Stderr.String()) + s := strings.TrimSpace(rr.Stdout.String()) switch s { case "active": return state.Running.String(), nil diff --git a/pkg/minikube/command/exec_runner.go b/pkg/minikube/command/exec_runner.go index 84e5fcd0a04d..66f804d70c9c 100644 --- a/pkg/minikube/command/exec_runner.go +++ b/pkg/minikube/command/exec_runner.go @@ -42,20 +42,24 @@ func (*ExecRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { rr := &RunResult{Args: cmd.Args} glog.Infof("(ExecRunner) Run: %v", rr.Command()) - var outb, errb bytes.Buffer + var outb, errb io.Writer if cmd.Stdout == nil { - cmd.Stdout, rr.Stdout = &outb, outb + var so bytes.Buffer + outb = io.MultiWriter(&so, &rr.Stdout) } else { - cmd.Stdout = io.MultiWriter(cmd.Stdout, &outb) - rr.Stdout = outb + outb = io.MultiWriter(cmd.Stdout, &rr.Stdout) } + if cmd.Stderr == nil { - cmd.Stderr, rr.Stderr = &errb, errb + var se bytes.Buffer + errb = io.MultiWriter(&se, &rr.Stderr) } else { - cmd.Stderr = io.MultiWriter(cmd.Stderr, &errb) - rr.Stderr = errb + errb = io.MultiWriter(cmd.Stderr, &rr.Stderr) } + cmd.Stdout = outb + cmd.Stderr = errb + start := time.Now() err := cmd.Run() elapsed := time.Since(start) diff --git a/pkg/minikube/command/ssh_runner.go b/pkg/minikube/command/ssh_runner.go index 2ae140201f46..2824b917ea08 100644 --- a/pkg/minikube/command/ssh_runner.go +++ b/pkg/minikube/command/ssh_runner.go @@ -96,16 +96,10 @@ func (s *SSHRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { glog.Infof("(SSHRunner) Run: %v", rr.Command()) var outb, errb io.Writer - start := time.Now() - glog.Infof("cmd: %+v", cmd) - glog.Infof("stdout: %v", cmd.Stdout) - glog.Infof("stderr: %v", cmd.Stderr) - if cmd.Stdout == nil { var so bytes.Buffer - glog.Infof("makin a stdout buffer: %T %v %p", so, so, &so) outb = io.MultiWriter(&so, &rr.Stdout) } else { outb = io.MultiWriter(cmd.Stdout, &rr.Stdout) @@ -113,7 +107,6 @@ func (s *SSHRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { if cmd.Stderr == nil { var se bytes.Buffer - glog.Infof("makin a stderr buffer: %T %v %p", se, se, &se) errb = io.MultiWriter(&se, &rr.Stderr) } else { errb = io.MultiWriter(cmd.Stderr, &rr.Stderr) From 291731c5b23e2a11641b23a6d7b2207f124740bc Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Fri, 25 Oct 2019 14:43:25 -0700 Subject: [PATCH 52/59] change shellquote to args --- pkg/minikube/cruntime/docker.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/minikube/cruntime/docker.go b/pkg/minikube/cruntime/docker.go index 2a80d160d418..bc87b453c917 100644 --- a/pkg/minikube/cruntime/docker.go +++ b/pkg/minikube/cruntime/docker.go @@ -22,7 +22,6 @@ import ( "strings" "github.com/golang/glog" - "github.com/kballard/go-shellquote" "github.com/pkg/errors" "k8s.io/minikube/pkg/minikube/out" ) @@ -157,7 +156,8 @@ func (r *Docker) StopContainers(ids []string) error { return nil } glog.Infof("Stopping containers: %s", ids) - c := exec.Command("docker", "stop", shellquote.Join(ids...)) + args := append([]string{"stop"}, ids...) + c := exec.Command("docker", args...) if _, err := r.Runner.RunCmd(c); err != nil { return errors.Wrap(err, "stopping containers docker.") } From 592ea158ee1ad0da0119d8d17417b59968605736 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Fri, 25 Oct 2019 16:00:36 -0700 Subject: [PATCH 53/59] fix none docker test --- pkg/minikube/cruntime/docker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/minikube/cruntime/docker.go b/pkg/minikube/cruntime/docker.go index bc87b453c917..3d80fca4595b 100644 --- a/pkg/minikube/cruntime/docker.go +++ b/pkg/minikube/cruntime/docker.go @@ -123,7 +123,7 @@ func (r *Docker) KubeletOptions() map[string]string { // ListContainers returns a list of containers func (r *Docker) ListContainers(filter string) ([]string, error) { filter = KubernetesContainerPrefix + filter - rr, err := r.Runner.RunCmd(exec.Command("docker", "ps", "-a", fmt.Sprintf(`--filter="name=%s"`, filter), "--format=\"{{.ID}}\"")) + rr, err := r.Runner.RunCmd(exec.Command("docker", "ps", "-a", fmt.Sprintf("--filter=name=%s", filter), "--format=\"{{.ID}}\"")) if err != nil { return nil, errors.Wrapf(err, "docker ListContainers. ") } From 792de2b0a1f284c38ae1fdd136a95fd15b36a261 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Fri, 25 Oct 2019 17:12:55 -0700 Subject: [PATCH 54/59] resolve code review --- pkg/drivers/none/none.go | 19 +++++++++---------- pkg/minikube/bootstrapper/certs.go | 5 ++--- pkg/minikube/bootstrapper/kubeadm/kubeadm.go | 4 ++-- pkg/minikube/command/ssh_runner.go | 6 ------ pkg/minikube/cruntime/cri.go | 4 ++-- pkg/minikube/cruntime/cruntime_test.go | 6 +----- 6 files changed, 16 insertions(+), 28 deletions(-) diff --git a/pkg/drivers/none/none.go b/pkg/drivers/none/none.go index 236fa970346d..7956864f396e 100644 --- a/pkg/drivers/none/none.go +++ b/pkg/drivers/none/none.go @@ -26,7 +26,6 @@ import ( "github.com/docker/machine/libmachine/drivers" "github.com/docker/machine/libmachine/state" "github.com/golang/glog" - "github.com/kballard/go-shellquote" "github.com/pkg/errors" "k8s.io/apimachinery/pkg/util/net" pkgdrivers "k8s.io/minikube/pkg/drivers" @@ -173,8 +172,8 @@ func (d *Driver) Remove() error { return errors.Wrap(err, "kill") } glog.Infof("Removing: %s", cleanupPaths) - c := exec.Command("sudo", "rm", "-rf", shellquote.Join(cleanupPaths...)) - if _, err := d.exec.RunCmd(c); err != nil { + args := append([]string{"rm", "-rf"}, cleanupPaths...) + if _, err := d.exec.RunCmd(exec.Command("sudo", args...)); err != nil { glog.Errorf("cleanup incomplete: %v", err) } return nil @@ -225,15 +224,15 @@ func (d *Driver) RunSSHCommandFromDriver() error { func stopKubelet(cr command.Runner) error { glog.Infof("stopping kubelet.service ...") stop := func() error { - cmdStop := exec.Command("sudo", "systemctl", "stop", "kubelet.service") - if rr, err := cr.RunCmd(cmdStop); err != nil { + cmd := exec.Command("sudo", "systemctl", "stop", "kubelet.service") + if rr, err := cr.RunCmd(cmd); err != nil { glog.Errorf("temporary error for %q : %v", rr.Command(), err) } var out bytes.Buffer - cmdCheck := exec.Command("sudo", "systemctl", "show", "-p", "SubState", "kubelet") - cmdCheck.Stdout = &out - cmdCheck.Stderr = &out - if rr, err := cr.RunCmd(cmdCheck); err != nil { + cmd = exec.Command("sudo", "systemctl", "show", "-p", "SubState", "kubelet") + cmd.Stdout = &out + cmd.Stderr = &out + if rr, err := cr.RunCmd(cmd); err != nil { glog.Errorf("temporary error: for %q : %v", rr.Command(), err) } if !strings.Contains(out.String(), "dead") && !strings.Contains(out.String(), "failed") { @@ -254,7 +253,7 @@ func restartKubelet(cr command.Runner) error { glog.Infof("restarting kubelet.service ...") c := exec.Command("sudo", "systemctl", "restart", "kubelet.service") if _, err := cr.RunCmd(c); err != nil { - return errors.Wrapf(err, "restartKubelet") + return err } return nil } diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index 549f74cd93bd..acb42300944f 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -320,10 +320,9 @@ func collectCACerts() (map[string]string, error) { // getSubjectHash calculates Certificate Subject Hash for creating certificate symlinks func getSubjectHash(cr command.Runner, filePath string) (string, error) { - c := exec.Command("openssl", "x509", "-hash", "-noout", "-in", filePath) - rr, err := cr.RunCmd(c) + rr, err := cr.RunCmd(exec.Command("openssl", "x509", "-hash", "-noout", "-in", filePath)) if err != nil { - return "", errors.Wrapf(err, "getSubjectHash") + return "", errors.Wrapf(err, rr.Command()) } stringHash := strings.TrimSpace(rr.Stdout.String()) return stringHash, nil diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index ba542742d062..367ed704d0d4 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -300,9 +300,9 @@ func (k *Bootstrapper) StartCluster(k8s config.KubernetesConfig) error { // adjustResourceLimits makes fine adjustments to pod resources that aren't possible via kubeadm config. func (k *Bootstrapper) adjustResourceLimits() error { - rr, err := k.c.RunCmd(exec.Command("cat", "/proc/$(pgrep kube-apiserver)/oom_adj")) + rr, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "cat /proc/$(pgrep kube-apiserver)/oom_adj")) if err != nil { - return errors.Wrap(err, "oom_adj check. command: %q output: %q") + return errors.Wrapf(err, "oom_adj check cmd %s. ", rr.Command()) } glog.Infof("apiserver oom_adj: %s", rr.Stdout.String()) // oom_adj is already a negative number diff --git a/pkg/minikube/command/ssh_runner.go b/pkg/minikube/command/ssh_runner.go index 2824b917ea08..a341afb0498c 100644 --- a/pkg/minikube/command/ssh_runner.go +++ b/pkg/minikube/command/ssh_runner.go @@ -191,19 +191,15 @@ func (s *SSHRunner) Copy(f assets.CopyableFile) error { // teePrefix copies bytes from a reader to writer, logging each new line. func teePrefix(prefix string, r io.Reader, w io.Writer, logger func(format string, args ...interface{})) error { - glog.Infof("prefix=%s, writer=%T %v", prefix, w, w) scanner := bufio.NewScanner(r) scanner.Split(bufio.ScanBytes) var line bytes.Buffer for scanner.Scan() { - glog.Infof("%s scan start ------", prefix) b := scanner.Bytes() - glog.Infof("writing %d bytes to %T %v: %s", len(b), w, w, b) if _, err := w.Write(b); err != nil { return err } - glog.Infof("written!") if bytes.IndexAny(b, "\r\n") == 0 { if line.Len() > 0 { logger("%s%s", prefix, line.String()) @@ -211,9 +207,7 @@ func teePrefix(prefix string, r io.Reader, w io.Writer, logger func(format strin } continue } - glog.Infof("copying to line...") line.Write(b) - glog.Infof("%s scan end ------", prefix) } // Catch trailing output in case stream does not end with a newline if line.Len() > 0 { diff --git a/pkg/minikube/cruntime/cri.go b/pkg/minikube/cruntime/cri.go index 8bf5c53ea24e..173e6523011f 100644 --- a/pkg/minikube/cruntime/cri.go +++ b/pkg/minikube/cruntime/cri.go @@ -400,8 +400,8 @@ image-endpoint: unix://{{.Socket}} return err } c := exec.Command("/bin/bash", "-c", fmt.Sprintf("sudo mkdir -p %s && printf %%s \"%s\" | sudo tee %s", path.Dir(cPath), b.String(), cPath)) - if _, err := cr.RunCmd(c); err != nil { - return errors.Wrap(err, "populateCRIConfig") + if rr, err := cr.RunCmd(c); err != nil { + return errors.Wrapf(err, "Run: %q", rr.Command()) } return nil } diff --git a/pkg/minikube/cruntime/cruntime_test.go b/pkg/minikube/cruntime/cruntime_test.go index bb735849c041..05eee3192ba6 100644 --- a/pkg/minikube/cruntime/cruntime_test.go +++ b/pkg/minikube/cruntime/cruntime_test.go @@ -317,16 +317,12 @@ func (f *FakeRunner) crictl(args []string, _ bool) (string, error) { } // systemctl is a fake implementation of systemctl -func (f *FakeRunner) systemctl(args []string, root bool) (string, error) { +func (f *FakeRunner) systemctl(args []string, root bool) (string, error) { // nolint result 0 (string) is always "" action := args[0] svcs := args[1:] out := "" for i, arg := range args { - // shamelessly useless if statement, only to suppress the lint : - result 0 (string) is always "" - if arg == "unknown" { - out = "unknown" - } // systemctl is-active --quiet service crio if arg == "service" { svcs = args[i+1:] From 1b834df3e47015c70dd5f71e165b38d385abb43c Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Fri, 25 Oct 2019 17:17:27 -0700 Subject: [PATCH 55/59] fix unit test --- pkg/minikube/cruntime/cruntime_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/minikube/cruntime/cruntime_test.go b/pkg/minikube/cruntime/cruntime_test.go index 05eee3192ba6..aa28c8a9dde2 100644 --- a/pkg/minikube/cruntime/cruntime_test.go +++ b/pkg/minikube/cruntime/cruntime_test.go @@ -210,7 +210,7 @@ func (f *FakeRunner) docker(args []string, _ bool) (string, error) { case "ps": // ps -a --filter="name=apiserver" --format="{{.ID}}" if args[1] == "-a" && strings.HasPrefix(args[2], "--filter") { - filter := strings.Split(args[2], `"`)[1] + filter := strings.Split(args[2], `r=`)[1] fname := strings.Split(filter, "=")[1] ids := []string{} f.t.Logf("fake docker: Looking for containers matching %q", fname) From 29a015b63f5cb0c18f86a590ce94cf069d2fe876 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Mon, 28 Oct 2019 14:10:22 -0700 Subject: [PATCH 56/59] remove more bin bash c --- cmd/minikube/cmd/start.go | 7 ++++--- pkg/minikube/command/command_runner.go | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index 14736f486dce..f90da4ac0821 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -1035,9 +1035,9 @@ Suggested workarounds: // Try an HTTPS connection to the proxy := os.Getenv("HTTPS_PROXY") - opts := "-sS" + opts := []string{"-sS"} if proxy != "" && !strings.HasPrefix(proxy, "localhost") && !strings.HasPrefix(proxy, "127.0") { - opts = fmt.Sprintf("-x %s %s", proxy, opts) + opts = append([]string{"-x", proxy}, opts...) } repo := viper.GetString(imageRepository) @@ -1045,7 +1045,8 @@ Suggested workarounds: repo = images.DefaultImageRepo } - if _, err := r.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("curl %s https://%s/", opts, repo))); err != nil { + opts = append(opts, fmt.Sprintf("https://%s/", repo)) + if _, err := r.RunCmd(exec.Command("curl", opts...)); err != nil { out.WarningT("VM is unable to connect to the selected image repository: {{.error}}", out.V{"error": err}) } return ip diff --git a/pkg/minikube/command/command_runner.go b/pkg/minikube/command/command_runner.go index fdfa87d41797..4ef6815e423e 100644 --- a/pkg/minikube/command/command_runner.go +++ b/pkg/minikube/command/command_runner.go @@ -54,7 +54,7 @@ func getDeleteFileCommand(f assets.CopyableFile) string { // Command returns a human readable command string that does not induce eye fatigue func (rr RunResult) Command() string { var sb strings.Builder - sb.WriteString(strings.TrimPrefix(rr.Args[0], "../../")) + sb.WriteString(rr.Args[0]) for _, a := range rr.Args[1:] { if strings.Contains(a, " ") { sb.WriteString(fmt.Sprintf(` "%s"`, a)) From cd9e413852bbac80e1f49b7fa169b5a808b504aa Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Tue, 29 Oct 2019 14:11:21 -0700 Subject: [PATCH 57/59] resolve code review --- pkg/drivers/none/none.go | 7 ++++--- pkg/minikube/bootstrapper/certs.go | 6 +++--- pkg/minikube/bootstrapper/kubeadm/kubeadm.go | 4 ++-- pkg/minikube/command/command_runner.go | 4 ++-- pkg/minikube/command/exec_runner.go | 3 +-- pkg/minikube/cruntime/containerd.go | 10 +++++----- pkg/minikube/cruntime/crio.go | 4 ++-- pkg/minikube/cruntime/cruntime.go | 4 ++-- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/pkg/drivers/none/none.go b/pkg/drivers/none/none.go index 1c367e769ad4..1e96cc6830b4 100644 --- a/pkg/drivers/none/none.go +++ b/pkg/drivers/none/none.go @@ -229,10 +229,11 @@ func stopKubelet(cr command.Runner) error { cmd = exec.Command("sudo", "systemctl", "show", "-p", "SubState", "kubelet") cmd.Stdout = &out cmd.Stderr = &out - if rr, err := cr.RunCmd(cmd); err != nil { + rr, err := cr.RunCmd(cmd) + if err != nil { glog.Errorf("temporary error: for %q : %v", rr.Command(), err) } - if !strings.Contains(out.String(), "dead") && !strings.Contains(out.String(), "failed") { + if !strings.Contains(rr.Stdout.String(), "dead") && !strings.Contains(rr.Stdout.String(), "failed") { return fmt.Errorf("unexpected kubelet state: %q", out) } return nil @@ -260,7 +261,7 @@ func checkKubelet(cr command.Runner) error { glog.Infof("checking for running kubelet ...") c := exec.Command("systemctl", "is-active", "--quiet", "service", "kubelet") if _, err := cr.RunCmd(c); err != nil { - return errors.Wrap(err, "checkKubelet") + return errors.Wrap(err, "check kubelet") } return nil } diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index acb42300944f..6702a6b1220f 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -347,19 +347,19 @@ func configureCACerts(cr command.Runner, caCerts map[string]string) error { _, err := cr.RunCmd(exec.Command("sudo", "test", "-f", certStorePath)) if err != nil { if _, err := cr.RunCmd(exec.Command("sudo", "ln", "-s", caCertFile, certStorePath)); err != nil { - return errors.Wrapf(err, "error making symbol link for certificate %s", caCertFile) + return errors.Wrapf(err, "create symlink for %s", caCertFile) } } if hasSSLBinary { subjectHash, err := getSubjectHash(cr, caCertFile) if err != nil { - return errors.Wrapf(err, "error calculating subject hash for certificate %s", caCertFile) + return errors.Wrapf(err, "calculate hash for cacert %s", caCertFile) } subjectHashLink := path.Join(SSLCertStoreDir, fmt.Sprintf("%s.0", subjectHash)) _, err = cr.RunCmd(exec.Command("sudo", "test", "-f", subjectHashLink)) if err != nil { if _, err := cr.RunCmd(exec.Command("sudo", "ln", "-s", certStorePath, subjectHashLink)); err != nil { - return errors.Wrapf(err, "linking caCertFile %s.", caCertFile) + return errors.Wrapf(err, "linking caCertFile %s", caCertFile) } } } diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index 367ed704d0d4..e4c7607a17d7 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -642,8 +642,8 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error { } } - if _, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "set -x;sudo systemctl daemon-reload && sudo systemctl start kubelet")); err != nil { - return errors.Wrap(err, "starting kubelet.") + if _, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "sudo systemctl daemon-reload && sudo systemctl start kubelet")); err != nil { + return errors.Wrap(err, "starting kubelet") } return nil } diff --git a/pkg/minikube/command/command_runner.go b/pkg/minikube/command/command_runner.go index 4ef6815e423e..309c8f6133a2 100644 --- a/pkg/minikube/command/command_runner.go +++ b/pkg/minikube/command/command_runner.go @@ -36,8 +36,8 @@ type RunResult struct { // Runner represents an interface to run commands. type Runner interface { - // RunCmd is a new expermintal way to run commands, takes Cmd interface and returns run result. - // if succesfull will cause a clean up to get rid of older methods. + // RunCmd runs a cmd of exec.Cmd type. allowing user to set cmd.Stdin, cmd.Stdout,... + // not all implementors are guaranteed to handle all the properties of cmd. RunCmd(cmd *exec.Cmd) (*RunResult, error) // Copy is a convenience method that runs a command to copy a file diff --git a/pkg/minikube/command/exec_runner.go b/pkg/minikube/command/exec_runner.go index 66f804d70c9c..2e9b92e6809f 100644 --- a/pkg/minikube/command/exec_runner.go +++ b/pkg/minikube/command/exec_runner.go @@ -18,7 +18,6 @@ package command import ( "bytes" - "fmt" "io" "os" "os/exec" @@ -73,7 +72,7 @@ func (*ExecRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { rr.ExitCode = exitError.ExitCode() } glog.Infof("(ExecRunner) Non-zero exit: %v: %v (%s)\n%s", rr.Command(), err, elapsed, rr.Output()) - err = errors.Wrapf(err, fmt.Sprintf("stderr: %s", rr.Stderr.String())) + err = errors.Wrapf(err, "command failed: %s\nstdout: %s\nstderr: %s", cmd, rr.Stdout.String(), rr.Stderr.String()) } return rr, err } diff --git a/pkg/minikube/cruntime/containerd.go b/pkg/minikube/cruntime/containerd.go index 85b214dd5d26..934f65c416ba 100644 --- a/pkg/minikube/cruntime/containerd.go +++ b/pkg/minikube/cruntime/containerd.go @@ -161,7 +161,7 @@ func (r *Containerd) Active() bool { // Available returns an error if it is not possible to use this runtime on a host func (r *Containerd) Available() error { - c := exec.Command("command", "-v", "containerd") + c := exec.Command("which", "containerd") if _, err := r.Runner.RunCmd(c); err != nil { return errors.Wrap(err, "check containerd availability.") } @@ -207,7 +207,7 @@ func (r *Containerd) Enable(disOthers bool) error { // Otherwise, containerd will fail API requests with 'Unimplemented' c := exec.Command("sudo", "systemctl", "restart", "containerd") if _, err := r.Runner.RunCmd(c); err != nil { - return errors.Wrap(err, "enable containrd.") + return errors.Wrap(err, "restart containerd") } return nil } @@ -216,7 +216,7 @@ func (r *Containerd) Enable(disOthers bool) error { func (r *Containerd) Disable() error { c := exec.Command("sudo", "systemctl", "stop", "containerd") if _, err := r.Runner.RunCmd(c); err != nil { - return errors.Wrapf(err, "disable containrd.") + return errors.Wrapf(err, "stop containerd") } return nil } @@ -224,9 +224,9 @@ func (r *Containerd) Disable() error { // LoadImage loads an image into this runtime func (r *Containerd) LoadImage(path string) error { glog.Infof("Loading image: %s", path) - c := exec.Command("ctr", "-n=k8s.io", "images", "import", path) + c := exec.Command("sudo", "ctr", "-n=k8s.io", "images", "import", path) if _, err := r.Runner.RunCmd(c); err != nil { - return errors.Wrapf(err, "disable containrd.") + return errors.Wrapf(err, "ctr images import") } return nil } diff --git a/pkg/minikube/cruntime/crio.go b/pkg/minikube/cruntime/crio.go index 0b7b26b3599d..763e52ac7395 100644 --- a/pkg/minikube/cruntime/crio.go +++ b/pkg/minikube/cruntime/crio.go @@ -73,7 +73,7 @@ func (r *CRIO) DefaultCNI() bool { // Available returns an error if it is not possible to use this runtime on a host func (r *CRIO) Available() error { - c := exec.Command("command", "-v", "crio") + c := exec.Command("which", "crio") if _, err := r.Runner.RunCmd(c); err != nil { return errors.Wrapf(err, "check crio available.") } @@ -124,7 +124,7 @@ func (r *CRIO) LoadImage(path string) error { glog.Infof("Loading image: %s", path) c := exec.Command("sudo", "podman", "load", "-i", path) if _, err := r.Runner.RunCmd(c); err != nil { - return errors.Wrap(err, "LoadImage crio.") + return errors.Wrap(err, "crio load image") } return nil } diff --git a/pkg/minikube/cruntime/cruntime.go b/pkg/minikube/cruntime/cruntime.go index e6bc2e753c75..6566a8d8cc02 100644 --- a/pkg/minikube/cruntime/cruntime.go +++ b/pkg/minikube/cruntime/cruntime.go @@ -133,12 +133,12 @@ func disableOthers(me Manager, cr CommandRunner) error { func enableIPForwarding(cr CommandRunner) error { c := exec.Command("sudo", "modprobe", "br_netfilter") if _, err := cr.RunCmd(c); err != nil { - return errors.Wrap(err, "br_netfilter.") + return errors.Wrap(err, "br_netfilter") } c = exec.Command("sudo", "sh", "-c", "echo 1 > /proc/sys/net/ipv4/ip_forward") if _, err := cr.RunCmd(c); err != nil { - return errors.Wrapf(err, "ip_forward.") + return errors.Wrapf(err, "ip_forward") } return nil } From 773c525ae71c1852ac650b72543c8a695a1431d1 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Tue, 29 Oct 2019 16:36:10 -0700 Subject: [PATCH 58/59] fix test and remove extra code --- pkg/drivers/none/none.go | 6 +----- pkg/minikube/command/exec_runner.go | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/pkg/drivers/none/none.go b/pkg/drivers/none/none.go index 1e96cc6830b4..4d99fd8b8ed1 100644 --- a/pkg/drivers/none/none.go +++ b/pkg/drivers/none/none.go @@ -17,7 +17,6 @@ limitations under the License. package none import ( - "bytes" "fmt" "os/exec" "strings" @@ -225,16 +224,13 @@ func stopKubelet(cr command.Runner) error { if rr, err := cr.RunCmd(cmd); err != nil { glog.Errorf("temporary error for %q : %v", rr.Command(), err) } - var out bytes.Buffer cmd = exec.Command("sudo", "systemctl", "show", "-p", "SubState", "kubelet") - cmd.Stdout = &out - cmd.Stderr = &out rr, err := cr.RunCmd(cmd) if err != nil { glog.Errorf("temporary error: for %q : %v", rr.Command(), err) } if !strings.Contains(rr.Stdout.String(), "dead") && !strings.Contains(rr.Stdout.String(), "failed") { - return fmt.Errorf("unexpected kubelet state: %q", out) + return fmt.Errorf("unexpected kubelet state: %q", rr.Stdout.String()) } return nil } diff --git a/pkg/minikube/command/exec_runner.go b/pkg/minikube/command/exec_runner.go index 2e9b92e6809f..a10023b3a82e 100644 --- a/pkg/minikube/command/exec_runner.go +++ b/pkg/minikube/command/exec_runner.go @@ -72,7 +72,7 @@ func (*ExecRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { rr.ExitCode = exitError.ExitCode() } glog.Infof("(ExecRunner) Non-zero exit: %v: %v (%s)\n%s", rr.Command(), err, elapsed, rr.Output()) - err = errors.Wrapf(err, "command failed: %s\nstdout: %s\nstderr: %s", cmd, rr.Stdout.String(), rr.Stderr.String()) + err = errors.Wrapf(err, "command failed: %s\nstdout: %s\nstderr: %s", rr.Command(), rr.Stdout.String(), rr.Stderr.String()) } return rr, err } From 77ccd4694d80ece0ed673d55efa15509ac6750cd Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Tue, 29 Oct 2019 17:50:49 -0700 Subject: [PATCH 59/59] resolve conflict --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 40b1205ad2a9..15e42c3e66fc 100755 --- a/Makefile +++ b/Makefile @@ -15,12 +15,12 @@ # Bump these on release - and please check ISO_VERSION for correctness. VERSION_MAJOR ?= 1 VERSION_MINOR ?= 5 -VERSION_BUILD ?= 0 +VERSION_BUILD ?= 1 RAW_VERSION=$(VERSION_MAJOR).$(VERSION_MINOR).${VERSION_BUILD} VERSION ?= v$(RAW_VERSION) # Default to .0 for higher cache hit rates, as build increments typically don't require new ISO versions -ISO_VERSION ?= v$(VERSION_MAJOR).$(VERSION_MINOR).0-beta.0 +ISO_VERSION ?= v$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_BUILD) # Dashes are valid in semver, but not Linux packaging. Use ~ to delimit alpha/beta DEB_VERSION ?= $(subst -,~,$(RAW_VERSION)) RPM_VERSION ?= $(DEB_VERSION)