diff options
Diffstat (limited to 'pkg/specgen')
-rw-r--r-- | pkg/specgen/generate/kube/kube.go | 12 | ||||
-rw-r--r-- | pkg/specgen/generate/kube/volume.go | 64 |
2 files changed, 69 insertions, 7 deletions
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) } |