Skip to content

feat: replace extractContent emptyDir+initContainers with image volumes#3806

Open
joelanford wants to merge 1 commit intooperator-framework:masterfrom
joelanford:image-volume-extract-content
Open

feat: replace extractContent emptyDir+initContainers with image volumes#3806
joelanford wants to merge 1 commit intooperator-framework:masterfrom
joelanford:image-volume-extract-content

Conversation

@joelanford
Copy link
Copy Markdown
Member

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:

  • Pod shape: 0 init containers (was 2), 1 image volume for opm (was 2-3 emptyDirs)
  • Main container image is now the catalog image (was opmImage), with opm binary
    from image volume
  • Digest change detection preserved: ContainerStatuses[0].ImageID returns the catalog
    image digest
  • utilImage removed from registry reconciler path (still used by bundle unpacker)
  • cmd/copy-content binary deleted (no longer needed)
  • Requires Kubernetes 1.33+ with ImageVolume feature gate (beta, enabled by default)

Testing remarks:

  • All unit tests updated and passing (make unit with Go 1.25.7 + setup-envtest)
  • go vet, golangci-lint clean
  • e2e test "configure gRPC registry pod to extract content" validated

Reviewer Checklist

  • Implementation matches the proposed design, or proposal is updated to match
  • Sufficient unit test coverage
  • Sufficient end-to-end test coverage
  • Commit messages sensible and descriptive
  • Code is properly formatted

@openshift-ci openshift-ci bot requested review from dtfranz and perdasilva March 31, 2026 18:21
@openshift-ci
Copy link
Copy Markdown

openshift-ci bot commented Mar 31, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign pedjak for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@joelanford joelanford force-pushed the image-volume-extract-content branch from 5b5b3fb to 6636b9d Compare March 31, 2026 18:26
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>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 extractContent pod wiring from emptyDir + 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-content binary 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.

Comment on lines +273 to +275
return pod.Spec.Volumes[0].Name == opmVolumeName &&
pod.Spec.Volumes[0].VolumeSource.Image != nil &&
pod.Spec.Volumes[0].VolumeSource.Image.Reference == source.opmImage
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a reasonable suggestion, but we are explicitly structuring the pod in a particular way.

Comment on lines +890 to +895
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)
}
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants