Skip to content

Commit 599066d

Browse files
authored
Merge pull request #5 from bigbinary/feature/image-volumes-support
Added feature Image volumes support
2 parents d063aea + d42f801 commit 599066d

10 files changed

Lines changed: 122 additions & 18 deletions

File tree

.tool-versions

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
golang 1.24.0

pkg/apis/build/v1alpha1/image_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ type ImageBuild struct {
6363
// +listType
6464
Env []corev1.EnvVar `json:"env,omitempty"`
6565
Resources corev1.ResourceRequirements `json:"resources,omitempty"`
66+
// +listType
67+
Volumes []corev1.Volume `json:"volumes,omitempty"`
68+
// +listType
69+
VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"`
6670
}
6771

6872
// +k8s:openapi-gen=true

pkg/apis/build/v1alpha2/build_pod.go

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ func (b *Build) BuildPod(images BuildPodImages, buildContext BuildContext) (*cor
272272
layersMount,
273273
workspaceVolume,
274274
homeMount,
275-
}),
275+
}, b.Spec.VolumeMounts),
276276
Env: []corev1.EnvVar{
277277
homeEnv,
278278
platformApiVersionEnvVar,
@@ -295,7 +295,7 @@ func (b *Build) BuildPod(images BuildPodImages, buildContext BuildContext) (*cor
295295
layersMount,
296296
platformMount,
297297
workspaceVolume,
298-
}, bindingVolumeMounts),
298+
}, bindingVolumeMounts, b.Spec.VolumeMounts),
299299
ImagePullPolicy: corev1.PullIfNotPresent,
300300
Env: []corev1.EnvVar{
301301
platformApiVersionEnvVar,
@@ -355,6 +355,7 @@ func (b *Build) BuildPod(images BuildPodImages, buildContext BuildContext) (*cor
355355
reportMount,
356356
notaryV1Mount,
357357
},
358+
b.Spec.VolumeMounts,
358359
),
359360
ImagePullPolicy: corev1.PullIfNotPresent,
360361
SecurityContext: containerSecurityContext(),
@@ -425,6 +426,7 @@ func (b *Build) BuildPod(images BuildPodImages, buildContext BuildContext) (*cor
425426
homeMount,
426427
projectMetadataMount,
427428
},
429+
b.Spec.VolumeMounts,
428430
),
429431
},
430432
)
@@ -446,7 +448,7 @@ func (b *Build) BuildPod(images BuildPodImages, buildContext BuildContext) (*cor
446448
VolumeMounts: volumeMounts([]corev1.VolumeMount{
447449
layersMount,
448450
homeMount,
449-
}, cacheVolumes),
451+
}, cacheVolumes, b.Spec.VolumeMounts),
450452
Env: []corev1.EnvVar{
451453
homeEnv,
452454
platformApiVersionEnvVar,
@@ -471,7 +473,7 @@ func (b *Build) BuildPod(images BuildPodImages, buildContext BuildContext) (*cor
471473
layersMount,
472474
platformMount,
473475
workspaceVolume,
474-
}, bindingVolumeMounts),
476+
}, bindingVolumeMounts, b.Spec.VolumeMounts),
475477
ImagePullPolicy: corev1.PullIfNotPresent,
476478
Env: []corev1.EnvVar{
477479
platformApiVersionEnvVar,
@@ -508,7 +510,7 @@ func (b *Build) BuildPod(images BuildPodImages, buildContext BuildContext) (*cor
508510
workspaceVolume,
509511
homeMount,
510512
reportMount,
511-
}, cacheVolumes),
513+
}, cacheVolumes, b.Spec.VolumeMounts),
512514
Env: envs(
513515
[]corev1.EnvVar{
514516
homeEnv,
@@ -581,7 +583,10 @@ func (b *Build) BuildPod(images BuildPodImages, buildContext BuildContext) (*cor
581583
b.Spec.Source.Source().ImagePullSecretsVolume(registrySourcePullSecretsVolumeName),
582584
b.notarySecretVolume(),
583585
},
584-
bindingVolumes),
586+
b.Spec.Volumes,
587+
bindingVolumes,
588+
),
589+
585590
ImagePullSecrets: b.Spec.Builder.ImagePullSecrets,
586591
},
587592
}
@@ -647,15 +652,19 @@ func (b *Build) useStandardContainers(buildWaiterImage string, pod *corev1.Pod)
647652
ImagePullPolicy: corev1.PullIfNotPresent,
648653
WorkingDir: "/workspace",
649654
VolumeMounts: volumeMounts(
650-
[]corev1.VolumeMount{
651-
buildWaitMount,
652-
},
655+
append(
656+
[]corev1.VolumeMount{buildWaitMount},
657+
b.Spec.VolumeMounts...,
658+
),
653659
),
654660
},
655661
}
662+
656663
pod.Spec.Containers = append(containers, pod.Spec.Containers...)
657664

