diff --git a/pkg/kubelet/prober/prober.go b/pkg/kubelet/prober/prober.go index 01f010095d92..fb81322c28b7 100644 --- a/pkg/kubelet/prober/prober.go +++ b/pkg/kubelet/prober/prober.go @@ -284,6 +284,10 @@ func (eic execInContainer) CombinedOutput() ([]byte, error) { return eic.run() } +func (eic execInContainer) Output() ([]byte, error) { + return nil, fmt.Errorf("unimplemented") +} + func (eic execInContainer) SetDir(dir string) { //unimplemented } diff --git a/pkg/probe/exec/exec_test.go b/pkg/probe/exec/exec_test.go index 4e0452a711dd..6c01871dd98e 100644 --- a/pkg/probe/exec/exec_test.go +++ b/pkg/probe/exec/exec_test.go @@ -24,14 +24,19 @@ import ( ) type FakeCmd struct { - out []byte - err error + out []byte + stdout []byte + err error } func (f *FakeCmd) CombinedOutput() ([]byte, error) { return f.out, f.err } +func (f *FakeCmd) Output() ([]byte, error) { + return f.stdout, f.err +} + func (f *FakeCmd) SetDir(dir string) {} type fakeExitError struct { diff --git a/pkg/util/exec/exec.go b/pkg/util/exec/exec.go index 7a2eda26b250..dc5ae9a69d97 100644 --- a/pkg/util/exec/exec.go +++ b/pkg/util/exec/exec.go @@ -39,6 +39,8 @@ type Cmd interface { // CombinedOutput runs the command and returns its combined standard output // and standard error. This follows the pattern of package os/exec. CombinedOutput() ([]byte, error) + // Output runs the command and returns standard output, but not standard err + Output() ([]byte, error) SetDir(dir string) } @@ -81,17 +83,29 @@ func (cmd *cmdWrapper) SetDir(dir string) { func (cmd *cmdWrapper) CombinedOutput() ([]byte, error) { out, err := (*osexec.Cmd)(cmd).CombinedOutput() if err != nil { - ee, ok := err.(*osexec.ExitError) - if !ok { - return out, err - } - // Force a compile fail if exitErrorWrapper can't convert to ExitError. - var x ExitError = &exitErrorWrapper{ee} - return out, x + return out, handleError(err) } return out, nil } +func (cmd *cmdWrapper) Output() ([]byte, error) { + out, err := (*osexec.Cmd)(cmd).Output() + if err != nil { + return out, handleError(err) + } + return out, nil +} + +func handleError(err error) error { + ee, ok := err.(*osexec.ExitError) + if !ok { + return err + } + // Force a compile fail if exitErrorWrapper can't convert to ExitError. + var x ExitError = &exitErrorWrapper{ee} + return x +} + // exitErrorWrapper is an implementation of ExitError in terms of os/exec ExitError. // Note: standard exec.ExitError is type *os.ProcessState, which already implements Exited(). type exitErrorWrapper struct { diff --git a/pkg/util/exec/fake_exec.go b/pkg/util/exec/fake_exec.go index e69ed55d8093..bd333c30b6ee 100644 --- a/pkg/util/exec/fake_exec.go +++ b/pkg/util/exec/fake_exec.go @@ -75,6 +75,10 @@ func (fake *FakeCmd) CombinedOutput() ([]byte, error) { return fake.CombinedOutputScript[i]() } +func (fake *FakeCmd) Output() ([]byte, error) { + return nil, fmt.Errorf("unimplemented") +} + // A simple fake ExitError type. type FakeExitError struct { Status int diff --git a/test/e2e/ingress.go b/test/e2e/ingress.go index 6ad402b050eb..905346e2d666 100644 --- a/test/e2e/ingress.go +++ b/test/e2e/ingress.go @@ -33,6 +33,7 @@ import ( "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/util" + utilexec "k8s.io/kubernetes/pkg/util/exec" "k8s.io/kubernetes/pkg/util/wait" . "github.com/onsi/ginkgo" @@ -187,18 +188,24 @@ func createApp(c *client.Client, ns string, i int) { // gcloudUnmarshal unmarshals json output of gcloud into given out interface. func gcloudUnmarshal(resource, regex string, out interface{}) { - args := []string{ + // gcloud prints a message to stderr if it has an available update + // so we only look at stdout. + command := []string{ "compute", resource, "list", fmt.Sprintf("--regex=%v", regex), fmt.Sprintf("--project=%v", testContext.CloudConfig.ProjectID), "-q", "--format=json", } - output, err := exec.Command("gcloud", args...).CombinedOutput() + output, err := exec.Command("gcloud", command...).Output() if err != nil { - Failf("Error unmarshalling gcloud output: %v", err) + errCode := -1 + if exitErr, ok := err.(utilexec.ExitError); ok { + errCode = exitErr.ExitStatus() + } + Logf("Error running gcloud command 'gcloud %s': err: %v, output: %v, status: %d", strings.Join(command, " "), err, string(output), errCode) } if err := json.Unmarshal([]byte(output), out); err != nil { - Failf("Error unmarshalling gcloud output for %v: %v, output: %v, command: gcloud %s", resource, err, string(output), strings.Join(args, " ")) + Failf("Error unmarshalling gcloud output for %v: %v, output: %v, command: gcloud %s", resource, err, string(output), strings.Join(command, " ")) } }