Skip to content

Commit 6c1a241

Browse files
committed
handle optionality of spec.grpcPodConfig.extractContent.cacheDir
Signed-off-by: Jordan Keister <[email protected]>
1 parent dfd0b2b commit 6c1a241

File tree

15 files changed

+936
-659
lines changed

15 files changed

+936
-659
lines changed

deploy/chart/crds/0000_50_olm_00-catalogsources.crd.yaml

+1-2
Original file line numberDiff line numberDiff line change
@@ -975,11 +975,10 @@ spec:
975975
configured to use *must* be using the file-based catalogs in order to utilize this feature.
976976
type: object
977977
required:
978-
- cacheDir
979978
- catalogDir
980979
properties:
981980
cacheDir:
982-
description: CacheDir is the directory storing the pre-calculated API cache.
981+
description: CacheDir is the (optional) directory storing the pre-calculated API cache.
983982
type: string
984983
catalogDir:
985984
description: CatalogDir is the directory storing the file-based catalog contents.

go.mod

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ require (
2424
github.com/onsi/gomega v1.36.2
2525
github.com/openshift/api v3.9.0+incompatible
2626
github.com/openshift/client-go v0.0.0-20220525160904-9e1acff93e4a
27-
github.com/operator-framework/api v0.30.0
27+
github.com/operator-framework/api v0.31.0
2828
github.com/operator-framework/operator-registry v1.51.0
2929
github.com/otiai10/copy v1.14.1
3030
github.com/pkg/errors v0.9.1
@@ -35,7 +35,7 @@ require (
3535
github.com/spf13/cobra v1.9.1
3636
github.com/spf13/pflag v1.0.6
3737
github.com/stretchr/testify v1.10.0
38-
golang.org/x/net v0.37.0
38+
golang.org/x/net v0.38.0
3939
golang.org/x/sync v0.12.0
4040
golang.org/x/time v0.11.0
4141
google.golang.org/grpc v1.70.0

go.sum

+4-4
Original file line numberDiff line numberDiff line change
@@ -1827,8 +1827,8 @@ github.com/openshift/api v0.0.0-20221021112143-4226c2167e40 h1:PxjGCA72RtsdHWToZ
18271827
github.com/openshift/api v0.0.0-20221021112143-4226c2167e40/go.mod h1:aQ6LDasvHMvHZXqLHnX2GRmnfTWCF/iIwz8EMTTIE9A=
18281828
github.com/openshift/client-go v0.0.0-20221019143426-16aed247da5c h1:CV76yFOTXmq9VciBR3Bve5ZWzSxdft7gaMVB3kS0rwg=
18291829
github.com/openshift/client-go v0.0.0-20221019143426-16aed247da5c/go.mod h1:lFMO8mLHXWFzSdYvGNo8ivF9SfF6zInA8ZGw4phRnUE=
1830-
github.com/operator-framework/api v0.30.0 h1:44hCmGnEnZk/Miol5o44dhSldNH0EToQUG7vZTl29kk=
1831-
github.com/operator-framework/api v0.30.0/go.mod h1:FYxAPhjtlXSAty/fbn5YJnFagt6SpJZJgFNNbvDe5W0=
1830+
github.com/operator-framework/api v0.31.0 h1:tRsFTuZ51xD8U5QgiPo3+mZgVipHZVgRXYrI6RRXOh8=
1831+
github.com/operator-framework/api v0.31.0/go.mod h1:57oCiHNeWcxmzu1Se8qlnwEKr/GGXnuHvspIYFCcXmY=
18321832
github.com/operator-framework/operator-registry v1.51.0 h1:3T1H2W0wYvJx82x+Ue6nooFsn859ceJf1yH6MdRdjMQ=
18331833
github.com/operator-framework/operator-registry v1.51.0/go.mod h1:dJadFTSvsgpeiqhTMK7+zXrhU0LIlx4Y/aDz0efq5oQ=
18341834
github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8=
@@ -2193,8 +2193,8 @@ golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
21932193
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
21942194
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
21952195
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
2196-
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
2197-
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
2196+
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
2197+
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
21982198
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
21992199
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
22002200
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=

pkg/controller/registry/reconciler/reconciler.go

+17-10
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,17 @@ func Pod(source *operatorsv1alpha1.CatalogSource, name, opmImg, utilImage, img s
275275
Name: "catalog-content",
276276
MountPath: catalogPath,
277277
}
278+
// init container to copy catalog info.
279+
// ExtractContent.CatalogDir is mandatory when ExtractContent is provided
280+
// ExtractContent.CacheDir is optional, so we only add it if it is set
281+
var extractArgs = []string{
282+
"--catalog.from=" + grpcPodConfig.ExtractContent.CatalogDir,
283+
"--catalog.to=" + fmt.Sprintf("%s/catalog", catalogPath),
284+
}
285+
if grpcPodConfig.ExtractContent.CacheDir != "" {
286+
extractArgs = append(extractArgs, "--cache.from="+grpcPodConfig.ExtractContent.CacheDir)
287+
extractArgs = append(extractArgs, "--cache.to="+fmt.Sprintf("%s/cache", catalogPath))
288+
}
278289
pod.Spec.InitContainers = append(pod.Spec.InitContainers, corev1.Container{
279290
Name: "extract-utilities",
280291
Image: utilImage,
@@ -283,22 +294,18 @@ func Pod(source *operatorsv1alpha1.CatalogSource, name, opmImg, utilImage, img s
283294
VolumeMounts: []corev1.VolumeMount{utilitiesVolumeMount},
284295
TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError,
285296
}, corev1.Container{
286-
Name: "extract-content",
287-
Image: img,
288-
ImagePullPolicy: image.InferImagePullPolicy(img),
289-
Command: []string{utilitiesPath + "/copy-content"},
290-
Args: []string{
291-
"--catalog.from=" + grpcPodConfig.ExtractContent.CatalogDir,
292-
"--catalog.to=" + fmt.Sprintf("%s/catalog", catalogPath),
293-
"--cache.from=" + grpcPodConfig.ExtractContent.CacheDir,
294-
"--cache.to=" + fmt.Sprintf("%s/cache", catalogPath),
295-
},
297+
Name: "extract-content",
298+
Image: img,
299+
ImagePullPolicy: image.InferImagePullPolicy(img),
300+
Command: []string{utilitiesPath + "/copy-content"},
301+
Args: extractArgs,
296302
VolumeMounts: []corev1.VolumeMount{utilitiesVolumeMount, contentVolumeMount},
297303
TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError,
298304
})
299305

300306
pod.Spec.Containers[0].Image = opmImg
301307
pod.Spec.Containers[0].Command = []string{"/bin/opm"}
308+
// set service cache dir unconditionally, since it should always have compatible permissions for generation, if not provided by grpcPodConfig
302309
pod.Spec.Containers[0].Args = []string{
303310
"serve",
304311
filepath.Join(catalogPath, "catalog"),

pkg/controller/registry/reconciler/reconciler_test.go

+241
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,119 @@ func TestPodExtractContent(t *testing.T) {
380380
},
381381
},
382382
},
383+
{
384+
name: "content extraction expected - legacy security context config, no catalog cache dir",
385+
input: &v1alpha1.CatalogSource{
386+
ObjectMeta: metav1.ObjectMeta{
387+
Name: "test",
388+
Namespace: "testns",
389+
},
390+
Spec: v1alpha1.CatalogSourceSpec{
391+
GrpcPodConfig: &v1alpha1.GrpcPodConfig{
392+
ExtractContent: &v1alpha1.ExtractContentConfig{
393+
CatalogDir: "/catalog",
394+
},
395+
},
396+
},
397+
},
398+
securityContextConfig: v1alpha1.Legacy,
399+
expected: &corev1.Pod{
400+
ObjectMeta: metav1.ObjectMeta{
401+
GenerateName: "test-",
402+
Namespace: "testns",
403+
Labels: map[string]string{"olm.pod-spec-hash": "b0yrMl85J8bFjFWNl1O2XxsX698iPAjbpNhRIT", "olm.managed": "true"},
404+
Annotations: map[string]string{"cluster-autoscaler.kubernetes.io/safe-to-evict": "true"},
405+
},
406+
Spec: corev1.PodSpec{
407+
Volumes: []corev1.Volume{
408+
{
409+
Name: "utilities",
410+
VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}},
411+
},
412+
{
413+
Name: "catalog-content",
414+
VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}},
415+
},
416+
},
417+
InitContainers: []corev1.Container{
418+
{
419+
Name: "extract-utilities",
420+
Image: "utilImage",
421+
Command: []string{"cp"},
422+
Args: []string{"/bin/copy-content", "/utilities/copy-content"},
423+
VolumeMounts: []corev1.VolumeMount{{Name: "utilities", MountPath: "/utilities"}},
424+
TerminationMessagePolicy: "FallbackToLogsOnError",
425+
},
426+
{
427+
Name: "extract-content",
428+
Image: "image",
429+
ImagePullPolicy: image.InferImagePullPolicy("image"),
430+
Command: []string{"/utilities/copy-content"},
431+
Args: []string{
432+
"--catalog.from=/catalog",
433+
"--catalog.to=/extracted-catalog/catalog",
434+
},
435+
VolumeMounts: []corev1.VolumeMount{
436+
{Name: "utilities", MountPath: "/utilities"},
437+
{Name: "catalog-content", MountPath: "/extracted-catalog"},
438+
},
439+
TerminationMessagePolicy: "FallbackToLogsOnError",
440+
},
441+
},
442+
Containers: []corev1.Container{
443+
{
444+
Name: "name",
445+
Image: "opmImage",
446+
Command: []string{"/bin/opm"},
447+
Args: []string{"serve", "/extracted-catalog/catalog", "--cache-dir=/extracted-catalog/cache"},
448+
Ports: []corev1.ContainerPort{{Name: "grpc", ContainerPort: 50051}},
449+
ReadinessProbe: &corev1.Probe{
450+
ProbeHandler: corev1.ProbeHandler{
451+
Exec: &corev1.ExecAction{
452+
Command: []string{"grpc_health_probe", "-addr=:50051"},
453+
},
454+
},
455+
InitialDelaySeconds: 0,
456+
TimeoutSeconds: 5,
457+
},
458+
LivenessProbe: &corev1.Probe{
459+
ProbeHandler: corev1.ProbeHandler{
460+
Exec: &corev1.ExecAction{
461+
Command: []string{"grpc_health_probe", "-addr=:50051"},
462+
},
463+
},
464+
InitialDelaySeconds: 0,
465+
TimeoutSeconds: 5,
466+
},
467+
StartupProbe: &corev1.Probe{
468+
ProbeHandler: corev1.ProbeHandler{
469+
Exec: &corev1.ExecAction{
470+
Command: []string{"grpc_health_probe", "-addr=:50051"},
471+
},
472+
},
473+
FailureThreshold: 10,
474+
PeriodSeconds: 10,
475+
TimeoutSeconds: 5,
476+
},
477+
Resources: corev1.ResourceRequirements{
478+
Requests: corev1.ResourceList{
479+
corev1.ResourceCPU: resource.MustParse("10m"),
480+
corev1.ResourceMemory: resource.MustParse("50Mi"),
481+
},
482+
},
483+
SecurityContext: &corev1.SecurityContext{
484+
ReadOnlyRootFilesystem: ptr.To(false),
485+
},
486+
ImagePullPolicy: image.InferImagePullPolicy("image"),
487+
TerminationMessagePolicy: "FallbackToLogsOnError",
488+
VolumeMounts: []corev1.VolumeMount{{Name: "catalog-content", MountPath: "/extracted-catalog"}},
489+
},
490+
},
491+
NodeSelector: map[string]string{"kubernetes.io/os": "linux"},
492+
ServiceAccountName: "service-account",
493+
},
494+
},
495+
},
383496
{
384497
name: "content extraction not requested - restricted security context config",
385498
input: &v1alpha1.CatalogSource{
@@ -586,6 +699,134 @@ func TestPodExtractContent(t *testing.T) {
586699
},
587700
},
588701
},
702+
{
703+
name: "content extraction expected - restricted security context config, no catalog cache dir",
704+
input: &v1alpha1.CatalogSource{
705+
ObjectMeta: metav1.ObjectMeta{
706+
Name: "test",
707+
Namespace: "testns",
708+
},
709+
Spec: v1alpha1.CatalogSourceSpec{
710+
GrpcPodConfig: &v1alpha1.GrpcPodConfig{
711+
ExtractContent: &v1alpha1.ExtractContentConfig{
712+
CatalogDir: "/catalog",
713+
},
714+
},
715+
},
716+
},
717+
securityContextConfig: v1alpha1.Restricted,
718+
expected: &corev1.Pod{
719+
ObjectMeta: metav1.ObjectMeta{
720+
GenerateName: "test-",
721+
Namespace: "testns",
722+
Labels: map[string]string{"olm.pod-spec-hash": "3qxzUcTKDfq8QwZPoXteAv35FSwRho7vyYkv4d", "olm.managed": "true"},
723+
Annotations: map[string]string{"cluster-autoscaler.kubernetes.io/safe-to-evict": "true"},
724+
},
725+
Spec: corev1.PodSpec{
726+
Volumes: []corev1.Volume{
727+
{
728+
Name: "utilities",
729+
VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}},
730+
},
731+
{
732+
Name: "catalog-content",
733+
VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}},
734+
},
735+
},
736+
InitContainers: []corev1.Container{
737+
{
738+
Name: "extract-utilities",
739+
Image: "utilImage",
740+
Command: []string{"cp"},
741+
Args: []string{"/bin/copy-content", "/utilities/copy-content"},
742+
SecurityContext: &corev1.SecurityContext{
743+
Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}},
744+
AllowPrivilegeEscalation: ptr.To(false),
745+
},
746+
VolumeMounts: []corev1.VolumeMount{{Name: "utilities", MountPath: "/utilities"}},
747+
TerminationMessagePolicy: "FallbackToLogsOnError",
748+
},
749+
{
750+
Name: "extract-content",
751+
Image: "image",
752+
ImagePullPolicy: image.InferImagePullPolicy("image"),
753+
Command: []string{"/utilities/copy-content"},
754+
Args: []string{
755+
"--catalog.from=/catalog",
756+
"--catalog.to=/extracted-catalog/catalog",
757+
},
758+
SecurityContext: &corev1.SecurityContext{
759+
Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}},
760+
AllowPrivilegeEscalation: ptr.To(false),
761+
},
762+
VolumeMounts: []corev1.VolumeMount{
763+
{Name: "utilities", MountPath: "/utilities"},
764+
{Name: "catalog-content", MountPath: "/extracted-catalog"},
765+
},
766+
TerminationMessagePolicy: "FallbackToLogsOnError",
767+
},
768+
},
769+
Containers: []corev1.Container{
770+
{
771+
Name: "name",
772+
Image: "opmImage",
773+
Command: []string{"/bin/opm"},
774+
Args: []string{"serve", "/extracted-catalog/catalog", "--cache-dir=/extracted-catalog/cache"},
775+
Ports: []corev1.ContainerPort{{Name: "grpc", ContainerPort: 50051}},
776+
ReadinessProbe: &corev1.Probe{
777+
ProbeHandler: corev1.ProbeHandler{
778+
Exec: &corev1.ExecAction{
779+
Command: []string{"grpc_health_probe", "-addr=:50051"},
780+
},
781+
},
782+
InitialDelaySeconds: 0,
783+
TimeoutSeconds: 5,
784+
},
785+
LivenessProbe: &corev1.Probe{
786+
ProbeHandler: corev1.ProbeHandler{
787+
Exec: &corev1.ExecAction{
788+
Command: []string{"grpc_health_probe", "-addr=:50051"},
789+
},
790+
},
791+
InitialDelaySeconds: 0,
792+
TimeoutSeconds: 5,
793+
},
794+
StartupProbe: &corev1.Probe{
795+
ProbeHandler: corev1.ProbeHandler{
796+
Exec: &corev1.ExecAction{
797+
Command: []string{"grpc_health_probe", "-addr=:50051"},
798+
},
799+
},
800+
FailureThreshold: 10,
801+
PeriodSeconds: 10,
802+
TimeoutSeconds: 5,
803+
},
804+
Resources: corev1.ResourceRequirements{
805+
Requests: corev1.ResourceList{
806+
corev1.ResourceCPU: resource.MustParse("10m"),
807+
corev1.ResourceMemory: resource.MustParse("50Mi"),
808+
},
809+
},
810+
ImagePullPolicy: image.InferImagePullPolicy("image"),
811+
SecurityContext: &corev1.SecurityContext{
812+
Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}},
813+
AllowPrivilegeEscalation: ptr.To(false),
814+
ReadOnlyRootFilesystem: ptr.To(false),
815+
},
816+
TerminationMessagePolicy: "FallbackToLogsOnError",
817+
VolumeMounts: []corev1.VolumeMount{{Name: "catalog-content", MountPath: "/extracted-catalog"}},
818+
},
819+
},
820+
NodeSelector: map[string]string{"kubernetes.io/os": "linux"},
821+
SecurityContext: &corev1.PodSecurityContext{
822+
RunAsUser: ptr.To(int64(workloadUserID)),
823+
RunAsNonRoot: ptr.To(true),
824+
SeccompProfile: &corev1.SeccompProfile{Type: corev1.SeccompProfileTypeRuntimeDefault},
825+
},
826+
ServiceAccountName: "service-account",
827+
},
828+
},
829+
},
589830
}
590831

591832
for _, testCase := range testCases {

vendor/github.com/operator-framework/api/crds/operators.coreos.com_catalogsources.yaml

+1-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/operator-framework/api/crds/zz_defs.go

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/catalogsource_types.go

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)