658665
for i := 0; i < len(pod.Spec.Containers); i++ {
666+
pod.Spec.Containers[i].VolumeMounts = append(pod.Spec.Containers[i].VolumeMounts, b.Spec.VolumeMounts...)
667+
659668
if i == 0 {
660669
pod.Spec.Containers[i].VolumeMounts = append(pod.Spec.Containers[i].VolumeMounts, downwardMount)
661670
pod.Spec.Containers[i] = setUpBuildWaiter(pod.Spec.Containers[i], "/downward/sidecars-ready")
@@ -689,6 +698,8 @@ func (b *Build) useStandardContainers(buildWaiterImage string, pod *corev1.Pod)
689698
},
690699
)
691700

701+
pod.Spec.Volumes = append(pod.Spec.Volumes, b.Spec.Volumes...)
702+
692703
delete(pod.Annotations, IstioInject)
693704
return pod
694705
}
@@ -847,6 +858,7 @@ func (b *Build) rebasePod(buildContext BuildContext, images BuildPodImages) (*co
847858
[]corev1.VolumeMount{
848859
reportMount,
849860
},
861+
b.Spec.VolumeMounts,
850862
),
851863
},
852864
},

pkg/apis/build/v1alpha2/build_pod_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2458,6 +2458,51 @@ func testBuildPod(t *testing.T, when spec.G, it spec.S) {
24582458
)
24592459
})
24602460
})
2461+
2462+
when("custom volumes and mounts", func() {
2463+
it("attaches user-supplied volumes and mounts to all init containers", func() {
2464+
build.Spec.Volumes = []corev1.Volume{
2465+
{
2466+
Name: "sqlite-pvc",
2467+
VolumeSource: corev1.VolumeSource{
2468+
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
2469+
ClaimName: "my-sqlite-pvc",
2470+
},
2471+
},
2472+
},
2473+
}
2474+
build.Spec.VolumeMounts = []corev1.VolumeMount{
2475+
{
2476+
Name: "sqlite-pvc",
2477+
MountPath: "/workspace/sqlite",
2478+
ReadOnly: false,
2479+
},
2480+
}
2481+
2482+
pod, err := build.BuildPod(config, buildContext)
2483+
require.NoError(t, err)
2484+
2485+
// Check that the volume is present in the pod spec
2486+
found := false
2487+
for _, v := range pod.Spec.Volumes {
2488+
if v.Name == "sqlite-pvc" && v.VolumeSource.PersistentVolumeClaim != nil && v.VolumeSource.PersistentVolumeClaim.ClaimName == "my-sqlite-pvc" {
2489+
found = true
2490+
}
2491+
}
2492+
assert.True(t, found, "sqlite-pvc volume should be present in pod spec")
2493+
2494+
// Check that the mount is present in all init containers
2495+
for _, c := range pod.Spec.InitContainers {
2496+
foundMount := false
2497+
for _, m := range c.VolumeMounts {
2498+
if m.Name == "sqlite-pvc" && m.MountPath == "/workspace/sqlite" {
2499+
foundMount = true
2500+
}
2501+
}
2502+
assert.True(t, foundMount, "sqlite-pvc mount should be present in init container %s", c.Name)
2503+
}
2504+
})
2505+
})
24612506
})
24622507
}
24632508

pkg/apis/build/v1alpha2/build_types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ type BuildSpec struct {
7878
SchedulerName string `json:"schedulerName,omitempty"`
7979
PriorityClassName string `json:"priorityClassName,omitempty"`
8080
CreationTime string `json:"creationTime,omitempty"`
81+
VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"`
82+
Volumes []corev1.Volume `json:"volumes,omitempty"`
8183
}
8284

