feat: replace extractContent emptyDir+initContainers with image volumes#3806
feat: replace extractContent emptyDir+initContainers with image volumes#3806joelanford wants to merge 1 commit intooperator-framework:masterfrom
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
5b5b3fb to
6636b9d
Compare
Use Kubernetes image volumes to eliminate disk I/O during catalog pod startup. The catalog image becomes the main container image (providing catalog data via its root filesystem), and the opm binary is provided by mounting the opmImage as an image volume. - Remove init containers and data-copying emptyDir volumes - Remove utilImage from registry reconciler (still used by bundle unpacker) - Simplify correctImages() and imageID() functions - Delete cmd/copy-content/ binary (no longer needed) - Update Dockerfile and .goreleaser.yml build targets Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6636b9d to
20939b0
Compare
There was a problem hiding this comment.
Pull request overview
This PR updates the gRPC registry extractContent pod construction to eliminate init-container-based copying and instead mount the opm binary via Kubernetes Image Volumes, using the catalog image as the main container image. It also removes the now-unneeded copy-content utility and updates associated unit tests and release packaging.
Changes:
- Replace
extractContentpod wiring fromemptyDir+ init containers to an Image Volume mounted at/opm. - Update reconciler/image validation logic and tests to match the new pod shape and digest detection behavior.
- Remove the
cmd/copy-contentbinary from the repo and release artifacts (Dockerfile + GoReleaser + docs updates).
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/controller/registry/reconciler/reconciler.go | Refactors Pod() to mount opm from an Image Volume and run catalog image as the main container. |
| pkg/controller/registry/reconciler/reconciler_test.go | Updates pod shape expectations and adds assertions for Image Volume pull policy behavior. |
| pkg/controller/registry/reconciler/grpc.go | Removes utilImage usage and updates “correct image/spec” detection for Image Volume-based pods. |
| pkg/controller/registry/reconciler/grpc_test.go | Updates imageID-related tests to match the new single-container status behavior. |
| pkg/controller/registry/reconciler/configmap.go | Updates Pod() call signature after removing utilImage. |
| pkg/controller/operators/catalog/operator.go | Updates reconciler factory construction after removing utilImage from that path. |
| pkg/controller/operators/catalog/operator_test.go | Updates fake operator wiring and test pod helper for new Pod() signature. |
| Dockerfile | Removes copy-content from the built image payload. |
| cmd/copy-content/main.go | Deletes the obsolete copy-content command implementation. |
| AGENTS.md | Updates repository layout docs to remove the deleted utility. |
| .goreleaser.yml | Removes copy-content build from release configuration. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return pod.Spec.Volumes[0].Name == opmVolumeName && | ||
| pod.Spec.Volumes[0].VolumeSource.Image != nil && | ||
| pod.Spec.Volumes[0].VolumeSource.Image.Reference == source.opmImage |
There was a problem hiding this comment.
correctImages assumes the opm image volume is always pod.Spec.Volumes[0]. This is brittle (any future volume added ahead of it will break the check and force unnecessary pod churn). Consider searching pod.Spec.Volumes for Name == opmVolumeName and validating that volume’s VolumeSource.Image.Reference instead of indexing at 0.
| return pod.Spec.Volumes[0].Name == opmVolumeName && | |
| pod.Spec.Volumes[0].VolumeSource.Image != nil && | |
| pod.Spec.Volumes[0].VolumeSource.Image.Reference == source.opmImage | |
| for _, volume := range pod.Spec.Volumes { | |
| if volume.Name != opmVolumeName { | |
| continue | |
| } | |
| return volume.VolumeSource.Image != nil && | |
| volume.VolumeSource.Image.Reference == source.opmImage | |
| } | |
| return false |
There was a problem hiding this comment.
This is a reasonable suggestion, but we are explicitly structuring the pod in a particular way.
| if tt.extractContent { | ||
| require.NotEmpty(t, p.Spec.Volumes, "expected at least one volume for extractContent") | ||
| require.NotNil(t, p.Spec.Volumes[0].VolumeSource.Image, "expected image volume source") | ||
| if p.Spec.Volumes[0].VolumeSource.Image.PullPolicy != tt.opmPolicy { | ||
| t.Fatalf("expected opm image volume pull policy %s for opm image %s, got %s", tt.opmPolicy, tt.opmImage, p.Spec.Volumes[0].VolumeSource.Image.PullPolicy) | ||
| } |
There was a problem hiding this comment.
This test asserts the opm image volume using p.Spec.Volumes[0], which couples the test to volume ordering. To make the test resilient to future volumes being added, consider locating the volume by Name == opmVolumeName (or "opm") before asserting on VolumeSource.Image.PullPolicy.
Description of the change:
Replace the extractContent pod construction to use Kubernetes image volumes
(beta in K8s 1.33+) instead of emptyDir volumes and init containers. The catalog
image becomes the main container image (its filesystem already contains the catalog
data), and the opm binary is provided by mounting opmImage as an image volume at /opm.
Motivation for the change:
The current extractContent approach copies large amounts of data via init containers
at every pod startup, causing excessive disk I/O, slow startup times, and bugs for
users with large catalogs. Image volumes eliminate all data copying by mounting image
filesystems directly.
Architectural changes:
from image volume
image digest
Testing remarks:
make unitwith Go 1.25.7 + setup-envtest)go vet,golangci-lintcleanReviewer Checklist