Skip to content

feat: make operator and data-plane image registry configurable - #464

Open
WentingWu666666 wants to merge 2 commits into
documentdb:mainfrom
WentingWu666666:developer/wenting-configurable-image-registry
Open

WentingWu666666 wants to merge 2 commits into
documentdb:mainfrom
WentingWu666666:developer/wenting-configurable-image-registry

Conversation

@WentingWu666666

Copy link
Copy Markdown
Collaborator

What

Make the operator and data-plane container images registry-configurable so the same operator binary and Helm chart can be repointed at a different registry (a public registry upstream, or a private/mirrored registry) without a code change. Default rendering is byte-identical to today's ghcr.io/... references, so existing deployments are unaffected.

Why

Downstream consumers (private mirrors, air-gapped/regulated environments) need to source every image from a single registry they control, without forking the chart or rebuilding the operator.

How

Single prefix + relative repository + verbatim clause.

  • values.yaml gains image.registry (default ghcr.io) and relative per-component repositories.
  • New documentdb.imageRef Helm helper implements the canonical Docker/containerd host-detection rule: if a repository's first path segment looks like a host (contains . or :, or equals localhost) it is used verbatim and the registry prefix is ignored; otherwise the prefix is prepended. An empty tag yields a bare repository. This lets you either re-home everything via one image.registry, or override any single component with a full ref.
  • Gateway/DocumentDB image pull policies are nested under image.{gateway,documentdb}.pullPolicy with explicit IfNotPresent defaults; added image.otelCollector / image.postgres seams (default to the operator's built-in images; postgres empty defers to CloudNativePG).
  • The chart passes data-plane image repositories (and optional otel/postgres refs) to the operator via environment variables.

Operator side:

  • Env-backed image-source getters (ExtensionImageRepo, GatewayImageRepo, OtelCollectorImage, PostgresImage) with compiled-in fallbacks.
  • Extracted DEFAULT_DOCUMENTDB_TAG and simplified ResolveComponentImage to compose repo:tag from a single default tag, so a registry override flows through to the default image as well.

Testing

  • go build ./..., go vet, gofmt, full go test ./... — all pass.
  • Helm: helm lint clean, helm unittest 98/98 (added registry-prefix, full-ref verbatim, localhost / localhost:port verbatim, data-plane env, and pull-policy default/empty cases).
  • helm template verified: defaults byte-identical to upstream ghcr.io/...:0.3.0; a registry override re-homes all images; per-component full refs are used verbatim.

Introduce a single registry-prefix model so the same operator binary and
Helm chart can be repointed at a different registry (public upstream, or a
private/mirrored registry) without a code change.

Helm:
- Add image.registry prefix and relative per-component repositories.
- Add documentdb.imageRef helper implementing the canonical Docker/
  containerd host-detection rule: a repository whose first path segment
  looks like a host (contains '.' or ':', or equals localhost) is used
  verbatim and the registry prefix is ignored; otherwise the prefix is
  prepended. Empty tag yields a bare repository.
- Nest gateway/documentdb pull policies under image.{gateway,documentdb}
  and set explicit IfNotPresent defaults; add image.otelCollector and
  image.postgres seams (default to the operator's built-in images).
- Pass data-plane image repositories and optional otel/postgres refs to
  the operator via environment variables.

Operator:
- Add env-backed image-source getters (ExtensionImageRepo, GatewayImageRepo,
  OtelCollectorImage, PostgresImage) with compiled-in fallbacks.
- Extract DEFAULT_DOCUMENTDB_TAG and simplify ResolveComponentImage to
  compose repo:tag from a single default tag, so a registry override flows
  through to the default image as well.

Default rendering is byte-identical to the previous ghcr.io references, so
existing deployments are unaffected.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e346b0ad-0a96-4275-ad25-875de64e4b21
Signed-off-by: Wenting Wu <wentingwu@microsoft.com>

Copilot AI left a comment

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.

Copilot review overview

🟡 Changes recommended

A critical release-workflow incompatibility and unresolved image-reference, registry, and pull-policy compatibility issues remain.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity · 2 Medium severity

Open (3)
What changed in this PR

This PR adds configurable registry and image-source handling for the operator and data-plane images through Helm values and operator environment variables.

Changes:

  • Adds host-aware registry and repository composition.
  • Adds configurable data-plane, OTel, and PostgreSQL image sources.
  • Updates image resolution, pull policies, and Helm test coverage.
File Summary
operator/​src/​internal/​utils/​util.go Image-source getters and resolution logic; design documentation is now stale.
operator/​src/​internal/​utils/​image_source_test.go Tests image-source defaults and overrides.
operator/​src/​internal/​utils/​constants.go Adds image constants and default tag; release workflow parsing must be updated.
operator/​src/​internal/​product/​profile.go Uses a default-tag model for image resolution.
operator/​src/​internal/​product/​profile_test.go Updates profile assertions.
operator/​src/​internal/​product/​documentdb.go Applies configurable image and PostgreSQL resolution.
operator/​src/​internal/​product/​documentdb_test.go Tests image overrides and resolution.
operator/​src/​internal/​cnpg/​cnpg_cluster.go Uses the configurable OTel image.
operator/​documentdb-helm-chart/​values.yaml Defines registry, repository, and pull-policy settings; compatibility and single-registry behavior need attention.
operator/​documentdb-helm-chart/​tests/​09_operator_deployment_test.yaml Adds image configuration and pull-policy coverage.
operator/​documentdb-helm-chart/​templates/​09_documentdb_operator.yaml Wires operator images and environment variables; full data-plane references and legacy pull-policy values need handling.
operator/​documentdb-helm-chart/​templates/​03_documentdb_wal_replica.yaml Uses registry-aware image rendering.
operator/​documentdb-helm-chart/​templates/​02_documentdb_sidecar_injector.yaml Uses registry-aware image rendering.
operator/​documentdb-helm-chart/​templates/​_helpers.tpl Implements canonical image-reference composition.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.


// DEFAULT_DOCUMENTDB_IMAGE is the extension image used in ImageVolume mode.
DEFAULT_DOCUMENTDB_IMAGE = DOCUMENTDB_EXTENSION_IMAGE_REPO + ":0.117.0"
DEFAULT_DOCUMENTDB_IMAGE = DOCUMENTDB_EXTENSION_IMAGE_REPO + ":" + DEFAULT_DOCUMENTDB_TAG

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in ef9c7b4. The release workflow now reads and rewrites DEFAULT_DOCUMENTDB_TAG (the single remaining version literal) instead of the DEFAULT_DOCUMENTDB_IMAGE line, which is now composed from repo + tag. Both the detect step (regex) and the update step (sed) were updated; verified the detection returns 0.117.0 and the bump rewrites the tag const.

Comment on lines +120 to +126
{{- if .Values.image.documentdb.repository }}
- name: DOCUMENTDB_EXTENSION_IMAGE_REPO
value: "{{ include "documentdb.imageRef" (dict "registry" .Values.image.registry "repo" .Values.image.documentdb.repository "tag" "") }}"
{{- end }}
{{- if .Values.image.gateway.repository }}
- name: GATEWAY_IMAGE_REPO
value: "{{ include "documentdb.imageRef" (dict "registry" .Values.image.registry "repo" .Values.image.gateway.repository "tag" "") }}"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in ef9c7b4, taking a stricter approach than composing a second path. Since a repository is defined as host/path only (the tag comes from the component tag field, or documentDbVersion for data-plane images), the documentdb.imageRef helper now rejects any repository whose final path segment already carries a tag (:) or digest (@) with an actionable error. All images (control-plane, data-plane repo env, otel, postgres) flow through this one helper, so this closes the double-tag hole everywhere without adding priority rules. Host ports like localhost:5000/repo are unaffected (only the last segment is inspected). Added helm-unittest cases for the embedded-tag and embedded-digest rejections.

Comment on lines +60 to +63
pullPolicy: IfNotPresent
gateway:
repository: documentdb/documentdb-kubernetes-operator/gateway
pullPolicy: IfNotPresent

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Acknowledged. Since the operator is in public preview, we're accepting this as a deliberate (preview-only) breaking change rather than carrying dual keys. To avoid it being silent, it's now documented under a new "Breaking Changes" entry in CHANGELOG (ef9c7b4): gatewayImagePullPolicy / documentDbImagePullPolicy → image.gateway.pullPolicy / image.documentdb.pullPolicy, with migration guidance.

…rd, changelog

- release_documentdb_images.yml: detect and bump DEFAULT_DOCUMENTDB_TAG
  instead of the now-composed DEFAULT_DOCUMENTDB_IMAGE literal, so the
  automated database-image version bump keeps working after the tag
  constant was factored out.
- documentdb.imageRef helper: reject a repository that already carries a
  tag or digest (':' or '@' in the final path segment) with an actionable
  error, so an embedded tag can no longer produce a double-tagged image
  reference on any component. Repositories are host/path only.
- CHANGELOG: document the configurable image registry feature and the
  breaking rename of the pull-policy values (gatewayImagePullPolicy /
  documentDbImagePullPolicy -> image.{gateway,documentdb}.pullPolicy).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e346b0ad-0a96-4275-ad25-875de64e4b21
Signed-off-by: Wenting Wu <wentingwu@microsoft.com>
value: "{{ .Values.image.gateway.pullPolicy }}"
{{- end }}
{{- if .Values.documentDbImagePullPolicy }}
{{- if .Values.image.documentdb.pullPolicy }}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

An invalid pull policy such as Sometimes renders successfully. Both consumers then silently fall back to their defaults, so the deployment does not use the policy the user requested. Can Helm reject values other than Always, IfNotPresent, and Never with a clear error?

{{- $first := (splitList "/" .repo) | first -}}
{{- $full := .repo -}}
{{- if not (or (contains "." $first) (contains ":" $first) (eq $first "localhost")) -}}
{{- $full = printf "%s/%s" .registry .repo -}}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

An empty image.registry or operator repository renders an invalid image such as /documentdb/...:0.3.0 or ghcr.io/:0.3.0. Helm reports success and the failure appears later at pod startup. Can we fail rendering with the name of the empty setting?

@documentdb-triage-tool documentdb-triage-tool Bot added CI/CD documentation Improvements or additions to documentation enhancement New feature or request go Pull requests that update go code test labels Sep 25, 2026
@documentdb-triage-tool

Copy link
Copy Markdown

🤖 Auto-triaged by documentdb-triage-tool.

Applied: go, test, CI/CD, documentation, enhancement
Project fields suggested: Component controllers · Priority P2 · Effort L · Status Needs Review
Confidence: 0.82 (mixed)

Reasoning

component from path globs (controllers, test, ci, docs); effort from diff stats (436+55 LOC, 16 files); LLM: Multi-file change spanning Helm chart values/helpers, operator env-var plumbing, and new Helm unit tests to enable configurable image registries for air-gapped/mirrored deployments.

If a label is wrong, remove it manually and ping @patty-chow so the rules can be tuned. The bot will not re-label items that already have component labels.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI/CD documentation Improvements or additions to documentation enhancement New feature or request go Pull requests that update go code test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants