2017-10-12 23:39:14 +00:00
|
|
|
|
/*
|
|
|
|
|
Copyright 2016 The Kubernetes Authors.
|
|
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
|
limitations under the License.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package common
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"os"
|
|
|
|
|
"path"
|
|
|
|
|
|
|
|
|
|
. "github.com/onsi/ginkgo"
|
|
|
|
|
. "github.com/onsi/gomega"
|
|
|
|
|
"k8s.io/api/core/v1"
|
|
|
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
|
|
|
"k8s.io/apimachinery/pkg/util/uuid"
|
|
|
|
|
"k8s.io/kubernetes/test/e2e/framework"
|
2018-08-07 01:18:35 +00:00
|
|
|
|
imageutils "k8s.io/kubernetes/test/utils/image"
|
2017-10-12 23:39:14 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var _ = Describe("[sig-storage] ConfigMap", func() {
|
|
|
|
|
f := framework.NewDefaultFramework("configmap")
|
|
|
|
|
|
2017-11-01 15:58:56 +00:00
|
|
|
|
/*
|
2018-02-27 22:57:56 +00:00
|
|
|
|
Release : v1.9
|
|
|
|
|
Testname: ConfigMap Volume, without mapping
|
|
|
|
|
Description: Create a ConfigMap, create a Pod that mounts a volume and populates the volume with data stored in the ConfigMap. The ConfigMap that is created MUST be accessible to read from the newly created Pod using the volume mount. The data content of the file MUST be readable and verified and file modes MUST default to 0x644.
|
2017-11-01 15:58:56 +00:00
|
|
|
|
*/
|
2018-05-22 01:09:33 +00:00
|
|
|
|
framework.ConformanceIt("should be consumable from pods in volume [NodeConformance]", func() {
|
2017-10-12 23:39:14 +00:00
|
|
|
|
doConfigMapE2EWithoutMappings(f, 0, 0, nil)
|
|
|
|
|
})
|
|
|
|
|
|
2017-11-01 15:58:56 +00:00
|
|
|
|
/*
|
2018-02-27 22:57:56 +00:00
|
|
|
|
Release : v1.9
|
|
|
|
|
Testname: ConfigMap Volume, without mapping, volume mode set
|
|
|
|
|
Description: Create a ConfigMap, create a Pod that mounts a volume and populates the volume with data stored in the ConfigMap. File mode is changed to a custom value of '0x400'. The ConfigMap that is created MUST be accessible to read from the newly created Pod using the volume mount. The data content of the file MUST be readable and verified and file modes MUST be set to the custom value of ‘0x400’
|
2017-11-01 15:58:56 +00:00
|
|
|
|
*/
|
2018-05-22 01:09:33 +00:00
|
|
|
|
framework.ConformanceIt("should be consumable from pods in volume with defaultMode set [NodeConformance]", func() {
|
2017-10-12 23:39:14 +00:00
|
|
|
|
defaultMode := int32(0400)
|
|
|
|
|
doConfigMapE2EWithoutMappings(f, 0, 0, &defaultMode)
|
|
|
|
|
})
|
|
|
|
|
|
2018-05-22 04:28:42 +00:00
|
|
|
|
It("should be consumable from pods in volume as non-root with defaultMode and fsGroup set [NodeFeature:FSGroup]", func() {
|
2017-10-12 23:39:14 +00:00
|
|
|
|
defaultMode := int32(0440) /* setting fsGroup sets mode to at least 440 */
|
|
|
|
|
doConfigMapE2EWithoutMappings(f, 1000, 1001, &defaultMode)
|
|
|
|
|
})
|
|
|
|
|
|
2017-11-01 15:58:56 +00:00
|
|
|
|
/*
|
2018-02-27 22:57:56 +00:00
|
|
|
|
Release : v1.9
|
|
|
|
|
Testname: ConfigMap Volume, without mapping, non-root user
|
|
|
|
|
Description: Create a ConfigMap, create a Pod that mounts a volume and populates the volume with data stored in the ConfigMap. Pod is run as a non-root user with uid=1000. The ConfigMap that is created MUST be accessible to read from the newly created Pod using the volume mount. The file on the volume MUST have file mode set to default value of 0x644.
|
2017-11-01 15:58:56 +00:00
|
|
|
|
*/
|
2018-05-22 01:09:33 +00:00
|
|
|
|
framework.ConformanceIt("should be consumable from pods in volume as non-root [NodeConformance]", func() {
|
2017-10-12 23:39:14 +00:00
|
|
|
|
doConfigMapE2EWithoutMappings(f, 1000, 0, nil)
|
|
|
|
|
})
|
|
|
|
|
|
2018-05-22 04:28:42 +00:00
|
|
|
|
It("should be consumable from pods in volume as non-root with FSGroup [NodeFeature:FSGroup]", func() {
|
2017-10-12 23:39:14 +00:00
|
|
|
|
doConfigMapE2EWithoutMappings(f, 1000, 1001, nil)
|
|
|
|
|
})
|
|
|
|
|
|
2017-11-01 15:58:56 +00:00
|
|
|
|
/*
|
2018-02-27 22:57:56 +00:00
|
|
|
|
Release : v1.9
|
|
|
|
|
Testname: ConfigMap Volume, with mapping
|
|
|
|
|
Description: Create a ConfigMap, create a Pod that mounts a volume and populates the volume with data stored in the ConfigMap. Files are mapped to a path in the volume. The ConfigMap that is created MUST be accessible to read from the newly created Pod using the volume mount. The data content of the file MUST be readable and verified and file modes MUST default to 0x644.
|
2017-11-01 15:58:56 +00:00
|
|
|
|
*/
|
2018-05-22 01:09:33 +00:00
|
|
|
|
framework.ConformanceIt("should be consumable from pods in volume with mappings [NodeConformance]", func() {
|
2017-10-12 23:39:14 +00:00
|
|
|
|
doConfigMapE2EWithMappings(f, 0, 0, nil)
|
|
|
|
|
})
|
|
|
|
|
|
2017-11-01 15:58:56 +00:00
|
|
|
|
/*
|
2018-02-27 22:57:56 +00:00
|
|
|
|
Release : v1.9
|
|
|
|
|
Testname: ConfigMap Volume, with mapping, volume mode set
|
|
|
|
|
Description: Create a ConfigMap, create a Pod that mounts a volume and populates the volume with data stored in the ConfigMap. Files are mapped to a path in the volume. File mode is changed to a custom value of '0x400'. The ConfigMap that is created MUST be accessible to read from the newly created Pod using the volume mount. The data content of the file MUST be readable and verified and file modes MUST be set to the custom value of ‘0x400’
|
2017-11-01 15:58:56 +00:00
|
|
|
|
*/
|
2018-05-22 01:09:33 +00:00
|
|
|
|
framework.ConformanceIt("should be consumable from pods in volume with mappings and Item mode set [NodeConformance]", func() {
|
2017-10-12 23:39:14 +00:00
|
|
|
|
mode := int32(0400)
|
|
|
|
|
doConfigMapE2EWithMappings(f, 0, 0, &mode)
|
|
|
|
|
})
|
|
|
|
|
|
2017-11-01 15:58:56 +00:00
|
|
|
|
/*
|
2018-02-27 22:57:56 +00:00
|
|
|
|
Release : v1.9
|
|
|
|
|
Testname: ConfigMap Volume, with mapping, non-root user
|
|
|
|
|
Description: Create a ConfigMap, create a Pod that mounts a volume and populates the volume with data stored in the ConfigMap. Files are mapped to a path in the volume. Pod is run as a non-root user with uid=1000. The ConfigMap that is created MUST be accessible to read from the newly created Pod using the volume mount. The file on the volume MUST have file mode set to default value of 0x644.
|
2017-11-01 15:58:56 +00:00
|
|
|
|
*/
|
2018-05-22 01:09:33 +00:00
|
|
|
|
framework.ConformanceIt("should be consumable from pods in volume with mappings as non-root [NodeConformance]", func() {
|
2017-10-12 23:39:14 +00:00
|
|
|
|
doConfigMapE2EWithMappings(f, 1000, 0, nil)
|
|
|
|
|
})
|
|
|
|
|
|
2018-05-22 04:28:42 +00:00
|
|
|
|
It("should be consumable from pods in volume with mappings as non-root with FSGroup [NodeFeature:FSGroup]", func() {
|
2017-10-12 23:39:14 +00:00
|
|
|
|
doConfigMapE2EWithMappings(f, 1000, 1001, nil)
|
|
|
|
|
})
|
|
|
|
|
|
2017-11-01 15:58:56 +00:00
|
|
|
|
/*
|
2018-02-27 22:57:56 +00:00
|
|
|
|
Release : v1.9
|
|
|
|
|
Testname: ConfigMap Volume, update
|
|
|
|
|
Description: The ConfigMap that is created MUST be accessible to read from the newly created Pod using the volume mount that is mapped to custom path in the Pod. When the ConfigMap is updated the change to the config map MUST be verified by reading the content from the mounted file in the Pod.
|
2017-11-01 15:58:56 +00:00
|
|
|
|
*/
|
2018-05-22 01:09:33 +00:00
|
|
|
|
framework.ConformanceIt("updates should be reflected in volume [NodeConformance]", func() {
|
2017-10-12 23:39:14 +00:00
|
|
|
|
podLogTimeout := framework.GetPodSecretUpdateTimeout(f.ClientSet)
|
|
|
|
|
containerTimeoutArg := fmt.Sprintf("--retry_time=%v", int(podLogTimeout.Seconds()))
|
|
|
|
|
|
|
|
|
|
name := "configmap-test-upd-" + string(uuid.NewUUID())
|
|
|
|
|
volumeName := "configmap-volume"
|
|
|
|
|
volumeMountPath := "/etc/configmap-volume"
|
|
|
|
|
containerName := "configmap-volume-test"
|
|
|
|
|
|
|
|
|
|
configMap := &v1.ConfigMap{
|
|
|
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
|
|
|
Namespace: f.Namespace.Name,
|
|
|
|
|
Name: name,
|
|
|
|
|
},
|
|
|
|
|
Data: map[string]string{
|
|
|
|
|
"data-1": "value-1",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
By(fmt.Sprintf("Creating configMap with name %s", configMap.Name))
|
|
|
|
|
var err error
|
2017-10-25 15:54:32 +00:00
|
|
|
|
if configMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(configMap); err != nil {
|
2017-10-12 23:39:14 +00:00
|
|
|
|
framework.Failf("unable to create test configMap %s: %v", configMap.Name, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pod := &v1.Pod{
|
|
|
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
|
|
|
Name: "pod-configmaps-" + string(uuid.NewUUID()),
|
|
|
|
|
},
|
|
|
|
|
Spec: v1.PodSpec{
|
|
|
|
|
Volumes: []v1.Volume{
|
|
|
|
|
{
|
|
|
|
|
Name: volumeName,
|
|
|
|
|
VolumeSource: v1.VolumeSource{
|
|
|
|
|
ConfigMap: &v1.ConfigMapVolumeSource{
|
|
|
|
|
LocalObjectReference: v1.LocalObjectReference{
|
|
|
|
|
Name: name,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
Containers: []v1.Container{
|
|
|
|
|
{
|
|
|
|
|
Name: containerName,
|
2018-08-14 13:37:40 +00:00
|
|
|
|
Image: imageutils.GetE2EImage(imageutils.Mounttest),
|
2017-10-12 23:39:14 +00:00
|
|
|
|
Command: []string{"/mounttest", "--break_on_expected_content=false", containerTimeoutArg, "--file_content_in_loop=/etc/configmap-volume/data-1"},
|
|
|
|
|
VolumeMounts: []v1.VolumeMount{
|
|
|
|
|
{
|
|
|
|
|
Name: volumeName,
|
|
|
|
|
MountPath: volumeMountPath,
|
|
|
|
|
ReadOnly: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
RestartPolicy: v1.RestartPolicyNever,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
By("Creating the pod")
|
|
|
|
|
f.PodClient().CreateSync(pod)
|
|
|
|
|
|
|
|
|
|
pollLogs := func() (string, error) {
|
|
|
|
|
return framework.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, containerName)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Eventually(pollLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("value-1"))
|
|
|
|
|
|
|
|
|
|
By(fmt.Sprintf("Updating configmap %v", configMap.Name))
|
|
|
|
|
configMap.ResourceVersion = "" // to force update
|
|
|
|
|
configMap.Data["data-1"] = "value-2"
|
2017-10-25 15:54:32 +00:00
|
|
|
|
_, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Update(configMap)
|
2017-10-12 23:39:14 +00:00
|
|
|
|
Expect(err).NotTo(HaveOccurred(), "Failed to update configmap %q in namespace %q", configMap.Name, f.Namespace.Name)
|
|
|
|
|
|
|
|
|
|
By("waiting to observe update in volume")
|
|
|
|
|
Eventually(pollLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("value-2"))
|
|
|
|
|
})
|
|
|
|
|
|
2018-08-07 03:48:31 +00:00
|
|
|
|
/*
|
|
|
|
|
Release: v1.12
|
|
|
|
|
Testname: ConfigMap Volume, text data, binary data
|
|
|
|
|
Description: The ConfigMap that is created with text data and binary data MUST be accessible to read from the newly created Pod using the volume mount that is mapped to custom path in the Pod. ConfigMap's text data and binary data MUST be verified by reading the content from the mounted files in the Pod.
|
|
|
|
|
*/
|
|
|
|
|
framework.ConformanceIt("binary data should be reflected in volume [NodeConformance]", func() {
|
2018-01-11 02:12:28 +00:00
|
|
|
|
podLogTimeout := framework.GetPodSecretUpdateTimeout(f.ClientSet)
|
|
|
|
|
containerTimeoutArg := fmt.Sprintf("--retry_time=%v", int(podLogTimeout.Seconds()))
|
|
|
|
|
|
|
|
|
|
name := "configmap-test-upd-" + string(uuid.NewUUID())
|
|
|
|
|
volumeName := "configmap-volume"
|
|
|
|
|
volumeMountPath := "/etc/configmap-volume"
|
|
|
|
|
containerName1 := "configmap-volume-data-test"
|
|
|
|
|
containerName2 := "configmap-volume-binary-test"
|
|
|
|
|
|
|
|
|
|
configMap := &v1.ConfigMap{
|
|
|
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
|
|
|
Namespace: f.Namespace.Name,
|
|
|
|
|
Name: name,
|
|
|
|
|
},
|
|
|
|
|
Data: map[string]string{
|
|
|
|
|
"data-1": "value-1",
|
|
|
|
|
},
|
|
|
|
|
BinaryData: map[string][]byte{
|
|
|
|
|
"dump.bin": {0xde, 0xca, 0xfe, 0xba, 0xd0, 0xfe, 0xff},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
By(fmt.Sprintf("Creating configMap with name %s", configMap.Name))
|
|
|
|
|
var err error
|
|
|
|
|
if configMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(configMap); err != nil {
|
|
|
|
|
framework.Failf("unable to create test configMap %s: %v", configMap.Name, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pod := &v1.Pod{
|
|
|
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
|
|
|
Name: "pod-configmaps-" + string(uuid.NewUUID()),
|
|
|
|
|
},
|
|
|
|
|
Spec: v1.PodSpec{
|
|
|
|
|
Volumes: []v1.Volume{
|
|
|
|
|
{
|
|
|
|
|
Name: volumeName,
|
|
|
|
|
VolumeSource: v1.VolumeSource{
|
|
|
|
|
ConfigMap: &v1.ConfigMapVolumeSource{
|
|
|
|
|
LocalObjectReference: v1.LocalObjectReference{
|
|
|
|
|
Name: name,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
Containers: []v1.Container{
|
|
|
|
|
{
|
|
|
|
|
Name: containerName1,
|
2018-08-14 13:37:40 +00:00
|
|
|
|
Image: imageutils.GetE2EImage(imageutils.Mounttest),
|
2018-01-11 02:12:28 +00:00
|
|
|
|
Command: []string{"/mounttest", "--break_on_expected_content=false", containerTimeoutArg, "--file_content_in_loop=/etc/configmap-volume/data-1"},
|
|
|
|
|
VolumeMounts: []v1.VolumeMount{
|
|
|
|
|
{
|
|
|
|
|
Name: volumeName,
|
|
|
|
|
MountPath: volumeMountPath,
|
|
|
|
|
ReadOnly: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Name: containerName2,
|
2018-08-07 01:18:35 +00:00
|
|
|
|
Image: imageutils.GetE2EImage(imageutils.BusyBox),
|
2018-01-11 02:12:28 +00:00
|
|
|
|
Command: []string{"hexdump", "-C", "/etc/configmap-volume/dump.bin"},
|
|
|
|
|
VolumeMounts: []v1.VolumeMount{
|
|
|
|
|
{
|
|
|
|
|
Name: volumeName,
|
|
|
|
|
MountPath: volumeMountPath,
|
|
|
|
|
ReadOnly: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
RestartPolicy: v1.RestartPolicyNever,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
By("Creating the pod")
|
|
|
|
|
f.PodClient().CreateSync(pod)
|
|
|
|
|
|
|
|
|
|
pollLogs1 := func() (string, error) {
|
|
|
|
|
return framework.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, containerName1)
|
|
|
|
|
}
|
|
|
|
|
pollLogs2 := func() (string, error) {
|
|
|
|
|
return framework.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, containerName2)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
By("Waiting for pod with text data")
|
|
|
|
|
Eventually(pollLogs1, podLogTimeout, framework.Poll).Should(ContainSubstring("value-1"))
|
|
|
|
|
By("Waiting for pod with binary data")
|
|
|
|
|
Eventually(pollLogs2, podLogTimeout, framework.Poll).Should(ContainSubstring("de ca fe ba d0 fe ff"))
|
|
|
|
|
})
|
|
|
|
|
|
2017-11-01 15:58:56 +00:00
|
|
|
|
/*
|
2018-02-27 22:57:56 +00:00
|
|
|
|
Release : v1.9
|
|
|
|
|
Testname: ConfigMap Volume, create, update and delete
|
|
|
|
|
Description: The ConfigMap that is created MUST be accessible to read from the newly created Pod using the volume mount that is mapped to custom path in the Pod. When the config map is updated the change to the config map MUST be verified by reading the content from the mounted file in the Pod. Also when the item(file) is deleted from the map that MUST result in a error reading that item(file).
|
2017-11-01 15:58:56 +00:00
|
|
|
|
*/
|
2018-05-22 01:09:33 +00:00
|
|
|
|
framework.ConformanceIt("optional updates should be reflected in volume [NodeConformance]", func() {
|
2017-10-12 23:39:14 +00:00
|
|
|
|
podLogTimeout := framework.GetPodSecretUpdateTimeout(f.ClientSet)
|
|
|
|
|
containerTimeoutArg := fmt.Sprintf("--retry_time=%v", int(podLogTimeout.Seconds()))
|
|
|
|
|
trueVal := true
|
|
|
|
|
volumeMountPath := "/etc/configmap-volumes"
|
|
|
|
|
|
|
|
|
|
deleteName := "cm-test-opt-del-" + string(uuid.NewUUID())
|
|
|
|
|
deleteContainerName := "delcm-volume-test"
|
|
|
|
|
deleteVolumeName := "deletecm-volume"
|
|
|
|
|
deleteConfigMap := &v1.ConfigMap{
|
|
|
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
|
|
|
Namespace: f.Namespace.Name,
|
|
|
|
|
Name: deleteName,
|
|
|
|
|
},
|
|
|
|
|
Data: map[string]string{
|
|
|
|
|
"data-1": "value-1",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
updateName := "cm-test-opt-upd-" + string(uuid.NewUUID())
|
|
|
|
|
updateContainerName := "updcm-volume-test"
|
|
|
|
|
updateVolumeName := "updatecm-volume"
|
|
|
|
|
updateConfigMap := &v1.ConfigMap{
|
|
|
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
|
|
|
Namespace: f.Namespace.Name,
|
|
|
|
|
Name: updateName,
|
|
|
|
|
},
|
|
|
|
|
Data: map[string]string{
|
|
|
|
|
"data-1": "value-1",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
createName := "cm-test-opt-create-" + string(uuid.NewUUID())
|
|
|
|
|
createContainerName := "createcm-volume-test"
|
|
|
|
|
createVolumeName := "createcm-volume"
|
|
|
|
|
createConfigMap := &v1.ConfigMap{
|
|
|
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
|
|
|
Namespace: f.Namespace.Name,
|
|
|
|
|
Name: createName,
|
|
|
|
|
},
|
|
|
|
|
Data: map[string]string{
|
|
|
|
|
"data-1": "value-1",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
By(fmt.Sprintf("Creating configMap with name %s", deleteConfigMap.Name))
|
|
|
|
|
var err error
|
2017-10-25 15:54:32 +00:00
|
|
|
|
if deleteConfigMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(deleteConfigMap); err != nil {
|
2017-10-12 23:39:14 +00:00
|
|
|
|
framework.Failf("unable to create test configMap %s: %v", deleteConfigMap.Name, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
By(fmt.Sprintf("Creating configMap with name %s", updateConfigMap.Name))
|
2017-10-25 15:54:32 +00:00
|
|
|
|
if updateConfigMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(updateConfigMap); err != nil {
|
2017-10-12 23:39:14 +00:00
|
|
|
|
framework.Failf("unable to create test configMap %s: %v", updateConfigMap.Name, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pod := &v1.Pod{
|
|
|
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
|
|
|
Name: "pod-configmaps-" + string(uuid.NewUUID()),
|
|
|
|
|
},
|
|
|
|
|
Spec: v1.PodSpec{
|
|
|
|
|
Volumes: []v1.Volume{
|
|
|
|
|
{
|
|
|
|
|
Name: deleteVolumeName,
|
|
|
|
|
VolumeSource: v1.VolumeSource{
|
|
|
|
|
ConfigMap: &v1.ConfigMapVolumeSource{
|
|
|
|
|
LocalObjectReference: v1.LocalObjectReference{
|
|
|
|
|
Name: deleteName,
|
|
|
|
|
},
|
|
|
|
|
Optional: &trueVal,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Name: updateVolumeName,
|
|
|
|
|
VolumeSource: v1.VolumeSource{
|
|
|
|
|
ConfigMap: &v1.ConfigMapVolumeSource{
|
|
|
|
|
LocalObjectReference: v1.LocalObjectReference{
|
|
|
|
|
Name: updateName,
|
|
|
|
|
},
|
|
|
|
|
Optional: &trueVal,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Name: createVolumeName,
|
|
|
|
|
VolumeSource: v1.VolumeSource{
|
|
|
|
|
ConfigMap: &v1.ConfigMapVolumeSource{
|
|
|
|
|
LocalObjectReference: v1.LocalObjectReference{
|
|
|
|
|
Name: createName,
|
|
|
|
|
},
|
|
|
|
|
Optional: &trueVal,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
Containers: []v1.Container{
|
|
|
|
|
{
|
|
|
|
|
Name: deleteContainerName,
|
2018-08-14 13:37:40 +00:00
|
|
|
|
Image: imageutils.GetE2EImage(imageutils.Mounttest),
|
2017-10-12 23:39:14 +00:00
|
|
|
|
Command: []string{"/mounttest", "--break_on_expected_content=false", containerTimeoutArg, "--file_content_in_loop=/etc/configmap-volumes/delete/data-1"},
|
|
|
|
|
VolumeMounts: []v1.VolumeMount{
|
|
|
|
|
{
|
|
|
|
|
Name: deleteVolumeName,
|
|
|
|
|
MountPath: path.Join(volumeMountPath, "delete"),
|
|
|
|
|
ReadOnly: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Name: updateContainerName,
|
2018-08-14 13:37:40 +00:00
|
|
|
|
Image: imageutils.GetE2EImage(imageutils.Mounttest),
|
2017-10-12 23:39:14 +00:00
|
|
|
|
Command: []string{"/mounttest", "--break_on_expected_content=false", containerTimeoutArg, "--file_content_in_loop=/etc/configmap-volumes/update/data-3"},
|
|
|
|
|
VolumeMounts: []v1.VolumeMount{
|
|
|
|
|
{
|
|
|
|
|
Name: updateVolumeName,
|
|
|
|
|
MountPath: path.Join(volumeMountPath, "update"),
|
|
|
|
|
ReadOnly: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Name: createContainerName,
|
2018-08-14 13:37:40 +00:00
|
|
|
|
Image: imageutils.GetE2EImage(imageutils.Mounttest),
|
2017-10-12 23:39:14 +00:00
|
|
|
|
Command: []string{"/mounttest", "--break_on_expected_content=false", containerTimeoutArg, "--file_content_in_loop=/etc/configmap-volumes/create/data-1"},
|
|
|
|
|
VolumeMounts: []v1.VolumeMount{
|
|
|
|
|
{
|
|
|
|
|
Name: createVolumeName,
|
|
|
|
|
MountPath: path.Join(volumeMountPath, "create"),
|
|
|
|
|
ReadOnly: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
RestartPolicy: v1.RestartPolicyNever,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
By("Creating the pod")
|
|
|
|
|
f.PodClient().CreateSync(pod)
|
|
|
|
|
|
|
|
|
|
pollCreateLogs := func() (string, error) {
|
|
|
|
|
return framework.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, createContainerName)
|
|
|
|
|
}
|
|
|
|
|
Eventually(pollCreateLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("Error reading file /etc/configmap-volumes/create/data-1"))
|
|
|
|
|
|
|
|
|
|
pollUpdateLogs := func() (string, error) {
|
|
|
|
|
return framework.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, updateContainerName)
|
|
|
|
|
}
|
|
|
|
|
Eventually(pollUpdateLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("Error reading file /etc/configmap-volumes/update/data-3"))
|
|
|
|
|
|
|
|
|
|
pollDeleteLogs := func() (string, error) {
|
|
|
|
|
return framework.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, deleteContainerName)
|
|
|
|
|
}
|
|
|
|
|
Eventually(pollDeleteLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("value-1"))
|
|
|
|
|
|
|
|
|
|
By(fmt.Sprintf("Deleting configmap %v", deleteConfigMap.Name))
|
2017-10-25 15:54:32 +00:00
|
|
|
|
err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Delete(deleteConfigMap.Name, &metav1.DeleteOptions{})
|
2017-10-12 23:39:14 +00:00
|
|
|
|
Expect(err).NotTo(HaveOccurred(), "Failed to delete configmap %q in namespace %q", deleteConfigMap.Name, f.Namespace.Name)
|
|
|
|
|
|
|
|
|
|
By(fmt.Sprintf("Updating configmap %v", updateConfigMap.Name))
|
|
|
|
|
updateConfigMap.ResourceVersion = "" // to force update
|
|
|
|
|
delete(updateConfigMap.Data, "data-1")
|
|
|
|
|
updateConfigMap.Data["data-3"] = "value-3"
|
2017-10-25 15:54:32 +00:00
|
|
|
|
_, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Update(updateConfigMap)
|
2017-10-12 23:39:14 +00:00
|
|
|
|
Expect(err).NotTo(HaveOccurred(), "Failed to update configmap %q in namespace %q", updateConfigMap.Name, f.Namespace.Name)
|
|
|
|
|
|
|
|
|
|
By(fmt.Sprintf("Creating configMap with name %s", createConfigMap.Name))
|
2017-10-25 15:54:32 +00:00
|
|
|
|
if createConfigMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(createConfigMap); err != nil {
|
2017-10-12 23:39:14 +00:00
|
|
|
|
framework.Failf("unable to create test configMap %s: %v", createConfigMap.Name, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
By("waiting to observe update in volume")
|
|
|
|
|
|
|
|
|
|
Eventually(pollCreateLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("value-1"))
|
|
|
|
|
Eventually(pollUpdateLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("value-3"))
|
|
|
|
|
Eventually(pollDeleteLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("Error reading file /etc/configmap-volumes/delete/data-1"))
|
|
|
|
|
})
|
|
|
|
|
|
2017-11-01 15:58:56 +00:00
|
|
|
|
/*
|
2018-02-27 22:57:56 +00:00
|
|
|
|
Release : v1.9
|
|
|
|
|
Testname: ConfigMap Volume, multiple volume maps
|
|
|
|
|
Description: The ConfigMap that is created MUST be accessible to read from the newly created Pod using the volume mount that is mapped to multiple paths in the Pod. The content MUST be accessible from all the mapped volume mounts.
|
2017-11-01 15:58:56 +00:00
|
|
|
|
*/
|
2018-05-22 01:09:33 +00:00
|
|
|
|
framework.ConformanceIt("should be consumable in multiple volumes in the same pod [NodeConformance]", func() {
|
2017-10-12 23:39:14 +00:00
|
|
|
|
var (
|
|
|
|
|
name = "configmap-test-volume-" + string(uuid.NewUUID())
|
|
|
|
|
volumeName = "configmap-volume"
|
|
|
|
|
volumeMountPath = "/etc/configmap-volume"
|
|
|
|
|
volumeName2 = "configmap-volume-2"
|
|
|
|
|
volumeMountPath2 = "/etc/configmap-volume-2"
|
|
|
|
|
configMap = newConfigMap(f, name)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
By(fmt.Sprintf("Creating configMap with name %s", configMap.Name))
|
|
|
|
|
var err error
|
2017-10-25 15:54:32 +00:00
|
|
|
|
if configMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(configMap); err != nil {
|
2017-10-12 23:39:14 +00:00
|
|
|
|
framework.Failf("unable to create test configMap %s: %v", configMap.Name, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pod := &v1.Pod{
|
|
|
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
|
|
|
Name: "pod-configmaps-" + string(uuid.NewUUID()),
|
|
|
|
|
},
|
|
|
|
|
Spec: v1.PodSpec{
|
|
|
|
|
Volumes: []v1.Volume{
|
|
|
|
|
{
|
|
|
|
|
Name: volumeName,
|
|
|
|
|
VolumeSource: v1.VolumeSource{
|
|
|
|
|
ConfigMap: &v1.ConfigMapVolumeSource{
|
|
|
|
|
LocalObjectReference: v1.LocalObjectReference{
|
|
|
|
|
Name: name,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Name: volumeName2,
|
|
|
|
|
VolumeSource: v1.VolumeSource{
|
|
|
|
|
ConfigMap: &v1.ConfigMapVolumeSource{
|
|
|
|
|
LocalObjectReference: v1.LocalObjectReference{
|
|
|
|
|
Name: name,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
Containers: []v1.Container{
|
|
|
|
|
{
|
|
|
|
|
Name: "configmap-volume-test",
|
2018-08-14 13:37:40 +00:00
|
|
|
|
Image: imageutils.GetE2EImage(imageutils.Mounttest),
|
2017-10-12 23:39:14 +00:00
|
|
|
|
Args: []string{"--file_content=/etc/configmap-volume/data-1"},
|
|
|
|
|
VolumeMounts: []v1.VolumeMount{
|
|
|
|
|
{
|
|
|
|
|
Name: volumeName,
|
|
|
|
|
MountPath: volumeMountPath,
|
|
|
|
|
ReadOnly: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Name: volumeName2,
|
|
|
|
|
MountPath: volumeMountPath2,
|
|
|
|
|
ReadOnly: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
RestartPolicy: v1.RestartPolicyNever,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f.TestContainerOutput("consume configMaps", pod, 0, []string{
|
|
|
|
|
"content of file \"/etc/configmap-volume/data-1\": value-1",
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
func newConfigMap(f *framework.Framework, name string) *v1.ConfigMap {
|
|
|
|
|
return &v1.ConfigMap{
|
|
|
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
|
|
|
Namespace: f.Namespace.Name,
|
|
|
|
|
Name: name,
|
|
|
|
|
},
|
|
|
|
|
Data: map[string]string{
|
|
|
|
|
"data-1": "value-1",
|
|
|
|
|
"data-2": "value-2",
|
|
|
|
|
"data-3": "value-3",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func doConfigMapE2EWithoutMappings(f *framework.Framework, uid, fsGroup int64, defaultMode *int32) {
|
|
|
|
|
userID := int64(uid)
|
|
|
|
|
groupID := int64(fsGroup)
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
name = "configmap-test-volume-" + string(uuid.NewUUID())
|
|
|
|
|
volumeName = "configmap-volume"
|
|
|
|
|
volumeMountPath = "/etc/configmap-volume"
|
|
|
|
|
configMap = newConfigMap(f, name)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
By(fmt.Sprintf("Creating configMap with name %s", configMap.Name))
|
|
|
|
|
var err error
|
2017-10-25 15:54:32 +00:00
|
|
|
|
if configMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(configMap); err != nil {
|
2017-10-12 23:39:14 +00:00
|
|
|
|
framework.Failf("unable to create test configMap %s: %v", configMap.Name, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
one := int64(1)
|
|
|
|
|
pod := &v1.Pod{
|
|
|
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
|
|
|
Name: "pod-configmaps-" + string(uuid.NewUUID()),
|
|
|
|
|
},
|
|
|
|
|
Spec: v1.PodSpec{
|
|
|
|
|
SecurityContext: &v1.PodSecurityContext{},
|
|
|
|
|
Volumes: []v1.Volume{
|
|
|
|
|
{
|
|
|
|
|
Name: volumeName,
|
|
|
|
|
VolumeSource: v1.VolumeSource{
|
|
|
|
|
ConfigMap: &v1.ConfigMapVolumeSource{
|
|
|
|
|
LocalObjectReference: v1.LocalObjectReference{
|
|
|
|
|
Name: name,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
Containers: []v1.Container{
|
|
|
|
|
{
|
|
|
|
|
Name: "configmap-volume-test",
|
2018-08-14 13:37:40 +00:00
|
|
|
|
Image: imageutils.GetE2EImage(imageutils.Mounttest),
|
2017-10-12 23:39:14 +00:00
|
|
|
|
Args: []string{
|
|
|
|
|
"--file_content=/etc/configmap-volume/data-1",
|
|
|
|
|
"--file_mode=/etc/configmap-volume/data-1"},
|
|
|
|
|
VolumeMounts: []v1.VolumeMount{
|
|
|
|
|
{
|
|
|
|
|
Name: volumeName,
|
|
|
|
|
MountPath: volumeMountPath,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
RestartPolicy: v1.RestartPolicyNever,
|
|
|
|
|
TerminationGracePeriodSeconds: &one,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if userID != 0 {
|
|
|
|
|
pod.Spec.SecurityContext.RunAsUser = &userID
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if groupID != 0 {
|
|
|
|
|
pod.Spec.SecurityContext.FSGroup = &groupID
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if defaultMode != nil {
|
|
|
|
|
pod.Spec.Volumes[0].VolumeSource.ConfigMap.DefaultMode = defaultMode
|
|
|
|
|
} else {
|
|
|
|
|
mode := int32(0644)
|
|
|
|
|
defaultMode = &mode
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
modeString := fmt.Sprintf("%v", os.FileMode(*defaultMode))
|
|
|
|
|
output := []string{
|
|
|
|
|
"content of file \"/etc/configmap-volume/data-1\": value-1",
|
|
|
|
|
"mode of file \"/etc/configmap-volume/data-1\": " + modeString,
|
|
|
|
|
}
|
|
|
|
|
f.TestContainerOutput("consume configMaps", pod, 0, output)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func doConfigMapE2EWithMappings(f *framework.Framework, uid, fsGroup int64, itemMode *int32) {
|
|
|
|
|
userID := int64(uid)
|
|
|
|
|
groupID := int64(fsGroup)
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
name = "configmap-test-volume-map-" + string(uuid.NewUUID())
|
|
|
|
|
volumeName = "configmap-volume"
|
|
|
|
|
volumeMountPath = "/etc/configmap-volume"
|
|
|
|
|
configMap = newConfigMap(f, name)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
By(fmt.Sprintf("Creating configMap with name %s", configMap.Name))
|
|
|
|
|
|
|
|
|
|
var err error
|
2017-10-25 15:54:32 +00:00
|
|
|
|
if configMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(configMap); err != nil {
|
2017-10-12 23:39:14 +00:00
|
|
|
|
framework.Failf("unable to create test configMap %s: %v", configMap.Name, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
one := int64(1)
|
|
|
|
|
pod := &v1.Pod{
|
|
|
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
|
|
|
Name: "pod-configmaps-" + string(uuid.NewUUID()),
|
|
|
|
|
},
|
|
|
|
|
Spec: v1.PodSpec{
|
|
|
|
|
SecurityContext: &v1.PodSecurityContext{},
|
|
|
|
|
Volumes: []v1.Volume{
|
|
|
|
|
{
|
|
|
|
|
Name: volumeName,
|
|
|
|
|
VolumeSource: v1.VolumeSource{
|
|
|
|
|
ConfigMap: &v1.ConfigMapVolumeSource{
|
|
|
|
|
LocalObjectReference: v1.LocalObjectReference{
|
|
|
|
|
Name: name,
|
|
|
|
|
},
|
|
|
|
|
Items: []v1.KeyToPath{
|
|
|
|
|
{
|
|
|
|
|
Key: "data-2",
|
|
|
|
|
Path: "path/to/data-2",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
Containers: []v1.Container{
|
|
|
|
|
{
|
|
|
|
|
Name: "configmap-volume-test",
|
2018-08-14 13:37:40 +00:00
|
|
|
|
Image: imageutils.GetE2EImage(imageutils.Mounttest),
|
2017-10-12 23:39:14 +00:00
|
|
|
|
Args: []string{"--file_content=/etc/configmap-volume/path/to/data-2",
|
|
|
|
|
"--file_mode=/etc/configmap-volume/path/to/data-2"},
|
|
|
|
|
VolumeMounts: []v1.VolumeMount{
|
|
|
|
|
{
|
|
|
|
|
Name: volumeName,
|
|
|
|
|
MountPath: volumeMountPath,
|
|
|
|
|
ReadOnly: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
RestartPolicy: v1.RestartPolicyNever,
|
|
|
|
|
TerminationGracePeriodSeconds: &one,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if userID != 0 {
|
|
|
|
|
pod.Spec.SecurityContext.RunAsUser = &userID
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if groupID != 0 {
|
|
|
|
|
pod.Spec.SecurityContext.FSGroup = &groupID
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if itemMode != nil {
|
|
|
|
|
pod.Spec.Volumes[0].VolumeSource.ConfigMap.Items[0].Mode = itemMode
|
|
|
|
|
} else {
|
|
|
|
|
mode := int32(0644)
|
|
|
|
|
itemMode = &mode
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Just check file mode if fsGroup is not set. If fsGroup is set, the
|
|
|
|
|
// final mode is adjusted and we are not testing that case.
|
|
|
|
|
output := []string{
|
|
|
|
|
"content of file \"/etc/configmap-volume/path/to/data-2\": value-2",
|
|
|
|
|
}
|
|
|
|
|
if fsGroup == 0 {
|
|
|
|
|
modeString := fmt.Sprintf("%v", os.FileMode(*itemMode))
|
|
|
|
|
output = append(output, "mode of file \"/etc/configmap-volume/path/to/data-2\": "+modeString)
|
|
|
|
|
}
|
|
|
|
|
f.TestContainerOutput("consume configMaps", pod, 0, output)
|
|
|
|
|
}
|