From fa9f6d7cd2702b83cee27c0dedddda0bec0ac3a3 Mon Sep 17 00:00:00 2001 From: Isaac Hollander McCreery Date: Wed, 1 Jun 2016 11:06:56 -0700 Subject: [PATCH] Add kubectl version guard around kubectl port-forward --- test/e2e/framework/util.go | 35 ++++++++++++++++++++++++++++++++--- test/e2e/portforward.go | 24 +++++++++++++++++++++--- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/test/e2e/framework/util.go b/test/e2e/framework/util.go index ba9f17e8989..58514359a9f 100644 --- a/test/e2e/framework/util.go +++ b/test/e2e/framework/util.go @@ -30,6 +30,7 @@ import ( "os/exec" "path" "path/filepath" + "regexp" goRuntime "runtime" "sort" "strconv" @@ -154,9 +155,14 @@ const ( RestartPodReadyAgainTimeout = 5 * time.Minute ) -// Label allocated to the image puller static pod that runs on each node -// before e2es. -var ImagePullerLabels = map[string]string{"name": "e2e-image-puller"} +var ( + // Label allocated to the image puller static pod that runs on each node + // before e2es. + ImagePullerLabels = map[string]string{"name": "e2e-image-puller"} + + // For parsing Kubectl version for version-skewed testing. + gitVersionRegexp = regexp.MustCompile("GitVersion:\"(v.+?)\"") +) // GetServerArchitecture fetches the architecture of the cluster's apiserver. func GetServerArchitecture(c *client.Client) string { @@ -1490,6 +1496,29 @@ func ServerVersionGTE(v semver.Version, c discovery.ServerVersionInterface) (boo return sv.GTE(v), nil } +// KubectlVersionGTE returns true if the kubectl version is greater than or +// equal to v. +func KubectlVersionGTE(v semver.Version) (bool, error) { + kv, err := KubectlVersion() + if err != nil { + return false, err + } + return kv.GTE(v), nil +} + +// KubectlVersion gets the version of kubectl that's currently being used (see +// --kubectl-path in e2e.go to use an alternate kubectl). +func KubectlVersion() (semver.Version, error) { + output := RunKubectlOrDie("version", "--client") + matches := gitVersionRegexp.FindStringSubmatch(output) + if len(matches) != 2 { + return semver.Version{}, fmt.Errorf("Could not find kubectl version in output %v", output) + } + // Don't use the full match, as it contains "GitVersion:\"" and a + // trailing "\"". Just use the submatch. + return version.Parse(matches[1]) +} + func PodsResponding(c *client.Client, ns, name string, wantName bool, pods *api.PodList) error { By("trying to dial each unique pod") label := labels.SelectorFromSet(labels.Set(map[string]string{"name": name})) diff --git a/test/e2e/portforward.go b/test/e2e/portforward.go index 854ede3be24..6ba46eeffe9 100644 --- a/test/e2e/portforward.go +++ b/test/e2e/portforward.go @@ -18,6 +18,7 @@ package e2e import ( "fmt" + "io" "io/ioutil" "net" "os/exec" @@ -29,6 +30,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/util/wait" + "k8s.io/kubernetes/pkg/version" "k8s.io/kubernetes/test/e2e/framework" . "github.com/onsi/ginkgo" @@ -39,7 +41,10 @@ const ( ) // TODO support other ports besides 80 -var portForwardRegexp = regexp.MustCompile("Forwarding from 127.0.0.1:([0-9]+) -> 80") +var ( + portForwardRegexp = regexp.MustCompile("Forwarding from 127.0.0.1:([0-9]+) -> 80") + portForwardPortToStdOutV = version.MustParse("v1.3.0-alpha.4") +) func pfPod(expectedClientData, chunks, chunkSize, chunkIntervalMillis string) *api.Pod { return &api.Pod{ @@ -124,15 +129,28 @@ func runPortForward(ns, podName string, port int) *portForwardCommand { // by the port-forward command. We don't want to hard code the port as we have no // way of guaranteeing we can pick one that isn't in use, particularly on Jenkins. framework.Logf("starting port-forward command and streaming output") - stdout, _, err := framework.StartCmdAndStreamOutput(cmd) + stdout, stderr, err := framework.StartCmdAndStreamOutput(cmd) if err != nil { framework.Failf("Failed to start port-forward command: %v", err) } buf := make([]byte, 128) + + // After v1.3.0-alpha.4 (#17030), kubectl port-forward outputs port + // info to stdout, not stderr, so for version-skewed tests, look there + // instead. + var portOutput io.ReadCloser + if useStdOut, err := framework.KubectlVersionGTE(portForwardPortToStdOutV); err != nil { + framework.Failf("Failed to get kubectl version: %v", err) + } else if useStdOut { + portOutput = stdout + } else { + portOutput = stderr + } + var n int framework.Logf("reading from `kubectl port-forward` command's stdout") - if n, err = stdout.Read(buf); err != nil { + if n, err = portOutput.Read(buf); err != nil { framework.Failf("Failed to read from kubectl port-forward stdout: %v", err) } portForwardOutput := string(buf[:n])