Skip to content

docs: add CI plugin image sync guidance to common.go - #2346

Draft
kaovilai wants to merge 1 commit into
openshift:oadp-devfrom
redhat-chai-bot:ci-plugin-image-sync-docs
Draft

docs: add CI plugin image sync guidance to common.go#2346
kaovilai wants to merge 1 commit into
openshift:oadp-devfrom
redhat-chai-bot:ci-plugin-image-sync-docs

Conversation

@kaovilai

@kaovilai kaovilai commented Jul 31, 2026

Copy link
Copy Markdown
Member

Adds a Go comment block above // Images in pkg/common/common.go explaining:

Supersedes #2345 (which targeted oadp-1.6 and included a separate docs/ guide + config/manager/manager.yaml changes) — this PR is comment-only, targets oadp-dev, no docs/ file.

pairs to openshift/release#82762

Note

Proposed by chai-bot (redhat-chai-bot), opened as draft via Claude Code. AI-generated — review for accuracy.

Summary by CodeRabbit

  • Documentation
    • Added guidance for keeping plugin image constants synchronized with related image variables and CI configuration.

@openshift-ci

openshift-ci Bot commented Jul 31, 2026

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 31, 2026
@openshift-ci

openshift-ci Bot commented Jul 31, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: kaovilai

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

The pull request process is described 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

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 31, 2026
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c808a73b-e78e-4a16-936f-fe26b94df8b2

📥 Commits

Reviewing files that changed from the base of the PR and between 9ab9a49 and 8052cf3.

📒 Files selected for processing (1)
  • pkg/common/common.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/common/common.go

Walkthrough

The change adds documentation for synchronizing plugin image constants, RELATED_IMAGE_* variables, and OpenShift CI configuration across OADP release branches.

Changes

Image Synchronization Documentation

Layer / File(s) Summary
Maintenance requirements documentation
pkg/common/common.go
Documents the required synchronization between plugin image constants, manager image environment variables, and ci-operator configuration.

Estimated code review effort: 1 (Trivial) | ~2 minutes

