Skip to content

Commit 1b7f0b3

Browse files
Separate PullOption for build process and image verification (#32)
Currently we have pull option in the Build section of the Module API. It is used both for configuring the pull option passed to the build configuration (kaniko) and also to the function that verifies images existence (pulling its manifest). We should separate them into 2 different entities: 1) present in ModuleLoader spec - used for image contents inspection and existence verification 2) present in the Build - used for specifying pull options of the base images of the build process
1 parent 4cedc9e commit 1b7f0b3

11 files changed

+117
-21
lines changed

api/v1beta1/module_types.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ type Build struct {
6363
Dockerfile string `json:"dockerfile"`
6464

6565
// +optional
66-
// Pull contains settings determining how to check if the DriverContainer image already exists.
66+
// Pull contains settings determining how to pull the base images of the build process.
6767
Pull PullOptions `json:"pull"`
6868

6969
// +optional
@@ -96,6 +96,11 @@ type KernelMapping struct {
9696
// Literal defines a literal target kernel version to be matched exactly against node kernels.
9797
Literal string `json:"literal"`
9898

99+
// +optional
100+
// Pull contains settings determining how to check if the ModuleLoader image already exists
101+
// and allows overriding of the ModuleLoader's pull options
102+
Pull *PullOptions `json:"pull"`
103+
99104
// +optional
100105
// Regexp is a regular expression to be match against node kernels.
101106
Regexp string `json:"regexp"`
@@ -162,6 +167,10 @@ type ModuleLoaderContainerSpec struct {
162167

163168
// Modprobe is a set of properties to customize which module modprobe loads and with which properties.
164169
Modprobe ModprobeSpec `json:"modprobe"`
170+
171+
// +optional
172+
// Pull contains settings determining how to check if the ModuleLoader image already exists.
173+
Pull *PullOptions `json:"pull"`
165174
}
166175

167176
type ModuleLoaderSpec struct {

api/v1beta1/zz_generated.deepcopy.go

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ci/module-kmm-ci-build.template.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ spec:
1111
kernelMappings:
1212
- literal: KVER_CHANGEME
1313
containerImage: registry.minikube/kmm-kmod:local
14+
pull:
15+
insecure: true
1416
build:
1517
buildArgs:
1618
- name: CI_BUILD_ARG

config/crd/bases/kmm.sigs.k8s.io_modules.yaml

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1880,7 +1880,7 @@ spec:
18801880
type: object
18811881
pull:
18821882
description: Pull contains settings determining how to
1883-
check if the DriverContainer image already exists.
1883+
pull the base images of the build process.
18841884
properties:
18851885
insecure:
18861886
description: If Insecure is true, images can be pulled
@@ -1977,8 +1977,7 @@ spec:
19771977
type: object
19781978
pull:
19791979
description: Pull contains settings determining
1980-
how to check if the DriverContainer image already
1981-
exists.
1980+
how to pull the base images of the build process.
19821981
properties:
19831982
insecure:
19841983
description: If Insecure is true, images can
@@ -2035,6 +2034,20 @@ spec:
20352034
description: Literal defines a literal target kernel
20362035
version to be matched exactly against node kernels.
20372036
type: string
2037+
pull:
2038+
description: Pull contains settings determining how
2039+
to check if the ModuleLoader image already exists
2040+
and allows overriding of the ModuleLoader's pull options
2041+
properties:
2042+
insecure:
2043+
description: If Insecure is true, images can be
2044+
pulled from an insecure (plain HTTP) registry.
2045+
type: boolean
2046+
insecureSkipTLSVerify:
2047+
description: If InsecureSkipTLSVerify, the operator
2048+
will accept any certificate provided by the registry.
2049+
type: boolean
2050+
type: object
20382051
regexp:
20392052
description: Regexp is a regular expression to be match
20402053
against node kernels.
@@ -2111,6 +2124,19 @@ spec:
21112124
required:
21122125
- moduleName
21132126
type: object
2127+
pull:
2128+
description: Pull contains settings determining how to check
2129+
if the ModuleLoader image already exists.
2130+
properties:
2131+
insecure:
2132+
description: If Insecure is true, images can be pulled
2133+
from an insecure (plain HTTP) registry.
2134+
type: boolean
2135+
insecureSkipTLSVerify:
2136+
description: If InsecureSkipTLSVerify, the operator will
2137+
accept any certificate provided by the registry.
2138+
type: boolean
2139+
type: object
21142140
required:
21152141
- kernelMappings
21162142
- modprobe

internal/build/helper.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
type Helper interface {
1313
ApplyBuildArgOverrides(args []v1beta1.BuildArg, overrides ...v1beta1.BuildArg) []v1beta1.BuildArg
1414
GetRelevantBuild(mod kmmv1beta1.Module, km kmmv1beta1.KernelMapping) *kmmv1beta1.Build
15+
GetRelevantPullOptions(mod kmmv1beta1.Module, km kmmv1beta1.KernelMapping) *kmmv1beta1.PullOptions
1516
}
1617

1718
type helper struct{}
@@ -67,3 +68,10 @@ func (m *helper) GetRelevantBuild(mod kmmv1beta1.Module, km kmmv1beta1.KernelMap
6768
buildConfig.Secrets = append(buildConfig.Secrets, km.Build.Secrets...)
6869
return buildConfig
6970
}
71+
72+
func (m *helper) GetRelevantPullOptions(mod kmmv1beta1.Module, km kmmv1beta1.KernelMapping) *kmmv1beta1.PullOptions {
73+
if km.Pull != nil {
74+
return km.Pull
75+
}
76+
return mod.Spec.ModuleLoader.Container.Pull
77+
}

internal/build/job/manager.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ func (jbm *jobManager) Sync(ctx context.Context, mod kmmv1beta1.Module, m kmmv1b
6666
logger := log.FromContext(ctx)
6767

6868
buildConfig := jbm.helper.GetRelevantBuild(mod, m)
69+
imagePullOptions := jbm.helper.GetRelevantPullOptions(mod, m)
6970

7071
var registryAuthGetter auth.RegistryAuthGetter
7172

@@ -76,7 +77,7 @@ func (jbm *jobManager) Sync(ctx context.Context, mod kmmv1beta1.Module, m kmmv1b
7677
}
7778
registryAuthGetter = auth.NewRegistryAuthGetter(jbm.client, namespacedName)
7879
}
79-
imageAvailable, err := jbm.registry.ImageExists(ctx, m.ContainerImage, buildConfig.Pull, registryAuthGetter)
80+
imageAvailable, err := jbm.registry.ImageExists(ctx, m.ContainerImage, imagePullOptions, registryAuthGetter)
8081
if err != nil {
8182
return build.Result{}, fmt.Errorf("could not check if the image is available: %v", err)
8283
}

internal/build/job/manager_test.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,18 @@ var _ = Describe("JobManager", func() {
6060
helper = build.NewMockHelper(ctrl)
6161
})
6262

63-
po := kmmv1beta1.PullOptions{}
63+
po := &kmmv1beta1.PullOptions{}
6464

6565
km := kmmv1beta1.KernelMapping{
66-
Build: &kmmv1beta1.Build{Pull: po},
66+
Build: &kmmv1beta1.Build{Pull: *po},
6767
ContainerImage: imageName,
6868
}
6969

7070
It("should return an error if there was an error getting the image", func() {
7171
ctx := context.Background()
7272
gomock.InOrder(
7373
helper.EXPECT().GetRelevantBuild(gomock.Any(), km).Return(km.Build),
74+
helper.EXPECT().GetRelevantPullOptions(gomock.Any(), km).Return(po),
7475
registry.EXPECT().ImageExists(ctx, imageName, po, gomock.Any()).Return(false, errors.New("random error")),
7576
)
7677
mgr := NewBuildManager(nil, registry, maker, helper)
@@ -84,6 +85,7 @@ var _ = Describe("JobManager", func() {
8485

8586
gomock.InOrder(
8687
helper.EXPECT().GetRelevantBuild(gomock.Any(), km).Return(km.Build),
88+
helper.EXPECT().GetRelevantPullOptions(gomock.Any(), km).Return(po),
8789
registry.EXPECT().ImageExists(ctx, imageName, po, gomock.Any()).Return(true, nil),
8890
)
8991

@@ -125,6 +127,7 @@ var _ = Describe("JobManager", func() {
125127

126128
gomock.InOrder(
127129
helper.EXPECT().GetRelevantBuild(mod, km).Return(km.Build),
130+
helper.EXPECT().GetRelevantPullOptions(gomock.Any(), km).Return(po),
128131
registry.EXPECT().ImageExists(ctx, imageName, po, gomock.Any()).Return(false, nil),
129132
)
130133

@@ -149,6 +152,7 @@ var _ = Describe("JobManager", func() {
149152

150153
gomock.InOrder(
151154
helper.EXPECT().GetRelevantBuild(mod, km).Return(km.Build),
155+
helper.EXPECT().GetRelevantPullOptions(gomock.Any(), km).Return(po),
152156
registry.EXPECT().ImageExists(ctx, imageName, po, gomock.Any()),
153157
maker.EXPECT().MakeJob(mod, km.Build, kernelVersion, km.ContainerImage, true).Return(nil, errors.New("random error")),
154158
)
@@ -179,6 +183,7 @@ var _ = Describe("JobManager", func() {
179183

180184
gomock.InOrder(
181185
helper.EXPECT().GetRelevantBuild(mod, km).Return(km.Build),
186+
helper.EXPECT().GetRelevantPullOptions(gomock.Any(), km).Return(po),
182187
registry.EXPECT().ImageExists(ctx, imageName, po, gomock.Any()),
183188
maker.EXPECT().MakeJob(mod, km.Build, kernelVersion, km.ContainerImage, true).Return(&j, nil),
184189
)
@@ -216,6 +221,7 @@ var _ = Describe("JobManager", func() {
216221

217222
gomock.InOrder(
218223
helper.EXPECT().GetRelevantBuild(mod, km).Return(km.Build),
224+
helper.EXPECT().GetRelevantPullOptions(gomock.Any(), km).Return(po),
219225
registry.EXPECT().ImageExists(ctx, imageName, po, gomock.Any()).DoAndReturn(
220226
func(_ interface{}, _ interface{}, _ interface{}, registryAuthGetter auth.RegistryAuthGetter) (bool, error) {
221227
Expect(registryAuthGetter).ToNot(BeNil())

internal/build/mock_helper.go

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/registry/mock_registry_api.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/registry/registry.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ type RepoPullConfig struct {
4040
//go:generate mockgen -source=registry.go -package=registry -destination=mock_registry_api.go
4141

4242
type Registry interface {
43-
ImageExists(ctx context.Context, image string, po kmmv1beta1.PullOptions, registryAuthGetter auth.RegistryAuthGetter) (bool, error)
43+
ImageExists(ctx context.Context, image string, po *kmmv1beta1.PullOptions, registryAuthGetter auth.RegistryAuthGetter) (bool, error)
4444
VerifyModuleExists(layer v1.Layer, pathPrefix, kernelVersion, moduleFileName string) bool
4545
GetLayersDigests(ctx context.Context, image string, registryAuthGetter auth.RegistryAuthGetter) ([]string, *RepoPullConfig, error)
4646
GetLayerByDigest(digest string, pullConfig *RepoPullConfig) (v1.Layer, error)
@@ -52,8 +52,8 @@ func NewRegistry() Registry {
5252
return &registry{}
5353
}
5454

55-
func (r *registry) ImageExists(ctx context.Context, image string, po kmmv1beta1.PullOptions, registryAuthGetter auth.RegistryAuthGetter) (bool, error) {
56-
pullConfig, err := r.getPullOptions(ctx, image, &po, registryAuthGetter)
55+
func (r *registry) ImageExists(ctx context.Context, image string, po *kmmv1beta1.PullOptions, registryAuthGetter auth.RegistryAuthGetter) (bool, error) {
56+
pullConfig, err := r.getPullOptions(ctx, image, po, registryAuthGetter)
5757
if err != nil {
5858
return false, fmt.Errorf("failed to get pull options for image %s: %w", image, err)
5959
}

internal/registry/registry_test.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ var _ = Describe("ImageExists", func() {
5858

5959
It("should fail if the image name isn't valid", func() {
6060

61-
_, err = reg.ImageExists(ctx, invalidImage, kmmv1beta1.PullOptions{}, nil)
61+
_, err = reg.ImageExists(ctx, invalidImage, &kmmv1beta1.PullOptions{}, nil)
6262

6363
Expect(err).To(HaveOccurred())
6464
Expect(err.Error()).To(ContainSubstring("does not contain hash or tag"))
@@ -68,7 +68,7 @@ var _ = Describe("ImageExists", func() {
6868

6969
mockRegistryAuthGetter.EXPECT().GetKeyChain(ctx).Return(nil, errors.New("some error"))
7070

71-
_, err = reg.ImageExists(ctx, validImage, kmmv1beta1.PullOptions{}, mockRegistryAuthGetter)
71+
_, err = reg.ImageExists(ctx, validImage, &kmmv1beta1.PullOptions{}, mockRegistryAuthGetter)
7272

7373
Expect(err).To(HaveOccurred())
7474
Expect(err.Error()).To(ContainSubstring("cannot get keychain from the registry auth getter"))
@@ -93,7 +93,7 @@ var _ = Describe("ImageExists", func() {
9393
u := mustParseURL(server.URL)
9494

9595
image := fmt.Sprintf("%s/%s/%s:%s", u.Host, validImageOrg, validImageName, validImageTag)
96-
_, err = reg.ImageExists(ctx, image, kmmv1beta1.PullOptions{}, nil)
96+
_, err = reg.ImageExists(ctx, image, &kmmv1beta1.PullOptions{}, nil)
9797

9898
Expect(err).To(HaveOccurred())
9999
Expect(err.Error()).To(ContainSubstring("failed to get crane manifest from image"))
@@ -108,7 +108,7 @@ var _ = Describe("ImageExists", func() {
108108
u := mustParseURL(server.URL)
109109

110110
image := fmt.Sprintf("%s/%s/%s:%s", u.Host, validImageOrg, validImageName, validImageTag)
111-
_, err = reg.ImageExists(ctx, image, kmmv1beta1.PullOptions{}, nil)
111+
_, err = reg.ImageExists(ctx, image, &kmmv1beta1.PullOptions{}, nil)
112112

113113
Expect(err).To(HaveOccurred())
114114
Expect(err.Error()).To(ContainSubstring("failed to unmarshal crane manifest"))
@@ -134,7 +134,7 @@ var _ = Describe("ImageExists", func() {
134134
u := mustParseURL(server.URL)
135135

136136
image := fmt.Sprintf("%s/%s/%s:%s", u.Host, validImageOrg, validImageName, validImageTag)
137-
_, err = reg.ImageExists(ctx, image, kmmv1beta1.PullOptions{}, nil)
137+
_, err = reg.ImageExists(ctx, image, &kmmv1beta1.PullOptions{}, nil)
138138

139139
Expect(err).To(HaveOccurred())
140140
Expect(err.Error()).To(ContainSubstring("mediaType is missing from the image"))
@@ -150,7 +150,7 @@ var _ = Describe("ImageExists", func() {
150150
u := mustParseURL(server.URL)
151151

152152
image := fmt.Sprintf("%s/%s/%s:%s", u.Host, validImageOrg, validImageName, validImageTag)
153-
_, err := reg.ImageExists(ctx, image, kmmv1beta1.PullOptions{}, nil)
153+
_, err := reg.ImageExists(ctx, image, &kmmv1beta1.PullOptions{}, nil)
154154

155155
Expect(err).ToNot(HaveOccurred())
156156
})
@@ -173,9 +173,9 @@ var _ = Describe("ImageExists", func() {
173173
var err error
174174
image := fmt.Sprintf("%s/%s/%s:%s", u.Host, validImageOrg, validImageName, validImageTag)
175175
if withRegistryAuthGetter {
176-
_, err = reg.ImageExists(ctx, image, kmmv1beta1.PullOptions{}, mockRegistryAuthGetter)
176+
_, err = reg.ImageExists(ctx, image, &kmmv1beta1.PullOptions{}, mockRegistryAuthGetter)
177177
} else {
178-
_, err = reg.ImageExists(ctx, image, kmmv1beta1.PullOptions{}, nil)
178+
_, err = reg.ImageExists(ctx, image, &kmmv1beta1.PullOptions{}, nil)
179179
}
180180
Expect(err).ToNot(HaveOccurred())
181181
},
@@ -223,7 +223,7 @@ var _ = Describe("GetLayersDigests", func() {
223223

224224
It("should fail if the image name isn't valid", func() {
225225

226-
_, err = reg.ImageExists(ctx, invalidImage, kmmv1beta1.PullOptions{}, nil)
226+
_, err = reg.ImageExists(ctx, invalidImage, &kmmv1beta1.PullOptions{}, nil)
227227

228228
Expect(err).To(HaveOccurred())
229229
Expect(err.Error()).To(ContainSubstring("does not contain hash or tag"))
@@ -233,7 +233,7 @@ var _ = Describe("GetLayersDigests", func() {
233233

234234
mockRegistryAuthGetter.EXPECT().GetKeyChain(ctx).Return(nil, errors.New("some error"))
235235

236-
_, err = reg.ImageExists(ctx, validImage, kmmv1beta1.PullOptions{}, mockRegistryAuthGetter)
236+
_, err = reg.ImageExists(ctx, validImage, &kmmv1beta1.PullOptions{}, mockRegistryAuthGetter)
237237

238238
Expect(err).To(HaveOccurred())
239239
Expect(err.Error()).To(ContainSubstring("cannot get keychain from the registry auth getter"))

0 commit comments

Comments
 (0)