diff --git a/pkg/config/stepmeta.go b/pkg/config/stepmeta.go index c31ccd4000..659451c338 100644 --- a/pkg/config/stepmeta.go +++ b/pkg/config/stepmeta.go @@ -13,6 +13,8 @@ import ( "github.com/pkg/errors" ) +const SupportedVolumeName = "volume" + // StepData defines the metadata for a step, like step descriptions, parameters, ... type StepData struct { Metadata StepMetadata `json:"metadata"` @@ -105,25 +107,25 @@ type StepOutputs struct { // Container defines an execution container type Container struct { //ToDo: check dockerOptions, dockerVolumeBind, containerPortMappings, sidecarOptions, sidecarVolumeBind - Command []string `json:"command"` - EnvVars []EnvVar `json:"env"` - Image string `json:"image"` - ImagePullPolicy string `json:"imagePullPolicy"` - Name string `json:"name"` - ReadyCommand string `json:"readyCommand"` - Shell string `json:"shell"` - WorkingDir string `json:"workingDir"` - Conditions []Condition `json:"conditions,omitempty"` - Options []Option `json:"options,omitempty"` - //VolumeMounts []VolumeMount `json:"volumeMounts,omitempty"` + Command []string `json:"command"` + EnvVars []EnvVar `json:"env"` + Image string `json:"image"` + ImagePullPolicy string `json:"imagePullPolicy"` + Name string `json:"name"` + ReadyCommand string `json:"readyCommand"` + Shell string `json:"shell"` + WorkingDir string `json:"workingDir"` + Conditions []Condition `json:"conditions,omitempty"` + Options []Option `json:"options,omitempty"` + VolumeMounts []VolumeMount `json:"volumeMounts,omitempty"` } // ToDo: Add the missing Volumes part to enable the volume mount completely // VolumeMount defines a mount path -// type VolumeMount struct { -// MountPath string `json:"mountPath"` -// Name string `json:"name"` -//} +type VolumeMount struct { + Name string `json:"name"` + MountPath string `json:"mountPath"` +} // Option defines an docker option type Option struct { @@ -385,7 +387,7 @@ func (container *Container) commonConfiguration(keyPrefix string, config *map[st } putStringIfNotEmpty(*config, keyPrefix+"Workspace", container.WorkingDir) putSliceIfNotEmpty(*config, keyPrefix+"Options", OptionsAsStringSlice(container.Options)) - //putSliceIfNotEmpty(*config, keyPrefix+"VolumeBind", volumeMountsAsStringSlice(container.VolumeMounts)) + putSliceIfNotEmpty(*config, keyPrefix+"VolumeBind", volumeMountsAsStringSlice(container.VolumeMounts)) } @@ -518,11 +520,14 @@ func ResolveMetadata(gitHubTokens map[string]string, metaDataResolver func() map return metadata, nil } -//ToDo: Enable this when the Volumes part is also implemented -//func volumeMountsAsStringSlice(volumeMounts []VolumeMount) []string { -// e := []string{} -// for _, v := range volumeMounts { -// e = append(e, fmt.Sprintf("%v:%v", v.Name, v.MountPath)) -// } -// return e -//} +func volumeMountsAsStringSlice(volumeMounts []VolumeMount) []string { + e := []string{} + for _, v := range volumeMounts { + if v.Name != SupportedVolumeName { + log.Entry().Warningf("Unsupported volume name: %q, only %q is supported", v.Name, SupportedVolumeName) + continue + } + e = append(e, fmt.Sprintf("%v:%v", v.Name, v.MountPath)) + } + return e +} diff --git a/pkg/config/stepmeta_test.go b/pkg/config/stepmeta_test.go index 5452d95c40..5d4a4449fa 100644 --- a/pkg/config/stepmeta_test.go +++ b/pkg/config/stepmeta_test.go @@ -397,10 +397,10 @@ func TestGetContextDefaults(t *testing.T) { {Name: "opt1", Value: "optValue1"}, {Name: "opt2", Value: "optValue2"}, }, - //VolumeMounts: []VolumeMount{ - // {MountPath: "mp1", Name: "mn1"}, - // {MountPath: "mp2", Name: "mn2"}, - //}, + VolumeMounts: []VolumeMount{ + {MountPath: "mp1", Name: "volume"}, + {MountPath: "mp2", Name: "mn2"}, + }, }, }, Sidecars: []Container{ @@ -419,10 +419,10 @@ func TestGetContextDefaults(t *testing.T) { {Name: "opt3", Value: "optValue3"}, {Name: "opt4", Value: "optValue4"}, }, - //VolumeMounts: []VolumeMount{ - // {MountPath: "mp3", Name: "mn3"}, - // {MountPath: "mp4", Name: "mn4"}, - //}, + VolumeMounts: []VolumeMount{ + {MountPath: "mp3", Name: "mn3"}, + {MountPath: "mp4", Name: "volume"}, + }, }, }, }, @@ -451,7 +451,7 @@ func TestGetContextDefaults(t *testing.T) { assert.Equal(t, true, d.Defaults[0].Steps["testStep"]["dockerPullImage"], "dockerPullImage default not available") assert.Equal(t, "/test/dir", d.Defaults[0].Steps["testStep"]["dockerWorkspace"], "dockerWorkspace default not available") assert.Equal(t, []interface{}{"opt1 optValue1", "opt2 optValue2"}, d.Defaults[0].Steps["testStep"]["dockerOptions"], "dockerOptions default not available") - //assert.Equal(t, []interface{}{"mn1:mp1", "mn2:mp2"}, d.Defaults[0].Steps["testStep"]["dockerVolumeBind"], "dockerVolumeBind default not available") + assert.Equal(t, []interface{}{"volume:mp1"}, d.Defaults[0].Steps["testStep"]["dockerVolumeBind"], "dockerVolumeBind default not available") assert.Equal(t, "/sidecar/command", d.Defaults[0].Steps["testStep"]["sidecarCommand"], "sidecarCommand default not available") assert.Equal(t, map[string]interface{}{"env3": "val3", "env4": "val4"}, d.Defaults[0].Steps["testStep"]["sidecarEnvVars"], "sidecarEnvVars default not available") @@ -461,7 +461,7 @@ func TestGetContextDefaults(t *testing.T) { assert.Equal(t, "/sidecar/command", d.Defaults[0].Steps["testStep"]["sidecarReadyCommand"], "sidecarReadyCommand default not available") assert.Equal(t, "/sidecar/dir", d.Defaults[0].Steps["testStep"]["sidecarWorkspace"], "sidecarWorkspace default not available") assert.Equal(t, []interface{}{"opt3 optValue3", "opt4 optValue4"}, d.Defaults[0].Steps["testStep"]["sidecarOptions"], "sidecarOptions default not available") - //assert.Equal(t, []interface{}{"mn3:mp3", "mn4:mp4"}, d.Defaults[0].Steps["testStep"]["sidecarVolumeBind"], "sidecarVolumeBind default not available") + assert.Equal(t, []interface{}{"volume:mp4"}, d.Defaults[0].Steps["testStep"]["sidecarVolumeBind"], "sidecarVolumeBind default not available") }) t.Run("Container conditions", func(t *testing.T) { diff --git a/vars/dockerExecute.groovy b/vars/dockerExecute.groovy index c00a07395e..4dc56499a6 100644 --- a/vars/dockerExecute.groovy +++ b/vars/dockerExecute.groovy @@ -183,6 +183,7 @@ void call(Map parameters = [:], body) { } def securityContext = securityContextFromOptions(config.dockerOptions) + def containerMountPath = containerMountPathFromVolumeBind(config.dockerVolumeBind) if (env.POD_NAME && isContainerDefined(config)) { container(getContainerDefined(config)) { withEnv(dockerEnvVars) { @@ -208,6 +209,7 @@ void call(Map parameters = [:], body) { stashContent: config.stashContent, stashNoDefaultExcludes: config.stashNoDefaultExcludes, securityContext: securityContext, + containerMountPath: containerMountPath, ] if (config.sidecarImage) { @@ -379,6 +381,17 @@ def securityContextFromOptions(dockerOptions) { return securityContext } +/* + * Picks the first volumeBind option and translates it into containerMountPath, currently only one fix volume is supported + */ +@NonCPS +def containerMountPathFromVolumeBind(dockerVolumeBind) { + if (dockerVolumeBind) { + return dockerVolumeBind[0].split(":")[1] + } + return "" +} + boolean isContainerDefined(config) { Map containerMap = ContainerMap.instance.getMap() diff --git a/vars/dockerExecuteOnKubernetes.groovy b/vars/dockerExecuteOnKubernetes.groovy index dcd4de1b76..f80eaea3f5 100644 --- a/vars/dockerExecuteOnKubernetes.groovy +++ b/vars/dockerExecuteOnKubernetes.groovy @@ -582,9 +582,12 @@ private List getContainerList(config) { command : [] ] def resources = getResources(sideCarContainerName, config) - if(resources) { + if (resources) { containerSpec.resources = resources } + if (config.containerMountPath) { + containerSpec.volumeMounts = [[name: "volume", mountPath: config.containerMountPath]] + } result.push(containerSpec) } return result