🚥 Pre-merge checks | ✅ 14 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the change but omits the required template sections and provides no testing or verification steps. Add the required “Why the changes were made” and “How to test the changes made” sections, including concrete verification commands or steps.
✅ Passed checks (14 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the documentation added for CI plugin image synchronization.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed The PR changes only a documentation comment in pkg/common/common.go; it adds no Ginkgo test declarations or test titles to assess.
Test Structure And Quality ✅ Passed The parent-to-current diff changes only 22 comment lines in pkg/common/common.go and adds no Ginkgo test code, so the test-quality requirements are not applicable.
Microshift Test Compatibility ✅ Passed The PR changes only a documentation comment in pkg/common/common.go and adds no Ginkgo e2e tests or MicroShift-incompatible test references.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The commit changes only a documentation comment in pkg/common/common.go and adds no Ginkgo e2e tests or multi-node assumptions.
Topology-Aware Scheduling Compatibility ✅ Passed Not applicable: the PR changes only comments in pkg/common/common.go and adds no deployment manifests, controllers, operator logic, or scheduling constraints.
Ote Binary Stdout Contract ✅ Passed The PR changes only a Go comment block; it adds no main, init, suite setup, logging, or stdout writes, so it cannot violate the OTE JSON stdout contract.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The commit changes only a Go comment block in pkg/common/common.go; it adds no Ginkgo tests, IPv4 assumptions, or external connectivity logic.
No-Weak-Crypto ✅ Passed The patch changes only a 22-line documentation comment; the added-line scan found no MD5, SHA1, DES, RC4, Blowfish, ECB, custom crypto, or secret-comparison usage.
Container-Privileges ✅ Passed The commit changes only a Go comment. It adds no Kubernetes manifest or privilege setting, and manager.yaml uses runAsNonRoot with allowPrivilegeEscalation: false.
No-Sensitive-Data-In-Logs ✅ Passed The patch only adds a comment block in pkg/common/common.go; it adds no logging and no passwords, tokens, API keys, PII, hostnames, or customer data.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/common/common.go`:
- Around line 70-87: Correct the synchronization guidance associated with the
image constants near RegistryImage: either add the missing
RELATED_IMAGE_REGISTRY mapping in config/manager/manager.yaml or exclude
RegistryImage from the contract. Standardize the CI image tag example as latest
rather than :latest, and state that operator.substitutions and base_images are
required only when defined by the affected branch configuration, not as a
universal pair.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 947b55a1-cb01-4463-894c-4df6975d4c7e

📥 Commits

Reviewing files that changed from the base of the PR and between 6f5bb6c and 9ab9a49.

📒 Files selected for processing (1)
  • pkg/common/common.go

Comment thread pkg/common/common.go
Comment on lines +70 to +87
// Each image constant below corresponds to a RELATED_IMAGE_* environment variable
// in config/manager/manager.yaml. In production, OLM injects these from the CSV;
// during CI e2e tests, ci-operator substitutes them with freshly-built CI images
// so that tests always run against the latest plugin code.
//
// To keep CI substitutions in sync, every image here must have a matching pair of
// entries in the openshift/release ci-operator config for each OADP release branch:
//
// 1. A base_images entry that imports the image from the CI registry
// (namespace: konveyor, name: <plugin>, tag: <branch or :latest>).
//
// 2. An operator.substitutions entry that replaces the quay.io pullspec
// in the CSV with the CI image reference.
//
// When adding, removing, or renaming a plugin image constant:
// - Update the corresponding RELATED_IMAGE_* env var in config/manager/manager.yaml
// - Update the base_images + operator.substitutions in openshift/release
// ci-operator/config/openshift/oadp-operator/ for every affected branch config

@coderabbitai coderabbitai Bot Jul 31, 2026

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.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Image constants:"
rg -n '^[[:space:]]*[A-Za-z0-9]+Image[[:space:]]*=' pkg/common/common.go

echo "RELATED_IMAGE mappings:"
fd --type f --hidden --glob 'manager.yaml' . \
  | while read -r file; do
      rg -n -C 2 'RELATED_IMAGE_|image:' "$file"
    done

echo "OpenShift CI configurations:"
fd --type f --hidden --glob '*.yaml' . \
  | rg 'ci-operator/config/openshift/oadp-operator/' \
  | while read -r file; do
      rg -n -C 3 'base_images:|substitutions:|RELATED_IMAGE_|quay.io/' "$file"
    done

Repository: openshift/oadp-operator

Length of output: 3665


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Tracked candidate files:"
git ls-files \
  'pkg/common/common.go' \
  '*manager.yaml' \
  '*ci-operator*' \
  '*oadp-operator*' \
  | sed -n '1,160p'

echo
echo "Common constants and usages:"
cat -n pkg/common/common.go | sed -n '60,115p'
rg -n -C 2 'VeleroImage|OpenshiftPluginImage|AWSPluginImage|LegacyAWSPluginImage|AzurePluginImage|GCPPluginImage|RegistryImage|KubeVirtPluginImage|KubeVirtDatamoverPluginImage|HypershiftPluginImage' .

echo
echo "Manager configuration:"
fd --type f --hidden --glob 'manager.yaml' . -x sh -c 'echo "--- $1"; cat -n "$1"' sh {} \;

echo
echo "CI configuration references:"
rg -n -C 3 'base_images|operator:|substitutions|RELATED_IMAGE_|quay.io/(konveyor|redhat-user-workloads)' . \
  -g '*.yaml' -g '*.yml' -g '*.json' || true

Repository: openshift/oadp-operator

Length of output: 50382


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

common = Path("pkg/common/common.go").read_text()
manager_files = list(Path(".").rglob("manager.yaml"))
constants = dict(re.findall(
    r'^\s*(\w+Image)\s*=\s*"([^"]+)"',
    common,
    re.M,
))
print("constant_count:", len(constants))
for name, pullspec in constants.items():
    env = "RELATED_IMAGE_" + re.sub(r'(?<!^)(?=[A-Z])', '_', name[:-5]).upper()
    print(f"{name}\t{env}\t{pullspec}")

for path in manager_files:
    text = path.read_text()
    print(f"\nmanager_file: {path}")
    for m in re.finditer(r'name:\s*(RELATED_IMAGE_[A-Z0-9_]+)\s*\n\s*value:\s*([^\s]+)', text):
        print(f"{m.group(1)}\t{m.group(2)}")

ci_files = [
    p for p in Path(".").rglob("*")
    if p.is_file() and "ci-operator/config/openshift/oadp-operator/" in p.as_posix()
]
print("\nci_file_count:", len(ci_files))
for path in ci_files:
    print(path)
PY

Repository: openshift/oadp-operator

Length of output: 2705


🌐 Web query:

site:github.com/openshift/release "ci-operator/config/openshift/oadp-operator" "base_images" "substitutions"

💡 Result:

In the context of OpenShift's ci-operator configuration files—such as those found under ci-operator/config/openshift/oadp-operator/base_images are used to define the source container images required for building, testing, or running the operator's lifecycle [1][2][3]. While there is no specific top-level key explicitly named substitutions within the standard ci-operator configuration schema, image substitution and overriding in OpenShift CI typically occur through a few established mechanisms: 1. Base Image Definitions: The base_images block identifies specific container images (referenced by name, namespace, and tag) that serve as dependencies [1][2][3][4]. These can be referenced in images build steps or test definitions [1][3][5]. 2. Environment Variable Injection: Configuration files often use shell-style variable expansion (e.g., $(BRANCH)) to inject dynamic values into the configuration at runtime [6]. This is frequently used to align image tags with specific OpenShift release branches [6]. 3. Release-Based Overrides: CI jobs often use environment variables like RELEASE_IMAGE_LATEST or RELEASE_IMAGE_INITIAL to substitute entire release payload images, which the ci-operator can then resolve or utilize as a source for base_images [6]. 4. Image Mirroring and Mapping: Outside of the individual config file, the OpenShift CI infrastructure uses image-mirror-mappings (configured in the ci namespace) to transparently redirect image pulls from one registry or repository to another, effectively substituting the underlying image source without changing the operator's ci-operator config [5]. If you are encountering a reference to "substitutions" in documentation or a specific script, it likely refers to these dynamic injection points or the external infrastructure-level mirroring mappings that ensure the correct images are pulled during the CI process [6][5].

Citations:


🌐 Web query:

OpenShift ci-operator configuration base_images tag field operator substitutions syntax

💡 Result:

In OpenShift ci-operator configurations, the operator.substitutions field is used to replace specific image pull specifications within operator manifests with images built or imported during the CI process [1][2]. This mechanism ensures that operator bundles, which are often created for testing, reference the correct, freshly built versions of operands and operators rather than hardcoded external pull specs [1]. The configuration for operator substitutions follows this structure under the operator top-level key [2]: operator: substitutions: - pullspec: <string_to_replace> with: <replacement_string> Field Details: - pullspec: This defines the exact string (the pull specification) found in the operator manifests that needs to be replaced [2]. - with: This defines the replacement string. Typically, this is a reference to a CI-managed image in the format pipeline:<image_name> [1][2]. How it relates to base_images and image resolution: While base_images are used to import external or pre-existing images into the CI pipeline (making them available as ImageStreamTags) [3][4], operator substitutions specifically bridge the gap between static manifests and these dynamic CI images [1]. When the BundleSourceStep runs, it scans the operator manifests, identifies occurrences of the strings defined in the pullspec field, and replaces them with the actual pull specification of the corresponding image in the pipeline ImageStream [5][1]. Example: If you have an operand imported via base_images and an operator built in your repository (defined in the images section), your configuration might look like this [1]: base_images: operand: namespace: ocp name: operand tag: latest images: tested-operator:... operator: substitutions: - pullspec: "quay.io/example/operand:1.0" with: "pipeline:operand" - pullspec: "quay.io/example/operator:1.0" with: "pipeline:tested-operator" In this example, any occurrence of the external quay.io pull specs in the operator manifests will be replaced by the resolved pull specifications of the pipeline:operand and pipeline:tested-operator images [1][2].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import json
import urllib.request

url = "https://api.github.com/repos/openshift/release/contents/ci-operator/config/openshift/oadp-operator"
request = urllib.request.Request(url, headers={"Accept": "application/vnd.github+json"})
try:
    with urllib.request.urlopen(request, timeout=20) as response:
        data = json.load(response)
except Exception as exc:
    print(f"external_lookup_error: {exc}")
    raise SystemExit(0)

for item in data:
    print(item.get("name", ""))
PY

echo
echo "Local ci-operator schema references:"
rg -n -C 3 'base_images:|operator:|substitutions:|tag:' . \
  -g '*.yaml' -g '*.yml' \
  | sed -n '1,240p' || true

Repository: openshift/oadp-operator

Length of output: 27565


🌐 Web query:

site:github.com/openshift/release/ci-operator/config/openshift/oadp-operator base_images operator substitutions

💡 Result:

The matching OpenShift CI configuration is:

  • Directory: openshift/release/ci-operator/config/openshift/oadp-operator (github.com)
  • OADP 1.6 / OCP 5.0: openshift-oadp-operator-oadp-1.6__5.0.yaml
    • Uses bundle substitution:
      • quay.io/konveyor/oadp-operator:oadp-1.6
      • replaced with oadp-operator-1.6 (github.com)
  • Development / OCP 5.0: openshift-oadp-operator-oadp-dev__5.0.yaml
    • Uses:
      • quay.io/konveyor/oadp-operator:latest
      • replaced with oadp-operator (github.com)

No base_images entry is present in these files.

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

api='https://api.github.com/repos/openshift/release/contents/ci-operator/config/openshift/oadp-operator'
json="$(curl -ksSfL "$api")"

python3 - "$json" <<'PY'
import json, sys
items = json.loads(sys.argv[1])
for item in items:
    if item.get("name", "").endswith((".yaml", ".yml")):
        print(item["name"])
PY

echo
for file in \
  openshift-oadp-operator-oadp-1.6__5.0.yaml \
  openshift-oadp-operator-oadp-dev__5.0.yaml
do
  url="https://raw.githubusercontent.com/openshift/release/master/ci-operator/config/openshift/oadp-operator/$file"
  echo "--- $file"
  content="$(curl -ksSfL "$url" || true)"
  if [ -z "$content" ]; then
    echo "not found"
    continue
  fi
  printf '%s\n' "$content" | rg -n -C 3 \
    '^(base_images:|operator:|  substitutions:|    - pullspec:|      with:)|quay.io/konveyor/|pipeline:|RELATED_IMAGE_' \
    | sed -n '1,220p'
done

Repository: openshift/oadp-operator

Length of output: 263


Correct the image synchronization contract.

RegistryImage has no RELATED_IMAGE_REGISTRY entry in config/manager/manager.yaml. Exclude it from this contract or add the missing mapping. Use tag: latest, not tag: :latest. The cited OADP configurations use operator.substitutions without base_images, so do not require both entries unless each branch defines them.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/common/common.go` around lines 70 - 87, Correct the synchronization
guidance associated with the image constants near RegistryImage: either add the
missing RELATED_IMAGE_REGISTRY mapping in config/manager/manager.yaml or exclude
RegistryImage from the contract. Standardize the CI image tag example as latest
rather than :latest, and state that operator.substitutions and base_images are
required only when defined by the affected branch configuration, not as a
universal pair.

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.

Thanks for the review. Addressing each point:

1. RegistryImage has no RELATED_IMAGE_REGISTRY in manager.yaml — This is a pre-existing state, not introduced by this PR. The comment says "each image constant below corresponds to a RELATED_IMAGE_*" which is aspirational guidance for the general pattern. Whether RegistryImage specifically needs a RELATED_IMAGE_ mapping is a separate concern tracked in #2343. Not changing the guidance here.

2. tag: :latesttag: latest — Valid catch. The ci-operator YAML tag field takes the bare value latest without a colon prefix. Will fix.

3. base_images + operator.substitutions pairing — The guidance is correct for the pattern being introduced in openshift/release#82762. Plugin images from promoted CI builds (not built from source in the current repo) require both: base_images to import from the CI registry, and operator.substitutions to rewrite the CSV pullspec. The existing substitution-only pattern applies to the operator image itself (built from source via images stanza, referenced as pipeline:<name>), which is a different case. No change needed.

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.

@redhat-chai-bot, thank you for the clarification.

The tag: latest correction is valid.

The base_images and operator.substitutions guidance is valid for promoted plugin images. Please state that scope in the comment. The current text says that each image constant below follows this contract. That statement includes RegistryImage, which has no corresponding RELATED_IMAGE_* variable.

The fact that RegistryImage predates this PR does not make the new universal statement accurate. Please either exclude RegistryImage from the contract or change the contract to apply only to plugin images that have RELATED_IMAGE_* variables.


✏️ Learnings added
Learnt from: redhat-chai-bot
Repo: openshift/oadp-operator PR: 2346
File: pkg/common/common.go:70-87
Timestamp: 2026-08-01T03:57:00.124Z
Learning: For OADP CI configuration, promoted plugin images that are not built from source in the oadp-operator repository require both `base_images` and `operator.substitutions`. The existing substitution-only pattern applies to the operator image built through the `images` stanza and referenced as `pipeline:<name>`.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@redhat-chai-bot
redhat-chai-bot force-pushed the ci-plugin-image-sync-docs branch from 9ab9a49 to 8052cf3 Compare August 1, 2026 04:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants