mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +00:00
Remove EphemeralContainers feature-gate checks
This commit is contained in:
parent
bc3c5ae269
commit
d238e67ba6
@ -46,11 +46,7 @@ const AllContainers ContainerType = (InitContainers | Containers | EphemeralCont
|
||||
// AllFeatureEnabledContainers returns a ContainerType mask which includes all container
|
||||
// types except for the ones guarded by feature gate.
|
||||
func AllFeatureEnabledContainers() ContainerType {
|
||||
containerType := AllContainers
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) {
|
||||
containerType &= ^EphemeralContainers
|
||||
}
|
||||
return containerType
|
||||
return AllContainers
|
||||
}
|
||||
|
||||
// ContainerVisitor is called with each container spec, and returns true
|
||||
@ -529,10 +525,6 @@ func dropDisabledFields(
|
||||
}
|
||||
}
|
||||
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) && !ephemeralContainersInUse(oldPodSpec) {
|
||||
podSpec.EphemeralContainers = nil
|
||||
}
|
||||
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.ProbeTerminationGracePeriod) && !probeGracePeriodInUse(oldPodSpec) {
|
||||
// Set pod-level terminationGracePeriodSeconds to nil if the feature is disabled and it is not used
|
||||
VisitContainers(podSpec, AllContainers, func(c *api.Container, containerType ContainerType) bool {
|
||||
@ -654,13 +646,6 @@ func nodeTaintsPolicyInUse(podSpec *api.PodSpec) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func ephemeralContainersInUse(podSpec *api.PodSpec) bool {
|
||||
if podSpec == nil {
|
||||
return false
|
||||
}
|
||||
return len(podSpec.EphemeralContainers) > 0
|
||||
}
|
||||
|
||||
// procMountInUse returns true if the pod spec is non-nil and has a SecurityContext's ProcMount field set to a non-default value
|
||||
func procMountInUse(podSpec *api.PodSpec) bool {
|
||||
if podSpec == nil {
|
||||
|
@ -39,11 +39,10 @@ import (
|
||||
func TestVisitContainers(t *testing.T) {
|
||||
setAllFeatureEnabledContainersDuringTest := ContainerType(0)
|
||||
testCases := []struct {
|
||||
desc string
|
||||
spec *api.PodSpec
|
||||
wantContainers []string
|
||||
mask ContainerType
|
||||
ephemeralContainersEnabled bool
|
||||
desc string
|
||||
spec *api.PodSpec
|
||||
wantContainers []string
|
||||
mask ContainerType
|
||||
}{
|
||||
{
|
||||
desc: "empty podspec",
|
||||
@ -127,25 +126,6 @@ func TestVisitContainers(t *testing.T) {
|
||||
wantContainers: []string{"i1", "i2", "c1", "c2", "e1", "e2"},
|
||||
mask: AllContainers,
|
||||
},
|
||||
{
|
||||
desc: "all feature enabled container types with ephemeral containers disabled",
|
||||
spec: &api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
{Name: "c1"},
|
||||
{Name: "c2"},
|
||||
},
|
||||
InitContainers: []api.Container{
|
||||
{Name: "i1"},
|
||||
{Name: "i2"},
|
||||
},
|
||||
EphemeralContainers: []api.EphemeralContainer{
|
||||
{EphemeralContainerCommon: api.EphemeralContainerCommon{Name: "e1"}},
|
||||
{EphemeralContainerCommon: api.EphemeralContainerCommon{Name: "e2"}},
|
||||
},
|
||||
},
|
||||
wantContainers: []string{"i1", "i2", "c1", "c2"},
|
||||
mask: setAllFeatureEnabledContainersDuringTest,
|
||||
},
|
||||
{
|
||||
desc: "all feature enabled container types with ephemeral containers enabled",
|
||||
spec: &api.PodSpec{
|
||||
@ -162,9 +142,8 @@ func TestVisitContainers(t *testing.T) {
|
||||
{EphemeralContainerCommon: api.EphemeralContainerCommon{Name: "e2"}},
|
||||
},
|
||||
},
|
||||
wantContainers: []string{"i1", "i2", "c1", "c2", "e1", "e2"},
|
||||
mask: setAllFeatureEnabledContainersDuringTest,
|
||||
ephemeralContainersEnabled: true,
|
||||
wantContainers: []string{"i1", "i2", "c1", "c2", "e1", "e2"},
|
||||
mask: setAllFeatureEnabledContainersDuringTest,
|
||||
},
|
||||
{
|
||||
desc: "dropping fields",
|
||||
@ -189,8 +168,6 @@ func TestVisitContainers(t *testing.T) {
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, tc.ephemeralContainersEnabled)()
|
||||
|
||||
if tc.mask == setAllFeatureEnabledContainersDuringTest {
|
||||
tc.mask = AllFeatureEnabledContainers()
|
||||
}
|
||||
@ -226,8 +203,6 @@ func TestVisitContainers(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPodSecrets(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)()
|
||||
|
||||
// Stub containing all possible secret references in a pod.
|
||||
// The names of the referenced secrets match struct paths detected by reflection.
|
||||
pod := &api.Pod{
|
||||
@ -425,8 +400,6 @@ func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, n
|
||||
}
|
||||
|
||||
func TestPodConfigmaps(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)()
|
||||
|
||||
// Stub containing all possible ConfigMap references in a pod.
|
||||
// The names of the referenced ConfigMaps match struct paths detected by reflection.
|
||||
pod := &api.Pod{
|
||||
@ -1023,95 +996,6 @@ func TestDropProbeGracePeriod(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDropEphemeralContainers(t *testing.T) {
|
||||
podWithEphemeralContainers := func() *api.Pod {
|
||||
return &api.Pod{
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyNever,
|
||||
EphemeralContainers: []api.EphemeralContainer{{EphemeralContainerCommon: api.EphemeralContainerCommon{Name: "container1", Image: "testimage"}}},
|
||||
},
|
||||
}
|
||||
}
|
||||
podWithoutEphemeralContainers := func() *api.Pod {
|
||||
return &api.Pod{
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyNever,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
podInfo := []struct {
|
||||
description string
|
||||
hasEphemeralContainers bool
|
||||
pod func() *api.Pod
|
||||
}{
|
||||
{
|
||||
description: "has ephemeral containers",
|
||||
hasEphemeralContainers: true,
|
||||
pod: podWithEphemeralContainers,
|
||||
},
|
||||
{
|
||||
description: "does not have ephemeral containers",
|
||||
hasEphemeralContainers: false,
|
||||
pod: podWithoutEphemeralContainers,
|
||||
},
|
||||
{
|
||||
description: "is nil",
|
||||
hasEphemeralContainers: false,
|
||||
pod: func() *api.Pod { return nil },
|
||||
},
|
||||
}
|
||||
|
||||
for _, enabled := range []bool{true, false} {
|
||||
for _, oldPodInfo := range podInfo {
|
||||
for _, newPodInfo := range podInfo {
|
||||
oldPodHasEphemeralContainers, oldPod := oldPodInfo.hasEphemeralContainers, oldPodInfo.pod()
|
||||
newPodHasEphemeralContainers, newPod := newPodInfo.hasEphemeralContainers, newPodInfo.pod()
|
||||
if newPod == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
t.Run(fmt.Sprintf("feature enabled=%v, old pod %v, new pod %v", enabled, oldPodInfo.description, newPodInfo.description), func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, enabled)()
|
||||
|
||||
var oldPodSpec *api.PodSpec
|
||||
if oldPod != nil {
|
||||
oldPodSpec = &oldPod.Spec
|
||||
}
|
||||
dropDisabledFields(&newPod.Spec, nil, oldPodSpec, nil)
|
||||
|
||||
// old pod should never be changed
|
||||
if !reflect.DeepEqual(oldPod, oldPodInfo.pod()) {
|
||||
t.Errorf("old pod changed: %v", cmp.Diff(oldPod, oldPodInfo.pod()))
|
||||
}
|
||||
|
||||
switch {
|
||||
case enabled || oldPodHasEphemeralContainers:
|
||||
// new pod should not be changed if the feature is enabled, or if the old pod had subpaths
|
||||
if !reflect.DeepEqual(newPod, newPodInfo.pod()) {
|
||||
t.Errorf("new pod changed: %v", cmp.Diff(newPod, newPodInfo.pod()))
|
||||
}
|
||||
case newPodHasEphemeralContainers:
|
||||
// new pod should be changed
|
||||
if reflect.DeepEqual(newPod, newPodInfo.pod()) {
|
||||
t.Errorf("new pod was not changed")
|
||||
}
|
||||
// new pod should not have subpaths
|
||||
if !reflect.DeepEqual(newPod, podWithoutEphemeralContainers()) {
|
||||
t.Errorf("new pod had subpaths: %v", cmp.Diff(newPod, podWithoutEphemeralContainers()))
|
||||
}
|
||||
default:
|
||||
// new pod should not need to be changed
|
||||
if !reflect.DeepEqual(newPod, newPodInfo.pod()) {
|
||||
t.Errorf("new pod changed: %v", cmp.Diff(newPod, newPodInfo.pod()))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidatePodDeletionCostOption(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
|
@ -23,8 +23,6 @@ import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
// FindPort locates the container port for the given pod and portName. If the
|
||||
@ -68,11 +66,7 @@ const AllContainers ContainerType = (InitContainers | Containers | EphemeralCont
|
||||
// AllFeatureEnabledContainers returns a ContainerType mask which includes all container
|
||||
// types except for the ones guarded by feature gate.
|
||||
func AllFeatureEnabledContainers() ContainerType {
|
||||
containerType := AllContainers
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) {
|
||||
containerType &= ^EphemeralContainers
|
||||
}
|
||||
return containerType
|
||||
return AllContainers
|
||||
}
|
||||
|
||||
// ContainerVisitor is called with each container spec, and returns true
|
||||
|
@ -29,9 +29,6 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
func TestFindPort(t *testing.T) {
|
||||
@ -205,11 +202,10 @@ func TestFindPort(t *testing.T) {
|
||||
func TestVisitContainers(t *testing.T) {
|
||||
setAllFeatureEnabledContainersDuringTest := ContainerType(0)
|
||||
testCases := []struct {
|
||||
desc string
|
||||
spec *v1.PodSpec
|
||||
wantContainers []string
|
||||
mask ContainerType
|
||||
ephemeralContainersEnabled bool
|
||||
desc string
|
||||
spec *v1.PodSpec
|
||||
wantContainers []string
|
||||
mask ContainerType
|
||||
}{
|
||||
{
|
||||
desc: "empty podspec",
|
||||
@ -294,26 +290,7 @@ func TestVisitContainers(t *testing.T) {
|
||||
mask: AllContainers,
|
||||
},
|
||||
{
|
||||
desc: "all feature enabled container types with ephemeral containers disabled",
|
||||
spec: &v1.PodSpec{
|
||||
Containers: []v1.Container{
|
||||
{Name: "c1"},
|
||||
{Name: "c2"},
|
||||
},
|
||||
InitContainers: []v1.Container{
|
||||
{Name: "i1"},
|
||||
{Name: "i2"},
|
||||
},
|
||||
EphemeralContainers: []v1.EphemeralContainer{
|
||||
{EphemeralContainerCommon: v1.EphemeralContainerCommon{Name: "e1"}},
|
||||
{EphemeralContainerCommon: v1.EphemeralContainerCommon{Name: "e2"}},
|
||||
},
|
||||
},
|
||||
wantContainers: []string{"i1", "i2", "c1", "c2"},
|
||||
mask: setAllFeatureEnabledContainersDuringTest,
|
||||
},
|
||||
{
|
||||
desc: "all feature enabled container types with ephemeral containers enabled",
|
||||
desc: "all feature enabled container types",
|
||||
spec: &v1.PodSpec{
|
||||
Containers: []v1.Container{
|
||||
{Name: "c1"},
|
||||
@ -328,9 +305,8 @@ func TestVisitContainers(t *testing.T) {
|
||||
{EphemeralContainerCommon: v1.EphemeralContainerCommon{Name: "e2"}},
|
||||
},
|
||||
},
|
||||
wantContainers: []string{"i1", "i2", "c1", "c2", "e1", "e2"},
|
||||
mask: setAllFeatureEnabledContainersDuringTest,
|
||||
ephemeralContainersEnabled: true,
|
||||
wantContainers: []string{"i1", "i2", "c1", "c2", "e1", "e2"},
|
||||
mask: setAllFeatureEnabledContainersDuringTest,
|
||||
},
|
||||
{
|
||||
desc: "dropping fields",
|
||||
@ -355,8 +331,6 @@ func TestVisitContainers(t *testing.T) {
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, tc.ephemeralContainersEnabled)()
|
||||
|
||||
if tc.mask == setAllFeatureEnabledContainersDuringTest {
|
||||
tc.mask = AllFeatureEnabledContainers()
|
||||
}
|
||||
@ -392,8 +366,6 @@ func TestVisitContainers(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPodSecrets(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)()
|
||||
|
||||
// Stub containing all possible secret references in a pod.
|
||||
// The names of the referenced secrets match struct paths detected by reflection.
|
||||
pod := &v1.Pod{
|
||||
@ -591,8 +563,6 @@ func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, n
|
||||
}
|
||||
|
||||
func TestPodConfigmaps(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)()
|
||||
|
||||
// Stub containing all possible ConfigMap references in a pod.
|
||||
// The names of the referenced ConfigMaps match struct paths detected by reflection.
|
||||
pod := &v1.Pod{
|
||||
|
@ -2396,8 +2396,6 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateDaemonSet(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)()
|
||||
|
||||
validSelector := map[string]string{"a": "b"}
|
||||
validPodTemplate := api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{
|
||||
@ -2660,8 +2658,6 @@ func validDeployment() *apps.Deployment {
|
||||
}
|
||||
|
||||
func TestValidateDeployment(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)()
|
||||
|
||||
successCases := []*apps.Deployment{
|
||||
validDeployment(),
|
||||
}
|
||||
|
@ -20,9 +20,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/fieldpath"
|
||||
)
|
||||
|
||||
@ -47,12 +45,10 @@ func VisitContainersWithPath(podSpec *api.PodSpec, specPath *field.Path, visitor
|
||||
return false
|
||||
}
|
||||
}
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) {
|
||||
fldPath = specPath.Child("ephemeralContainers")
|
||||
for i := range podSpec.EphemeralContainers {
|
||||
if !visitor((*api.Container)(&podSpec.EphemeralContainers[i].EphemeralContainerCommon), fldPath.Index(i)) {
|
||||
return false
|
||||
}
|
||||
fldPath = specPath.Child("ephemeralContainers")
|
||||
for i := range podSpec.EphemeralContainers {
|
||||
if !visitor((*api.Container)(&podSpec.EphemeralContainers[i].EphemeralContainerCommon), fldPath.Index(i)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
@ -21,15 +21,10 @@ import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
func TestVisitContainersWithPath(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)()
|
||||
|
||||
testCases := []struct {
|
||||
description string
|
||||
path *field.Path
|
||||
|
@ -11485,8 +11485,6 @@ func makeValidService() core.Service {
|
||||
}
|
||||
|
||||
func TestValidatePodEphemeralContainersUpdate(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)()
|
||||
|
||||
makePod := func(ephemeralContainers []core.EphemeralContainer) *core.Pod {
|
||||
return &core.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@ -20312,7 +20310,6 @@ func TestValidateWindowsHostProcessPod(t *testing.T) {
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.WindowsHostProcessContainers, testCase.featureEnabled)()
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)()
|
||||
|
||||
opts := PodValidationOptions{AllowWindowsHostProcessField: testCase.featureEnabled}
|
||||
|
||||
|
@ -26,9 +26,6 @@ import (
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
func TestEnvVarsToMap(t *testing.T) {
|
||||
@ -326,7 +323,6 @@ func TestExpandVolumeMountsWithSubpath(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetContainerSpec(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)()
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
havePod *v1.Pod
|
||||
|
@ -20,10 +20,8 @@ import (
|
||||
"fmt"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
ref "k8s.io/client-go/tools/reference"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
// ImplicitContainerPrefix is a container name prefix that will indicate that container was started implicitly (like the pod infra container).
|
||||
@ -67,15 +65,13 @@ func fieldPath(pod *v1.Pod, container *v1.Container) (string, error) {
|
||||
return fmt.Sprintf("spec.initContainers{%s}", here.Name), nil
|
||||
}
|
||||
}
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) {
|
||||
for i := range pod.Spec.EphemeralContainers {
|
||||
here := &pod.Spec.EphemeralContainers[i]
|
||||
if here.Name == container.Name {
|
||||
if here.Name == "" {
|
||||
return fmt.Sprintf("spec.ephemeralContainers[%d]", i), nil
|
||||
}
|
||||
return fmt.Sprintf("spec.ephemeralContainers{%s}", here.Name), nil
|
||||
for i := range pod.Spec.EphemeralContainers {
|
||||
here := &pod.Spec.EphemeralContainers[i]
|
||||
if here.Name == container.Name {
|
||||
if here.Name == "" {
|
||||
return fmt.Sprintf("spec.ephemeralContainers[%d]", i), nil
|
||||
}
|
||||
return fmt.Sprintf("spec.ephemeralContainers{%s}", here.Name), nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("container %q not found in pod %s/%s", container.Name, pod.Namespace, pod.Name)
|
||||
|
@ -1221,7 +1221,7 @@ func (kl *Kubelet) validateContainerLogStatus(podName string, podStatus *v1.PodS
|
||||
if !found {
|
||||
cStatus, found = podutil.GetContainerStatus(podStatus.InitContainerStatuses, containerName)
|
||||
}
|
||||
if !found && utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) {
|
||||
if !found {
|
||||
cStatus, found = podutil.GetContainerStatus(podStatus.EphemeralContainerStatuses, containerName)
|
||||
}
|
||||
if !found {
|
||||
@ -1602,23 +1602,21 @@ func (kl *Kubelet) convertStatusToAPIStatus(pod *v1.Pod, podStatus *kubecontaine
|
||||
len(pod.Spec.InitContainers) > 0,
|
||||
true,
|
||||
)
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) {
|
||||
var ecSpecs []v1.Container
|
||||
for i := range pod.Spec.EphemeralContainers {
|
||||
ecSpecs = append(ecSpecs, v1.Container(pod.Spec.EphemeralContainers[i].EphemeralContainerCommon))
|
||||
}
|
||||
|
||||
// #80875: By now we've iterated podStatus 3 times. We could refactor this to make a single
|
||||
// pass through podStatus.ContainerStatuses
|
||||
apiPodStatus.EphemeralContainerStatuses = kl.convertToAPIContainerStatuses(
|
||||
pod, podStatus,
|
||||
oldPodStatus.EphemeralContainerStatuses,
|
||||
ecSpecs,
|
||||
len(pod.Spec.InitContainers) > 0,
|
||||
false,
|
||||
)
|
||||
var ecSpecs []v1.Container
|
||||
for i := range pod.Spec.EphemeralContainers {
|
||||
ecSpecs = append(ecSpecs, v1.Container(pod.Spec.EphemeralContainers[i].EphemeralContainerCommon))
|
||||
}
|
||||
|
||||
// #80875: By now we've iterated podStatus 3 times. We could refactor this to make a single
|
||||
// pass through podStatus.ContainerStatuses
|
||||
apiPodStatus.EphemeralContainerStatuses = kl.convertToAPIContainerStatuses(
|
||||
pod, podStatus,
|
||||
oldPodStatus.EphemeralContainerStatuses,
|
||||
ecSpecs,
|
||||
len(pod.Spec.InitContainers) > 0,
|
||||
false,
|
||||
)
|
||||
|
||||
return &apiPodStatus
|
||||
}
|
||||
|
||||
|
@ -46,9 +46,7 @@ import (
|
||||
kubetypes "k8s.io/apimachinery/pkg/types"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
"k8s.io/kubernetes/pkg/kubelet/cri/remote"
|
||||
"k8s.io/kubernetes/pkg/kubelet/events"
|
||||
@ -120,7 +118,7 @@ func ephemeralContainerStartSpec(ec *v1.EphemeralContainer) *startSpec {
|
||||
// usually isn't a problem since ephemeral containers aren't allowed at pod creation time.
|
||||
// This always returns nil when the EphemeralContainers feature is disabled.
|
||||
func (s *startSpec) getTargetID(podStatus *kubecontainer.PodStatus) (*kubecontainer.ContainerID, error) {
|
||||
if s.ephemeralContainer == nil || s.ephemeralContainer.TargetContainerName == "" || !utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) {
|
||||
if s.ephemeralContainer == nil || s.ephemeralContainer.TargetContainerName == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
@ -520,7 +520,6 @@ func TestGetHugepageLimitsFromResources(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGenerateLinuxContainerConfigNamespaces(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)()
|
||||
_, _, m, err := createTestRuntimeManager()
|
||||
if err != nil {
|
||||
t.Fatalf("error creating test RuntimeManager: %v", err)
|
||||
|
@ -17,7 +17,6 @@ limitations under the License.
|
||||
package kuberuntime
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -32,10 +31,7 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
containertest "k8s.io/kubernetes/pkg/kubelet/container/testing"
|
||||
"k8s.io/kubernetes/pkg/kubelet/lifecycle"
|
||||
@ -405,23 +401,12 @@ func TestStartSpec(t *testing.T) {
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)()
|
||||
if got, err := tc.spec.getTargetID(podStatus); err != nil {
|
||||
t.Fatalf("%v: getTargetID got unexpected error: %v", t.Name(), err)
|
||||
} else if diff := cmp.Diff(tc.want, got); diff != "" {
|
||||
t.Errorf("%v: getTargetID got unexpected result. diff:\n%v", t.Name(), diff)
|
||||
}
|
||||
})
|
||||
|
||||
// Test with feature disabled in self-contained section which can be removed when feature flag is removed.
|
||||
t.Run(fmt.Sprintf("%s (disabled)", tc.name), func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, false)()
|
||||
if got, err := tc.spec.getTargetID(podStatus); err != nil {
|
||||
t.Fatalf("%v: getTargetID got unexpected error: %v", t.Name(), err)
|
||||
} else if got != nil {
|
||||
t.Errorf("%v: getTargetID got: %v, wanted nil", t.Name(), got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -578,14 +578,12 @@ func (m *kubeGenericRuntimeManager) computePodActions(pod *v1.Pod, podStatus *ku
|
||||
}
|
||||
|
||||
// Ephemeral containers may be started even if initialization is not yet complete.
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) {
|
||||
for i := range pod.Spec.EphemeralContainers {
|
||||
c := (*v1.Container)(&pod.Spec.EphemeralContainers[i].EphemeralContainerCommon)
|
||||
for i := range pod.Spec.EphemeralContainers {
|
||||
c := (*v1.Container)(&pod.Spec.EphemeralContainers[i].EphemeralContainerCommon)
|
||||
|
||||
// Ephemeral Containers are never restarted
|
||||
if podStatus.FindContainerStatusByName(c.Name) == nil {
|
||||
changes.EphemeralContainersToStart = append(changes.EphemeralContainersToStart, i)
|
||||
}
|
||||
// Ephemeral Containers are never restarted
|
||||
if podStatus.FindContainerStatusByName(c.Name) == nil {
|
||||
changes.EphemeralContainersToStart = append(changes.EphemeralContainersToStart, i)
|
||||
}
|
||||
}
|
||||
|
||||
@ -914,10 +912,8 @@ func (m *kubeGenericRuntimeManager) SyncPod(pod *v1.Pod, podStatus *kubecontaine
|
||||
// These are started "prior" to init containers to allow running ephemeral containers even when there
|
||||
// are errors starting an init container. In practice init containers will start first since ephemeral
|
||||
// containers cannot be specified on pod creation.
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) {
|
||||
for _, idx := range podContainerChanges.EphemeralContainersToStart {
|
||||
start("ephemeral container", metrics.EphemeralContainer, ephemeralContainerStartSpec(&pod.Spec.EphemeralContainers[idx]))
|
||||
}
|
||||
for _, idx := range podContainerChanges.EphemeralContainersToStart {
|
||||
start("ephemeral container", metrics.EphemeralContainer, ephemeralContainerStartSpec(&pod.Spec.EphemeralContainers[idx]))
|
||||
}
|
||||
|
||||
// Step 6: start the init container.
|
||||
|
@ -35,14 +35,11 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
|
||||
apitest "k8s.io/cri-api/pkg/apis/testing"
|
||||
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
|
||||
"k8s.io/kubernetes/pkg/credentialprovider"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
containertest "k8s.io/kubernetes/pkg/kubelet/container/testing"
|
||||
proberesults "k8s.io/kubernetes/pkg/kubelet/prober/results"
|
||||
@ -490,9 +487,6 @@ func TestGetPods(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestKillPod(t *testing.T) {
|
||||
// Tests that KillPod also kills Ephemeral Containers
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)()
|
||||
|
||||
fakeRuntime, _, m, err := createTestRuntimeManager()
|
||||
assert.NoError(t, err)
|
||||
|
||||
@ -1372,7 +1366,6 @@ func makeBasePodAndStatusWithInitContainers() (*v1.Pod, *kubecontainer.PodStatus
|
||||
}
|
||||
|
||||
func TestComputePodActionsWithInitAndEphemeralContainers(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)()
|
||||
// Make sure existing test cases pass with feature enabled
|
||||
TestComputePodActions(t)
|
||||
TestComputePodActionsWithInitContainers(t)
|
||||
|
@ -22,8 +22,6 @@ import (
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/kubelet/configmap"
|
||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
"k8s.io/kubernetes/pkg/kubelet/metrics"
|
||||
@ -162,10 +160,6 @@ func (pm *basicManager) UpdatePod(pod *v1.Pod) {
|
||||
// updateMetrics updates the metrics surfaced by the pod manager.
|
||||
// oldPod or newPod may be nil to signify creation or deletion.
|
||||
func updateMetrics(oldPod, newPod *v1.Pod) {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) {
|
||||
return
|
||||
}
|
||||
|
||||
var numEC int
|
||||
if oldPod != nil {
|
||||
numEC -= len(oldPod.Spec.EphemeralContainers)
|
||||
|
@ -916,7 +916,7 @@ func (s *Server) checkpoint(request *restful.Request, response *restful.Response
|
||||
}
|
||||
}
|
||||
}
|
||||
if !found && utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) {
|
||||
if !found {
|
||||
for _, container := range pod.Spec.EphemeralContainers {
|
||||
if container.Name == containerName {
|
||||
found = true
|
||||
|
@ -33,12 +33,10 @@ import (
|
||||
"k8s.io/apiserver/pkg/storage"
|
||||
storeerr "k8s.io/apiserver/pkg/storage/errors"
|
||||
"k8s.io/apiserver/pkg/util/dryrun"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
policyclient "k8s.io/client-go/kubernetes/typed/policy/v1"
|
||||
podutil "k8s.io/kubernetes/pkg/api/pod"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/core/validation"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/kubelet/client"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
|
||||
@ -330,10 +328,6 @@ var _ = rest.Patcher(&EphemeralContainersREST{})
|
||||
|
||||
// Get retrieves the object from the storage. It is required to support Patch.
|
||||
func (r *EphemeralContainersREST) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) {
|
||||
return nil, errors.NewBadRequest("feature EphemeralContainers disabled")
|
||||
}
|
||||
|
||||
return r.store.Get(ctx, name, options)
|
||||
}
|
||||
|
||||
@ -350,10 +344,6 @@ func (r *EphemeralContainersREST) Destroy() {
|
||||
|
||||
// Update alters the EphemeralContainers field in PodSpec
|
||||
func (r *EphemeralContainersREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) {
|
||||
return nil, false, errors.NewBadRequest("feature EphemeralContainers disabled")
|
||||
}
|
||||
|
||||
// We are explicitly setting forceAllowCreate to false in the call to the underlying storage because
|
||||
// subresources should never allow create on update.
|
||||
return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options)
|
||||
|
@ -35,12 +35,9 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/kubelet/client"
|
||||
utilpointer "k8s.io/utils/pointer"
|
||||
|
||||
@ -355,7 +352,6 @@ func (g mockPodGetter) Get(context.Context, string, *metav1.GetOptions) (runtime
|
||||
}
|
||||
|
||||
func TestCheckLogLocation(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)()
|
||||
ctx := genericapirequest.NewDefaultContext()
|
||||
fakePodName := "test"
|
||||
tcs := []struct {
|
||||
|
@ -36,13 +36,11 @@ import (
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
serverstorage "k8s.io/apiserver/pkg/server/storage"
|
||||
"k8s.io/apiserver/pkg/storage/etcd3"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
policyclient "k8s.io/client-go/kubernetes/typed/policy/v1"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/cluster/ports"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
|
||||
"k8s.io/kubernetes/pkg/registry/core/componentstatus"
|
||||
configmapstore "k8s.io/kubernetes/pkg/registry/core/configmap/storage"
|
||||
@ -291,9 +289,7 @@ func (c LegacyRESTStorageProvider) NewLegacyRESTStorage(apiResourceConfigSource
|
||||
if podStorage.Eviction != nil {
|
||||
storage[resource+"/eviction"] = podStorage.Eviction
|
||||
}
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.EphemeralContainers) {
|
||||
storage[resource+"/ephemeralcontainers"] = podStorage.EphemeralContainers
|
||||
}
|
||||
storage[resource+"/ephemeralcontainers"] = podStorage.EphemeralContainers
|
||||
|
||||
}
|
||||
if resource := "bindings"; apiResourceConfigSource.ResourceEnabled(corev1.SchemeGroupVersion.WithResource(resource)) {
|
||||
|
@ -28,10 +28,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
_ "k8s.io/kubernetes/pkg/apis/core/install"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/util/slice"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
utilptr "k8s.io/utils/pointer"
|
||||
@ -581,7 +578,6 @@ func TestMakeAbsolutePath(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetPodVolumeNames(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)()
|
||||
tests := []struct {
|
||||
name string
|
||||
pod *v1.Pod
|
||||
|
@ -20,12 +20,10 @@ import (
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/kubernetes/pkg/kubelet/util/format"
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
||||
e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper"
|
||||
imageutils "k8s.io/kubernetes/test/utils/image"
|
||||
admissionapi "k8s.io/pod-security-admission/api"
|
||||
|
||||
@ -69,11 +67,6 @@ var _ = SIGDescribe("Ephemeral Containers [NodeConformance]", func() {
|
||||
},
|
||||
}
|
||||
err := podClient.AddEphemeralContainerSync(pod, ec, time.Minute)
|
||||
// BEGIN TODO: Remove when EphemeralContainers feature gate is retired.
|
||||
if apierrors.IsNotFound(err) {
|
||||
e2eskipper.Skipf("Skipping test because EphemeralContainers feature disabled (error: %q)", err)
|
||||
}
|
||||
// END TODO: Remove when EphemeralContainers feature gate is retired.
|
||||
framework.ExpectNoError(err, "Failed to patch ephemeral containers in pod %q", format.Pod(pod))
|
||||
|
||||
ginkgo.By("checking pod container endpoints")
|
||||
|
@ -50,7 +50,6 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/uuid"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/client-go/dynamic"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
@ -58,7 +57,6 @@ import (
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
watchtools "k8s.io/client-go/tools/watch"
|
||||
"k8s.io/component-base/featuregate"
|
||||
testutils "k8s.io/kubernetes/test/utils"
|
||||
imageutils "k8s.io/kubernetes/test/utils/image"
|
||||
uexec "k8s.io/utils/exec"
|
||||
@ -776,8 +774,6 @@ func (f *Framework) testContainerOutputMatcher(scenarioName string,
|
||||
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
|
||||
@ -790,11 +786,7 @@ const (
|
||||
// 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
|
||||
return AllContainers
|
||||
}
|
||||
|
||||
// ContainerVisitor is called with each container spec, and returns true
|
||||
|
@ -609,12 +609,6 @@ func testVolumeClient(f *framework.Framework, config TestConfig, fsGroup *int64,
|
||||
ec.Name = "volume-ephemeral-container"
|
||||
err = f.PodClient().AddEphemeralContainerSync(clientPod, ec, timeouts.PodStart)
|
||||
// The API server will return NotFound for the subresource when the feature is disabled
|
||||
// BEGIN TODO: remove after EphemeralContainers feature gate is retired
|
||||
if apierrors.IsNotFound(err) {
|
||||
framework.Logf("Skipping ephemeral container re-test because feature is disabled (error: %q)", err)
|
||||
return
|
||||
}
|
||||
// END TODO: remove after EphemeralContainers feature gate is retired
|
||||
framework.ExpectNoError(err, "failed to add ephemeral container for re-test")
|
||||
testVolumeContent(f, clientPod, ec.Name, fsGroup, fsType, tests)
|
||||
}
|
||||
|
@ -491,7 +491,7 @@ func testWebhookAdmission(t *testing.T, watchCache bool) {
|
||||
// force enable all resources so we can check storage.
|
||||
"--runtime-config=api/all=true",
|
||||
// enable feature-gates that protect resources to check their storage, too.
|
||||
"--feature-gates=EphemeralContainers=true",
|
||||
// e.g. "--feature-gates=EphemeralContainers=true",
|
||||
}, etcdConfig)
|
||||
defer server.TearDownFn()
|
||||
|
||||
|
@ -23,15 +23,11 @@ import (
|
||||
"testing"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
typedv1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/test/integration"
|
||||
"k8s.io/kubernetes/test/integration/framework"
|
||||
)
|
||||
@ -190,8 +186,6 @@ func TestPodReadOnlyFilesystem(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPodCreateEphemeralContainers(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)()
|
||||
|
||||
// Disable ServiceAccount admission plugin as we don't have serviceaccount controller running.
|
||||
server := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--disable-admission-plugins=ServiceAccount"}, framework.SharedEtcd())
|
||||
defer server.TearDownFn()
|
||||
@ -261,8 +255,6 @@ func setUpEphemeralContainers(podsClient typedv1.PodInterface, pod *v1.Pod, cont
|
||||
}
|
||||
|
||||
func TestPodPatchEphemeralContainers(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)()
|
||||
|
||||
// Disable ServiceAccount admission plugin as we don't have serviceaccount controller running.
|
||||
server := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--disable-admission-plugins=ServiceAccount"}, framework.SharedEtcd())
|
||||
defer server.TearDownFn()
|
||||
@ -494,8 +486,6 @@ func TestPodPatchEphemeralContainers(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPodUpdateEphemeralContainers(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, true)()
|
||||
|
||||
// Disable ServiceAccount admission plugin as we don't have serviceaccount controller running.
|
||||
server := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--disable-admission-plugins=ServiceAccount"}, framework.SharedEtcd())
|
||||
defer server.TearDownFn()
|
||||
@ -684,61 +674,3 @@ func TestPodUpdateEphemeralContainers(t *testing.T) {
|
||||
integration.DeletePodOrErrorf(t, client, ns.Name, pod.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// TestPodEphemeralContainersDisabled tests that the API server returns a 404 when the feature is disabled (because the subresource won't exist).
|
||||
// This validates that the feature gate is working, but kubectl also uses the 404 to guess that the feature is disabled on the server.
|
||||
func TestPodEphemeralContainersDisabled(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EphemeralContainers, false)()
|
||||
|
||||
// Disable ServiceAccount admission plugin as we don't have serviceaccount controller running.
|
||||
server := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--disable-admission-plugins=ServiceAccount"}, framework.SharedEtcd())
|
||||
defer server.TearDownFn()
|
||||
|
||||
client := clientset.NewForConfigOrDie(server.ClientConfig)
|
||||
|
||||
ns := framework.CreateNamespaceOrDie(client, "pod-ephemeral-containers-disabled", t)
|
||||
defer framework.DeleteNamespaceOrDie(client, ns, t)
|
||||
|
||||
pod := &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "ephemeral-container-pod",
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: "fake-name",
|
||||
Image: "fakeimage",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
pod, err := setUpEphemeralContainers(client.CoreV1().Pods(ns.Name), pod, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer integration.DeletePodOrErrorf(t, client, ns.Name, pod.Name)
|
||||
|
||||
pod.Spec.EphemeralContainers = append(pod.Spec.EphemeralContainers, v1.EphemeralContainer{
|
||||
EphemeralContainerCommon: v1.EphemeralContainerCommon{
|
||||
Name: "debugger",
|
||||
Image: "debugimage",
|
||||
ImagePullPolicy: "Always",
|
||||
TerminationMessagePolicy: "File",
|
||||
},
|
||||
})
|
||||
|
||||
if _, err = client.CoreV1().Pods(ns.Name).UpdateEphemeralContainers(context.TODO(), pod.Name, pod, metav1.UpdateOptions{}); err == nil {
|
||||
t.Fatalf("got nil error when updating ephemeral containers with feature disabled, wanted %q", metav1.StatusReasonNotFound)
|
||||
}
|
||||
|
||||
se, ok := err.(*errors.StatusError)
|
||||
if !ok {
|
||||
t.Fatalf("got error %#v, expected StatusError", err)
|
||||
}
|
||||
if se.ErrStatus.Reason != metav1.StatusReasonNotFound {
|
||||
t.Errorf("got error reason %q when updating ephemeral containers with feature disabled, want %q: %#v", se.ErrStatus.Reason, metav1.StatusReasonNotFound, se)
|
||||
}
|
||||
if se.ErrStatus.Details.Name != "" {
|
||||
t.Errorf("got error details with name %q, want %q: %#v", se.ErrStatus.Details.Name, "", se)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user