From bc0cfd273e59382743640509d2ae11996b52f6bf Mon Sep 17 00:00:00 2001 From: gavinfish Date: Fri, 27 Mar 2020 09:39:30 +0800 Subject: [PATCH] e2e/framework: remove direct imports to /pkg/api/v1/pod --- test/e2e/framework/BUILD | 3 +- test/e2e/framework/util.go | 69 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/test/e2e/framework/BUILD b/test/e2e/framework/BUILD index 370daec5a3c..bdbef4c3f74 100644 --- a/test/e2e/framework/BUILD +++ b/test/e2e/framework/BUILD @@ -23,7 +23,6 @@ go_library( importpath = "k8s.io/kubernetes/test/e2e/framework", visibility = ["//visibility:public"], deps = [ - "//pkg/api/v1/pod:go_default_library", "//pkg/controller:go_default_library", "//pkg/kubelet/apis/config:go_default_library", "//pkg/kubelet/apis/stats/v1alpha1:go_default_library", @@ -44,6 +43,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/yaml:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/serviceaccount:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/client-go/discovery:go_default_library", "//staging/src/k8s.io/client-go/discovery/cached/memory:go_default_library", "//staging/src/k8s.io/client-go/dynamic:go_default_library", @@ -58,6 +58,7 @@ go_library( "//staging/src/k8s.io/client-go/tools/remotecommand:go_default_library", "//staging/src/k8s.io/client-go/tools/watch:go_default_library", "//staging/src/k8s.io/component-base/cli/flag:go_default_library", + "//staging/src/k8s.io/component-base/featuregate:go_default_library", "//staging/src/k8s.io/kubectl/pkg/util/podutils:go_default_library", "//test/e2e/framework/auth:go_default_library", "//test/e2e/framework/ginkgowrapper:go_default_library", diff --git a/test/e2e/framework/util.go b/test/e2e/framework/util.go index bc31b8c5bde..bc1dd97f5f2 100644 --- a/test/e2e/framework/util.go +++ b/test/e2e/framework/util.go @@ -54,6 +54,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" utilyaml "k8s.io/apimachinery/pkg/util/yaml" "k8s.io/apimachinery/pkg/watch" + utilfeature "k8s.io/apiserver/pkg/util/feature" clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" @@ -61,7 +62,7 @@ import ( "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" watchtools "k8s.io/client-go/tools/watch" - podutil "k8s.io/kubernetes/pkg/api/v1/pod" + "k8s.io/component-base/featuregate" "k8s.io/kubernetes/pkg/controller" testutils "k8s.io/kubernetes/test/utils" imageutils "k8s.io/kubernetes/test/utils/image" @@ -142,6 +143,10 @@ const ( // TODO(justinsb): Avoid hardcoding this. awsMasterIP = "172.20.0.9" + + // AllContainers specifies that all containers be visited + // Copied from pkg/api/v1/pod to avoid pulling extra dependencies + AllContainers = InitContainers | Containers | EphemeralContainers ) var ( @@ -734,6 +739,66 @@ func (f *Framework) testContainerOutputMatcher(scenarioName string, ExpectNoError(f.MatchContainerOutput(pod, pod.Spec.Containers[containerIndex].Name, expectedOutput, matcher)) } +// ContainerType signifies container type +type ContainerType int + +const ( + // FeatureEphemeralContainers allows running an ephemeral container in pod namespaces to troubleshoot a running pod + FeatureEphemeralContainers featuregate.Feature = "EphemeralContainers" + // Containers is for normal containers + Containers ContainerType = 1 << iota + // InitContainers is for init containers + InitContainers + // EphemeralContainers is for ephemeral containers + EphemeralContainers +) + +// allFeatureEnabledContainers returns a ContainerType mask which includes all container +// types except for the ones guarded by feature gate. +// Copied from pkg/api/v1/pod to avoid pulling extra dependencies +func allFeatureEnabledContainers() ContainerType { + containerType := AllContainers + if !utilfeature.DefaultFeatureGate.Enabled(FeatureEphemeralContainers) { + containerType &= ^EphemeralContainers + } + return containerType +} + +// ContainerVisitor is called with each container spec, and returns true +// if visiting should continue. +// Copied from pkg/api/v1/pod to avoid pulling extra dependencies +type ContainerVisitor func(container *v1.Container, containerType ContainerType) (shouldContinue bool) + +// visitContainers invokes the visitor function with a pointer to every container +// spec in the given pod spec with type set in mask. If visitor returns false, +// visiting is short-circuited. visitContainers returns true if visiting completes, +// false if visiting was short-circuited. +// Copied from pkg/api/v1/pod to avoid pulling extra dependencies +func visitContainers(podSpec *v1.PodSpec, mask ContainerType, visitor ContainerVisitor) bool { + if mask&InitContainers != 0 { + for i := range podSpec.InitContainers { + if !visitor(&podSpec.InitContainers[i], InitContainers) { + return false + } + } + } + if mask&Containers != 0 { + for i := range podSpec.Containers { + if !visitor(&podSpec.Containers[i], Containers) { + return false + } + } + } + if mask&EphemeralContainers != 0 { + for i := range podSpec.EphemeralContainers { + if !visitor((*v1.Container)(&podSpec.EphemeralContainers[i].EphemeralContainerCommon), EphemeralContainers) { + return false + } + } + } + return true +} + // MatchContainerOutput creates a pod and waits for all it's containers to exit with success. // It then tests that the matcher with each expectedOutput matches the output of the specified container. func (f *Framework) MatchContainerOutput( @@ -764,7 +829,7 @@ func (f *Framework) MatchContainerOutput( if podErr != nil { // Pod failed. Dump all logs from all containers to see what's wrong - _ = podutil.VisitContainers(&podStatus.Spec, podutil.AllFeatureEnabledContainers(), func(c *v1.Container, containerType podutil.ContainerType) bool { + _ = visitContainers(&podStatus.Spec, allFeatureEnabledContainers(), func(c *v1.Container, containerType ContainerType) bool { logs, err := e2epod.GetPodLogs(f.ClientSet, ns, podStatus.Name, c.Name) if err != nil { Logf("Failed to get logs from node %q pod %q container %q: %v",