diff --git a/pkg/kubelet/prober/prober.go b/pkg/kubelet/prober/prober.go index 470817687f..12ba3e6472 100644 --- a/pkg/kubelet/prober/prober.go +++ b/pkg/kubelet/prober/prober.go @@ -214,6 +214,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 4e0452a711..6c01871dd9 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 23c2a26852..80444a9d86 100644 --- a/pkg/util/exec/exec.go +++ b/pkg/util/exec/exec.go @@ -42,6 +42,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) } @@ -84,21 +86,33 @@ func (cmd *cmdWrapper) SetDir(dir string) { func (cmd *cmdWrapper) CombinedOutput() ([]byte, error) { out, err := (*osexec.Cmd)(cmd).CombinedOutput() if err != nil { - if ee, ok := err.(*osexec.ExitError); ok { - // Force a compile fail if exitErrorWrapper can't convert to ExitError. - var x ExitError = &exitErrorWrapper{ee} - return out, x - } - if ee, ok := err.(*osexec.Error); ok { - if ee.Err == osexec.ErrNotFound { - return out, ErrExecutableNotFound - } - } - return out, err + 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 { + if ee, ok := err.(*osexec.ExitError); ok { + // Force a compile fail if exitErrorWrapper can't convert to ExitError. + var x ExitError = &exitErrorWrapper{ee} + return x + } + if ee, ok := err.(*osexec.Error); ok { + if ee.Err == osexec.ErrNotFound { + return ErrExecutableNotFound + } + } + return err +} + // 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 e5737a0bef..40df52921b 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 d9f0037823..832c7d2b31 100644 --- a/test/e2e/ingress.go +++ b/test/e2e/ingress.go @@ -31,6 +31,7 @@ import ( "k8s.io/kubernetes/pkg/apis/extensions" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/labels" + utilexec "k8s.io/kubernetes/pkg/util/exec" "k8s.io/kubernetes/pkg/util/intstr" "k8s.io/kubernetes/pkg/util/wait" @@ -190,12 +191,21 @@ func createApp(c *client.Client, ns string, i int) { // gcloudUnmarshal unmarshals json output of gcloud into given out interface. func gcloudUnmarshal(resource, regex, project string, out interface{}) { - output, err := exec.Command("gcloud", "compute", resource, "list", + // 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", project), - "-q", "--format=json").CombinedOutput() + "-q", "--format=json", + } + output, err := exec.Command("gcloud", command...).Output() if err != nil { - Logf("Error unmarshalling gcloud err: %v, output: %v", err, string(output)) + 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 { Logf("Error unmarshalling gcloud output for %v: %v, output: %v", resource, err, string(output))