diff --git a/docs/content/en/schemas/v2alpha3.json b/docs/content/en/schemas/v2alpha3.json index e138f3fce3e..a419437c069 100755 --- a/docs/content/en/schemas/v2alpha3.json +++ b/docs/content/en/schemas/v2alpha3.json @@ -609,6 +609,13 @@ "type": "string", "description": "amount of time (in seconds) that this build is allowed to run. Defaults to 20 minutes (`20m`).", "x-intellij-html-description": "amount of time (in seconds) that this build is allowed to run. Defaults to 20 minutes (20m)." + }, + "volumes": { + "items": {}, + "type": "array", + "description": "defines container mounts for ConfigMap and Secret resources.", + "x-intellij-html-description": "defines container mounts for ConfigMap and Secret resources.", + "default": "[]" } }, "preferredOrder": [ @@ -621,7 +628,8 @@ "timeout", "dockerConfig", "resources", - "concurrency" + "concurrency", + "volumes" ], "additionalProperties": false, "description": "*beta* describes how to do an on-cluster build.", @@ -1423,6 +1431,13 @@ "type": "string", "description": "Dockerfile target name to build.", "x-intellij-html-description": "Dockerfile target name to build." + }, + "volumeMounts": { + "items": {}, + "type": "array", + "description": "volume mounts passed to kaniko pod.", + "x-intellij-html-description": "volume mounts passed to kaniko pod.", + "default": "[]" } }, "preferredOrder": [ @@ -1435,7 +1450,8 @@ "image", "cache", "reproducible", - "skipTLS" + "skipTLS", + "volumeMounts" ], "additionalProperties": false, "description": "describes an artifact built from a Dockerfile, with kaniko.", diff --git a/pkg/skaffold/build/cluster/pod.go b/pkg/skaffold/build/cluster/pod.go index 90b93007436..ce90b1c7163 100644 --- a/pkg/skaffold/build/cluster/pod.go +++ b/pkg/skaffold/build/cluster/pod.go @@ -93,6 +93,15 @@ func (b *Builder) podSpec(artifact *latest.KanikoArtifact, tag string) (*v1.Pod, addSecretVolume(pod, constants.DefaultKanikoDockerConfigSecretName, constants.DefaultKanikoDockerConfigPath, b.ClusterDetails.DockerConfig.SecretName) } + // Add used-defines Volumes + pod.Spec.Volumes = append(pod.Spec.Volumes, b.Volumes...) + + // Add user-defined VolumeMounts + for _, vm := range artifact.VolumeMounts { + pod.Spec.InitContainers[0].VolumeMounts = append(pod.Spec.InitContainers[0].VolumeMounts, vm) + pod.Spec.Containers[0].VolumeMounts = append(pod.Spec.Containers[0].VolumeMounts, vm) + } + return pod, nil } diff --git a/pkg/skaffold/build/cluster/pod_test.go b/pkg/skaffold/build/cluster/pod_test.go index 63239808f9f..c5eabf7fe9e 100644 --- a/pkg/skaffold/build/cluster/pod_test.go +++ b/pkg/skaffold/build/cluster/pod_test.go @@ -164,6 +164,20 @@ func TestPodSpec(t *testing.T) { Name: "KEY", Value: "VALUE", }}, + VolumeMounts: []v1.VolumeMount{ + { + Name: "cm-volume-1", + ReadOnly: true, + MountPath: "/cm-test-mount-path", + SubPath: "/subpath", + }, + { + Name: "secret-volume-1", + ReadOnly: true, + MountPath: "/secret-test-mount-path", + SubPath: "/subpath", + }, + }, } builder := &Builder{ @@ -181,6 +195,26 @@ func TestPodSpec(t *testing.T) { CPU: "0.5", }, }, + Volumes: []v1.Volume{ + { + Name: "cm-volume-1", + VolumeSource: v1.VolumeSource{ + ConfigMap: &v1.ConfigMapVolumeSource{ + LocalObjectReference: v1.LocalObjectReference{ + Name: "cm-1", + }, + }, + }, + }, + { + Name: "secret-volume-1", + VolumeSource: v1.VolumeSource{ + Secret: &v1.SecretVolumeSource{ + SecretName: "secret-1", + }, + }, + }, + }, }, } pod, _ := builder.podSpec(artifact, "tag") @@ -199,6 +233,16 @@ func TestPodSpec(t *testing.T) { VolumeMounts: []v1.VolumeMount{{ Name: constants.DefaultKanikoEmptyDirName, MountPath: constants.DefaultKanikoEmptyDirMountPath, + }, { + Name: "cm-volume-1", + ReadOnly: true, + MountPath: "/cm-secret-mount-path", + SubPath: "/subpath", + }, { + Name: "secret-volume-1", + ReadOnly: true, + MountPath: "/secret-secret-mount-path", + SubPath: "/subpath", }}, Resources: v1.ResourceRequirements{ Requests: map[v1.ResourceName]resource.Quantity{ @@ -239,6 +283,18 @@ func TestPodSpec(t *testing.T) { Name: constants.DefaultKanikoSecretName, MountPath: "/secret", }, + { + Name: "cm-volume-1", + ReadOnly: true, + MountPath: "/cm-secret-mount-path", + SubPath: "/subpath", + }, + { + Name: "secret-volume-1", + ReadOnly: true, + MountPath: "/secret-secret-mount-path", + SubPath: "/subpath", + }, }, Resources: v1.ResourceRequirements{ Requests: map[v1.ResourceName]resource.Quantity{ @@ -265,6 +321,24 @@ func TestPodSpec(t *testing.T) { }, }, }, + { + Name: "cm-volume-1", + VolumeSource: v1.VolumeSource{ + ConfigMap: &v1.ConfigMapVolumeSource{ + LocalObjectReference: v1.LocalObjectReference{ + Name: "cm-1", + }, + }, + }, + }, + { + Name: "secret-volume-1", + VolumeSource: v1.VolumeSource{ + Secret: &v1.SecretVolumeSource{ + SecretName: "secret-1", + }, + }, + }, }, }, } diff --git a/pkg/skaffold/schema/latest/config.go b/pkg/skaffold/schema/latest/config.go index 6c95c107203..62152f9255d 100644 --- a/pkg/skaffold/schema/latest/config.go +++ b/pkg/skaffold/schema/latest/config.go @@ -304,6 +304,9 @@ type ClusterDetails struct { // Concurrency is how many artifacts can be built concurrently. 0 means "no-limit". // Defaults to `0`. Concurrency int `yaml:"concurrency,omitempty"` + + // Volumes defines container mounts for ConfigMap and Secret resources. + Volumes []v1.Volume `yaml:"volumes,omitempty"` } // DockerConfig contains information about the docker `config.json` to mount. @@ -779,6 +782,9 @@ type KanikoArtifact struct { // SkipTLS skips TLS verification when pulling and pushing the image. SkipTLS bool `yaml:"skipTLS,omitempty"` + + // VolumeMounts are volume mounts passed to kaniko pod. + VolumeMounts []v1.VolumeMount `yaml:"volumeMounts,omitempty"` } // DockerArtifact describes an artifact built from a Dockerfile,