Add ImageVolumeSource API

Adding the required Kubernetes API so that the kubelet can start using
it. This patch also adds the corresponding alpha feature gate as
outlined in KEP 4639.

Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
This commit is contained in:
Sascha Grunert
2024-06-24 10:34:43 +02:00
parent ad72be434d
commit f7ca3131e0
86 changed files with 2395 additions and 1167 deletions

View File

@@ -165,6 +165,7 @@ func testWorkloadDefaults(t *testing.T, featuresEnabled bool) {
".Spec.Volumes[0].VolumeSource.Ephemeral.VolumeClaimTemplate.Spec.VolumeMode": `"Filesystem"`,
".Spec.Volumes[0].VolumeSource.HostPath.Type": `""`,
".Spec.Volumes[0].VolumeSource.ISCSI.ISCSIInterface": `"default"`,
".Spec.Volumes[0].VolumeSource.Image.PullPolicy": `"IfNotPresent"`,
".Spec.Volumes[0].VolumeSource.Projected.DefaultMode": `420`,
".Spec.Volumes[0].VolumeSource.Projected.Sources[0].DownwardAPI.Items[0].FieldRef.APIVersion": `"v1"`,
".Spec.Volumes[0].VolumeSource.Projected.Sources[0].ServiceAccountToken.ExpirationSeconds": `3600`,
@@ -175,6 +176,9 @@ func testWorkloadDefaults(t *testing.T, featuresEnabled bool) {
".Spec.Volumes[0].VolumeSource.ScaleIO.StorageMode": `"ThinProvisioned"`,
".Spec.Volumes[0].VolumeSource.Secret.DefaultMode": `420`,
}
if !featuresEnabled {
delete(expectedDefaults, ".Spec.Volumes[0].VolumeSource.Image.PullPolicy")
}
t.Run("empty PodTemplateSpec", func(t *testing.T) {
rc := &v1.ReplicationController{Spec: v1.ReplicationControllerSpec{Template: &v1.PodTemplateSpec{}}}
template := rc.Spec.Template
@@ -353,6 +357,7 @@ func testPodDefaults(t *testing.T, featuresEnabled bool) {
".Spec.Volumes[0].VolumeSource.Ephemeral.VolumeClaimTemplate.Spec.VolumeMode": `"Filesystem"`,
".Spec.Volumes[0].VolumeSource.HostPath.Type": `""`,
".Spec.Volumes[0].VolumeSource.ISCSI.ISCSIInterface": `"default"`,
".Spec.Volumes[0].VolumeSource.Image.PullPolicy": `"IfNotPresent"`,
".Spec.Volumes[0].VolumeSource.Projected.DefaultMode": `420`,
".Spec.Volumes[0].VolumeSource.Projected.Sources[0].DownwardAPI.Items[0].FieldRef.APIVersion": `"v1"`,
".Spec.Volumes[0].VolumeSource.Projected.Sources[0].ServiceAccountToken.ExpirationSeconds": `3600`,
@@ -363,6 +368,9 @@ func testPodDefaults(t *testing.T, featuresEnabled bool) {
".Spec.Volumes[0].VolumeSource.ScaleIO.StorageMode": `"ThinProvisioned"`,
".Spec.Volumes[0].VolumeSource.Secret.DefaultMode": `420`,
}
if !featuresEnabled {
delete(expectedDefaults, ".Spec.Volumes[0].VolumeSource.Image.PullPolicy")
}
defaults := detectDefaults(t, pod, reflect.ValueOf(pod))
if !reflect.DeepEqual(expectedDefaults, defaults) {
t.Errorf("Defaults for PodSpec changed. This can cause spurious restarts of containers on API server upgrade.")
@@ -2306,3 +2314,34 @@ func TestSetDefaultResizePolicy(t *testing.T) {
})
}
}
func TestSetDefaults_Volume(t *testing.T) {
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ImageVolume, true)
for desc, tc := range map[string]struct {
given, expected *v1.Volume
}{
"defaults to emptyDir": {
given: &v1.Volume{},
expected: &v1.Volume{VolumeSource: v1.VolumeSource{EmptyDir: &v1.EmptyDirVolumeSource{}}},
},
"default image volume source pull policy is IfNotPresent": {
given: &v1.Volume{VolumeSource: v1.VolumeSource{Image: &v1.ImageVolumeSource{Reference: "image:v1"}}},
expected: &v1.Volume{VolumeSource: v1.VolumeSource{Image: &v1.ImageVolumeSource{Reference: "image:v1", PullPolicy: v1.PullIfNotPresent}}},
},
"default image volume source pull policy Always if 'latest' tag is used": {
given: &v1.Volume{VolumeSource: v1.VolumeSource{Image: &v1.ImageVolumeSource{Reference: "image:latest"}}},
expected: &v1.Volume{VolumeSource: v1.VolumeSource{Image: &v1.ImageVolumeSource{Reference: "image:latest", PullPolicy: v1.PullAlways}}},
},
"default image volume source pull policy Always if no tag is used": {
given: &v1.Volume{VolumeSource: v1.VolumeSource{Image: &v1.ImageVolumeSource{Reference: "image"}}},
expected: &v1.Volume{VolumeSource: v1.VolumeSource{Image: &v1.ImageVolumeSource{Reference: "image", PullPolicy: v1.PullAlways}}},
},
} {
t.Run(desc, func(t *testing.T) {
corev1.SetDefaults_Volume(tc.given)
if !cmp.Equal(tc.given, tc.expected) {
t.Errorf("expected volume %+v, but got %+v", tc.expected, tc.given)
}
})
}
}