8385
func (bs *BuildSpec) RegistryCacheTag() string {

pkg/apis/build/v1alpha2/build_validation.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func (b *Build) Validate(ctx context.Context) *apis.FieldError {
2525
}
2626

2727
func (bs *BuildSpec) Validate(ctx context.Context) *apis.FieldError {
28-
return validate.ListNotEmpty(bs.Tags, "tags").
28+
err := validate.ListNotEmpty(bs.Tags, "tags").
2929
Also(validate.Tags(bs.Tags, "tags")).
3030
Also(bs.Cache.Validate(ctx).ViaField("cache")).
3131
Also(bs.Builder.Validate(ctx).ViaField("builder")).
@@ -36,6 +36,25 @@ func (bs *BuildSpec) Validate(ctx context.Context) *apis.FieldError {
3636
Also(validateCnbBindings(ctx, bs.CNBBindings).ViaField("cnbBindings")).
3737
Also(bs.validateNodeSelector(ctx)).
3838
Also(validateNotary(ctx, bs.Notary).ViaField("notary"))
39+
40+
// Validate that all volumeMounts refer to a defined volume
41+
volumeNames := make(map[string]struct{})
42+
for _, v := range bs.Volumes {
43+
if _, exists := volumeNames[v.Name]; exists {
44+
err = err.Also(apis.ErrGeneric("duplicate volume name", "volumes", v.Name))
45+
}
46+
volumeNames[v.Name] = struct{}{}
47+
}
48+
for i, m := range bs.VolumeMounts {
49+
if m.Name == "" {
50+
err = err.Also(apis.ErrMissingField("name").ViaField("volumeMounts").ViaIndex(i))
51+
continue
52+
}
53+
if _, ok := volumeNames[m.Name]; !ok {
54+
err = err.Also(apis.ErrInvalidValue(m.Name, "volumeMounts").ViaIndex(i).Also(apis.ErrGeneric("volumeMount refers to undefined volume", "volumeMounts", m.Name)))
55+
}
56+
}
57+
return err
3958
}
4059

4160
func resourceCreatedByKpackController(info *authv1.UserInfo) bool {

pkg/apis/build/v1alpha2/image_builds.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ func (im *Image) Build(sourceResolver *SourceResolver, builder BuilderResource,
8282
PriorityClassName: priorityClass,
8383
ActiveDeadlineSeconds: im.BuildTimeout(),
8484
CreationTime: im.Spec.creationTime(),
85+
Volumes: im.Volumes(),
86+
VolumeMounts: im.VolumeMounts(),
8587
},
8688
}
8789
}
@@ -304,3 +306,17 @@ func (is *ImageSpec) creationTime() string {
304306

305307
return ""
306308
}
309+
310+
func (im *Image) Volumes() []corev1.Volume {
311+
if im.Spec.Build == nil {
312+
return nil
313+
}
314+
return im.Spec.Build.Volumes
315+
}
316+
317+
func (im *Image) VolumeMounts() []corev1.VolumeMount {
318+
if im.Spec.Build == nil {
319+
return nil
320+
}
321+
return im.Spec.Build.VolumeMounts
322+
}

pkg/apis/build/v1alpha2/image_conversion.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ func (is *ImageSpec) convertTo(to *v1alpha1.ImageSpec) {
7676
to.Build.Env = is.Build.Env
7777
to.Build.Resources = is.Build.Resources
7878
to.Build.Bindings = is.Build.CNBBindings
79+
to.Build.VolumeMounts = is.Build.VolumeMounts
80+
to.Build.Volumes = is.Build.Volumes
7981
}
8082
}
8183

@@ -283,6 +285,8 @@ func (is *ImageSpec) convertFrom(from *v1alpha1.ImageSpec) {
283285
is.Build.Env = from.Build.Env
284286
is.Build.Resources = from.Build.Resources
285287
is.Build.CNBBindings = from.Build.Bindings
288+
is.Build.VolumeMounts = from.Build.VolumeMounts
289+
is.Build.Volumes = from.Build.Volumes
286290
}
287291
}
288292

pkg/apis/build/v1alpha2/image_types.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,15 @@ type ImageBuild struct {
7272
Env []corev1.EnvVar `json:"env,omitempty"`
7373
Resources corev1.ResourceRequirements `json:"resources,omitempty"`
7474
// +listType
75-
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
76-
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
77-
Affinity *corev1.Affinity `json:"affinity,omitempty"`
78-
RuntimeClassName *string `json:"runtimeClassName,omitempty"`
79-
SchedulerName string `json:"schedulerName,omitempty"`
80-
BuildTimeout *int64 `json:"buildTimeout,omitempty"`
81-
CreationTime string `json:"creationTime,omitempty"`
75+
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
76+
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
77+
Affinity *corev1.Affinity `json:"affinity,omitempty"`
78+
RuntimeClassName *string `json:"runtimeClassName,omitempty"`
79+
SchedulerName string `json:"schedulerName,omitempty"`
80+
BuildTimeout *int64 `json:"buildTimeout,omitempty"`
81+
CreationTime string `json:"creationTime,omitempty"`
82+
VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"`
83+
Volumes []corev1.Volume `json:"volumes,omitempty"`
8284
}
8385

8486
// +k8s:openapi-gen=true

pkg/git/fetch.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ func (f Fetcher) Fetch(dir, gitURL, gitRevision, metadataDir string) error {
6262
}
6363

6464
err = remote.Fetch(&gogit.FetchOptions{
65-
Depth: 1,
6665
RefSpecs: []config.RefSpec{config.RefSpec(resolvedSourceConfig.Git.Revision + ":" + resolvedSourceConfig.Git.Revision)},
6766
Auth: auth,
6867
Depth: 1,

0 commit comments

Comments
 (0)