diff options
author | OpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com> | 2021-12-03 14:54:47 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-03 14:54:47 +0100 |
commit | dd109daa45bafc85487aa2e627202d23b5c76021 (patch) | |
tree | b627ec36853c7cf40b5202c506c367f332c4d31b /pkg | |
parent | 999fe0d89355498c1bc77efb8dfc50c5f0bb0efa (diff) | |
parent | 7d331d35ddf5e511bd474505b675191d3f949dc0 (diff) | |
download | podman-dd109daa45bafc85487aa2e627202d23b5c76021.tar.gz podman-dd109daa45bafc85487aa2e627202d23b5c76021.tar.bz2 podman-dd109daa45bafc85487aa2e627202d23b5c76021.zip |
Merge pull request #12440 from umohnani8/cm
Add support for configmap volumes to play kube
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/domain/infra/abi/play.go | 71 | ||||
-rw-r--r-- | pkg/specgen/generate/kube/kube.go | 12 | ||||
-rw-r--r-- | pkg/specgen/generate/kube/volume.go | 64 |
3 files changed, 119 insertions, 28 deletions
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go index bdf22cf0c..ab52fad64 100644 --- a/pkg/domain/infra/abi/play.go +++ b/pkg/domain/infra/abi/play.go @@ -239,27 +239,6 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY return nil, err } podSpec := entities.PodSpec{PodSpecGen: *p} - volumes, err := kube.InitializeVolumes(podYAML.Spec.Volumes) - if err != nil { - return nil, err - } - - seccompPaths, err := kube.InitializeSeccompPaths(podYAML.ObjectMeta.Annotations, options.SeccompProfileRoot) - if err != nil { - return nil, err - } - - var ctrRestartPolicy string - switch podYAML.Spec.RestartPolicy { - case v1.RestartPolicyAlways: - ctrRestartPolicy = define.RestartPolicyAlways - case v1.RestartPolicyOnFailure: - ctrRestartPolicy = define.RestartPolicyOnFailure - case v1.RestartPolicyNever: - ctrRestartPolicy = define.RestartPolicyNo - default: // Default to Always - ctrRestartPolicy = define.RestartPolicyAlways - } configMapIndex := make(map[string]struct{}) for _, configMap := range configMaps { @@ -284,6 +263,56 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY configMaps = append(configMaps, cm) } + volumes, err := kube.InitializeVolumes(podYAML.Spec.Volumes, configMaps) + if err != nil { + return nil, err + } + + // Go through the volumes and create a podman volume for all volumes that have been + // defined by a configmap + for _, v := range volumes { + if v.Type == kube.KubeVolumeTypeConfigMap && !v.Optional { + vol, err := ic.Libpod.NewVolume(ctx, libpod.WithVolumeName(v.Source)) + if err != nil { + return nil, errors.Wrapf(err, "cannot create a local volume for volume from configmap %q", v.Source) + } + mountPoint, err := vol.MountPoint() + if err != nil || mountPoint == "" { + return nil, errors.Wrapf(err, "unable to get mountpoint of volume %q", vol.Name()) + } + // Create files and add data to the volume mountpoint based on the Items in the volume + for k, v := range v.Items { + dataPath := filepath.Join(mountPoint, k) + f, err := os.Create(dataPath) + if err != nil { + return nil, errors.Wrapf(err, "cannot create file %q at volume mountpoint %q", k, mountPoint) + } + defer f.Close() + _, err = f.WriteString(v) + if err != nil { + return nil, err + } + } + } + } + + seccompPaths, err := kube.InitializeSeccompPaths(podYAML.ObjectMeta.Annotations, options.SeccompProfileRoot) + if err != nil { + return nil, err + } + + var ctrRestartPolicy string + switch podYAML.Spec.RestartPolicy { + case v1.RestartPolicyAlways: + ctrRestartPolicy = define.RestartPolicyAlways + case v1.RestartPolicyOnFailure: + ctrRestartPolicy = define.RestartPolicyOnFailure + case v1.RestartPolicyNever: + ctrRestartPolicy = define.RestartPolicyNo + default: // Default to Always + ctrRestartPolicy = define.RestartPolicyAlways + } + if podOpt.Infra { infraImage := util.DefaultContainerConfig().Engine.InfraImage infraOptions := entities.NewInfraContainerCreateOptions() diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go index c502a6e62..6d9f598c9 100644 --- a/pkg/specgen/generate/kube/kube.go +++ b/pkg/specgen/generate/kube/kube.go @@ -310,6 +310,11 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener if !exists { return nil, errors.Errorf("Volume mount %s specified for container but not configured in volumes", volume.Name) } + // Skip if the volume is optional. This means that a configmap for a configmap volume was not found but it was + // optional so we can move on without throwing an error + if exists && volumeSource.Optional { + continue + } dest, options, err := parseMountPath(volume.MountPath, volume.ReadOnly) if err != nil { @@ -341,6 +346,13 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener Options: options, } s.Volumes = append(s.Volumes, &namedVolume) + case KubeVolumeTypeConfigMap: + cmVolume := specgen.NamedVolume{ + Dest: volume.MountPath, + Name: volumeSource.Source, + Options: options, + } + s.Volumes = append(s.Volumes, &cmVolume) default: return nil, errors.Errorf("Unsupported volume source type") } diff --git a/pkg/specgen/generate/kube/volume.go b/pkg/specgen/generate/kube/volume.go index a8042b532..76ec0a390 100644 --- a/pkg/specgen/generate/kube/volume.go +++ b/pkg/specgen/generate/kube/volume.go @@ -23,6 +23,7 @@ type KubeVolumeType int const ( KubeVolumeTypeBindMount KubeVolumeType = iota KubeVolumeTypeNamed KubeVolumeType = iota + KubeVolumeTypeConfigMap KubeVolumeType = iota ) // nolint:golint @@ -31,6 +32,14 @@ type KubeVolume struct { Type KubeVolumeType // Path for bind mount or volume name for named volume Source string + // Items to add to a named volume created where the key is the file name and the value is the data + // This is only used when there are volumes in the yaml that refer to a configmap + // Example: if configmap has data "SPECIAL_LEVEL: very" then the file name is "SPECIAL_LEVEL" and the + // data in that file is "very". + Items map[string]string + // If the volume is optional, we can move on if it is not found + // Only used when there are volumes in a yaml that refer to a configmap + Optional bool } // Create a KubeVolume from an HostPathVolumeSource @@ -98,23 +107,64 @@ func VolumeFromPersistentVolumeClaim(claim *v1.PersistentVolumeClaimVolumeSource }, nil } +func VolumeFromConfigMap(configMapVolumeSource *v1.ConfigMapVolumeSource, configMaps []v1.ConfigMap) (*KubeVolume, error) { + var configMap *v1.ConfigMap + kv := &KubeVolume{Type: KubeVolumeTypeConfigMap, Items: map[string]string{}} + for _, cm := range configMaps { + if cm.Name == configMapVolumeSource.Name { + matchedCM := cm + // Set the source to the config map name + kv.Source = cm.Name + configMap = &matchedCM + break + } + } + + if configMap == nil { + // If the volumeSource was optional, move on even if a matching configmap wasn't found + if *configMapVolumeSource.Optional { + kv.Source = configMapVolumeSource.Name + kv.Optional = *configMapVolumeSource.Optional + return kv, nil + } + return nil, errors.Errorf("no such ConfigMap %q", configMapVolumeSource.Name) + } + + // If there are Items specified in the volumeSource, that overwrites the Data from the configmap + if len(configMapVolumeSource.Items) > 0 { + for _, item := range configMapVolumeSource.Items { + if val, ok := configMap.Data[item.Key]; ok { + kv.Items[item.Path] = val + } + } + } else { + for k, v := range configMap.Data { + kv.Items[k] = v + } + } + return kv, nil +} + // Create a KubeVolume from one of the supported VolumeSource -func VolumeFromSource(volumeSource v1.VolumeSource) (*KubeVolume, error) { - if volumeSource.HostPath != nil { +func VolumeFromSource(volumeSource v1.VolumeSource, configMaps []v1.ConfigMap) (*KubeVolume, error) { + switch { + case volumeSource.HostPath != nil: return VolumeFromHostPath(volumeSource.HostPath) - } else if volumeSource.PersistentVolumeClaim != nil { + case volumeSource.PersistentVolumeClaim != nil: return VolumeFromPersistentVolumeClaim(volumeSource.PersistentVolumeClaim) - } else { - return nil, errors.Errorf("HostPath and PersistentVolumeClaim are currently the only supported VolumeSource") + case volumeSource.ConfigMap != nil: + return VolumeFromConfigMap(volumeSource.ConfigMap, configMaps) + default: + return nil, errors.Errorf("HostPath, ConfigMap, and PersistentVolumeClaim are currently the only supported VolumeSource") } } // Create a map of volume name to KubeVolume -func InitializeVolumes(specVolumes []v1.Volume) (map[string]*KubeVolume, error) { +func InitializeVolumes(specVolumes []v1.Volume, configMaps []v1.ConfigMap) (map[string]*KubeVolume, error) { volumes := make(map[string]*KubeVolume) for _, specVolume := range specVolumes { - volume, err := VolumeFromSource(specVolume.VolumeSource) + volume, err := VolumeFromSource(specVolume.VolumeSource, configMaps) if err != nil { return nil, errors.Wrapf(err, "failed to create volume %q", specVolume.Name) } |