Skip to content

build-sync: Mirror RHCOS images to QCI#2991

Open
joepvd wants to merge 1 commit into
openshift-eng:mainfrom
joepvd:mirror-rhcos-to-qci
Open

build-sync: Mirror RHCOS images to QCI#2991
joepvd wants to merge 1 commit into
openshift-eng:mainfrom
joepvd:mirror-rhcos-to-qci

Conversation

@joepvd

@joepvd joepvd commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Tag RHCOS container images to QCI (quay.io/openshift/ci) during build-sync for external CI consumption.

Uses oc tag with reference mode (as suggested by reviewer) to create image references without copying bytes:

  • --reference-policy='source' - Reference points to source location
  • --import-mode='PreserveOriginal' - Preserve original manifest format
  • --reference - Create reference without importing image

QCI Pullspec Format

Images are tagged with:

  • Prunable tags (for cleanup): quay.io/openshift/ci:<timestamp>_prune_art__ocp_<version>_<tag>
  • Floating tags (latest): quay.io/openshift/ci:art__ocp_<version>_<tag>

Examples for OCP 4.17

Public images:

quay.io/openshift/ci:20260603120000_prune_art__ocp_4.17_rhel-coreos
quay.io/openshift/ci:art__ocp_4.17_rhel-coreos
quay.io/openshift/ci:art__ocp_4.17_rhel-coreos-extensions
quay.io/openshift/ci:art__ocp_4.17_machine-os-content
quay.io/openshift/ci:art__ocp_4.17_rhel-coreos-10
quay.io/openshift/ci:art__ocp_4.17_rhel-coreos-10-extensions

Private images (for openshift-priv CI):

quay.io/openshift/ci:art__ocp_4.17_priv_rhel-coreos
quay.io/openshift/ci:art__ocp_4.17_priv_rhel-coreos-extensions

Implementation Details

  • Added _mirror_rhcos_to_qci() orchestration method with guards for version ≥4.12, stream assembly, and QCI credentials
  • Added _mirror_single_rhcos_to_qci() to fetch ART imagestream pullspecs and tag to QCI
  • Uses same public ART imagestream source for both public and private (consistent with _tag_into_ci_imagestream)
  • QCI credentials via QCI_USER/QCI_PASSWORD environment variables (requires Jenkinsfile update in aos-cd-jobs)
  • Errors are logged and sent to Slack but don't fail the build (non-critical mirror)

Test Plan

  • Unit tests for success, skip conditions, dry-run, tag naming
  • Integration test with actual QCI credentials

@openshift-ci

openshift-ci Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

[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 jupierce 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

@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The PR adds QCI mirroring functionality to BuildSyncPipeline. It conditionally constructs QCI credentials from environment variables, adds a nightly-only mirroring flow that tags RHCOS images into QCI registries with version and gitref guards, and integrates the mirroring into the nightly pipeline after populating CI imagestreams.

Changes

RHCOS-to-QCI Mirroring Integration

Layer / File(s) Summary
Imports and Dependencies
pyartcd/pyartcd/pipelines/build_sync.py
Adds datetime import and imports RegistryCredential and REGISTRY_QUAY_CI to enable QCI auth construction and registry configuration.
QCI Credential and Registry Configuration
pyartcd/pyartcd/pipelines/build_sync.py
Updates run() to conditionally build QCI auth credentials from QCI_USER and QCI_PASSWORD environment variables, warn when either is missing, and append REGISTRY_QUAY_CI to registries passed to RegistryConfig.
RHCOS-to-QCI Mirroring Implementation
pyartcd/pyartcd/pipelines/build_sync.py
Introduces _mirror_rhcos_to_qci() that guards on RHCOS version (>= 4.12), assembly type (stream only), gitref override presence, and QCI credential availability; computes prune timestamps and schedules concurrent per-tag mirroring for both public and private QCI namespaces with Slack failure reporting. Introduces _mirror_single_rhcos_to_qci() helper that retrieves ART imagestream pullspecs, derives prunable and floating QCI tag names with optional _priv suffix, skips on missing/empty pullspecs, and performs oc tag reference-mode operations with retries.
Nightly Flow Integration
pyartcd/pyartcd/pipelines/build_sync.py
Wires _mirror_rhcos_to_qci() into the nightly pipeline immediately after _populate_ci_imagestreams().

🎯 4 (Complex) | ⏱️ ~45 minutes

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

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

🧹 Nitpick comments (3)
pyartcd/tests/pipelines/test_build_sync.py (2)

144-147: 💤 Low value

Test assertions may be fragile due to uses_konflux_imagestream_override dependency.

The assertions check for 'art-latest:rhel-coreos' but is_base_name depends on uses_konflux_imagestream_override(self.version). If this function returns False for version 4.17, the actual imagestream name would be 4.17-konflux-art-latest, causing these assertions to fail.

Consider mocking uses_konflux_imagestream_override or using a more flexible assertion pattern.

🤖 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 `@pyartcd/tests/pipelines/test_build_sync.py` around lines 144 - 147, The test
assertions are brittle because the imagestream name in the command depends on
uses_konflux_imagestream_override(self.version); update the test to either mock
uses_konflux_imagestream_override to return a known value for the tested version
or relax the assertions to accept both possible imagestream forms (e.g., check
for suffix ':rhel-coreos' and that the command contains either
'art-latest:rhel-coreos' or '4.17-konflux-art-latest:rhel-coreos'); locate the
call site around mock_cmd_gather and the helper
is_base_name/uses_konflux_imagestream_override to implement the mocking or
flexible assertion so the test no longer fails depending on the override result.

275-282: 💤 Low value

Use constant instead of hardcoded string for registry check.

Line 282 uses hardcoded 'quay.io/openshift' while line 275 already imports REGISTRY_QUAY_CI. Consider importing and using REGISTRY_QUAY_OPENSHIFT for consistency with the implementation.

         # Should include QCI registry
         from artcommonlib.constants import REGISTRY_QUAY_CI
+        from artcommonlib.constants import REGISTRY_QUAY_OPENSHIFT

         assert REGISTRY_QUAY_CI in call_kwargs['registries']

         # Should include QCI credentials
         assert len(call_kwargs['credentials']) == 1
         cred = call_kwargs['credentials'][0]
-        assert cred.registry == 'quay.io/openshift'
+        assert cred.registry == REGISTRY_QUAY_OPENSHIFT
🤖 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 `@pyartcd/tests/pipelines/test_build_sync.py` around lines 275 - 282, Replace
the hardcoded registry string in the test with the proper constant: instead of
asserting cred.registry == 'quay.io/openshift', import and use
REGISTRY_QUAY_OPENSHIFT (similar to the existing REGISTRY_QUAY_CI import) and
assert cred.registry == REGISTRY_QUAY_OPENSHIFT so the test uses the canonical
constant; update the import list to include REGISTRY_QUAY_OPENSHIFT and adjust
the assertion that inspects call_kwargs['credentials'] / cred.
pyartcd/pyartcd/pipelines/build_sync.py (1)

498-500: 💤 Low value

QCI mirroring failures are silently swallowed.

When mirroring fails (e.g., network issues, auth problems), the exception is logged and a Slack notification is sent, but the build continues without re-raising. This means QCI mirroring failures won't fail the overall build-sync job.

If this is intentional (to avoid breaking builds for a non-critical mirror), consider documenting this decision in the code comment. If QCI mirrors are expected to be reliable, consider re-raising after notification so operators are alerted via build failure.

🤖 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 `@pyartcd/pyartcd/pipelines/build_sync.py` around lines 498 - 500, The except
block currently logs the error and notifies Slack but swallows the exception
(self.logger.error(...) and await self.slack_client.say(...)) which lets
build-sync continue on QCI mirror failures; update the handler in build_sync.py
(the method containing these lines) to either re-raise the exception after
sending the Slack notification (add "raise" after await
self.slack_client.say(...)) so the job fails on mirror errors, or if swallowing
is intentional add a clear code comment explaining why this is tolerated and
what alerts/operators should expect; reference the existing symbols
self.logger.error and await self.slack_client.say when making the change.
🤖 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.

Nitpick comments:
In `@pyartcd/pyartcd/pipelines/build_sync.py`:
- Around line 498-500: The except block currently logs the error and notifies
Slack but swallows the exception (self.logger.error(...) and await
self.slack_client.say(...)) which lets build-sync continue on QCI mirror
failures; update the handler in build_sync.py (the method containing these
lines) to either re-raise the exception after sending the Slack notification
(add "raise" after await self.slack_client.say(...)) so the job fails on mirror
errors, or if swallowing is intentional add a clear code comment explaining why
this is tolerated and what alerts/operators should expect; reference the
existing symbols self.logger.error and await self.slack_client.say when making
the change.

In `@pyartcd/tests/pipelines/test_build_sync.py`:
- Around line 144-147: The test assertions are brittle because the imagestream
name in the command depends on uses_konflux_imagestream_override(self.version);
update the test to either mock uses_konflux_imagestream_override to return a
known value for the tested version or relax the assertions to accept both
possible imagestream forms (e.g., check for suffix ':rhel-coreos' and that the
command contains either 'art-latest:rhel-coreos' or
'4.17-konflux-art-latest:rhel-coreos'); locate the call site around
mock_cmd_gather and the helper is_base_name/uses_konflux_imagestream_override to
implement the mocking or flexible assertion so the test no longer fails
depending on the override result.
- Around line 275-282: Replace the hardcoded registry string in the test with
the proper constant: instead of asserting cred.registry == 'quay.io/openshift',
import and use REGISTRY_QUAY_OPENSHIFT (similar to the existing REGISTRY_QUAY_CI
import) and assert cred.registry == REGISTRY_QUAY_OPENSHIFT so the test uses the
canonical constant; update the import list to include REGISTRY_QUAY_OPENSHIFT
and adjust the assertion that inspects call_kwargs['credentials'] / cred.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: ac4a2d90-545e-4611-9983-5817d0362fff

📥 Commits

Reviewing files that changed from the base of the PR and between 1a84e5b and 0500142.

📒 Files selected for processing (2)
  • pyartcd/pyartcd/pipelines/build_sync.py
  • pyartcd/tests/pipelines/test_build_sync.py

@joepvd joepvd force-pushed the mirror-rhcos-to-qci branch from 0500142 to 331df40 Compare June 3, 2026 11:51

@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 `@pyartcd/pyartcd/pipelines/build_sync.py`:
- Around line 521-527: The private path is querying the wrong namespace: when
private is True, change the namespace used for the ART istag lookup (the
namespace variable next to is_name) to the ART private imagestream namespace
used by _backup_all_imagestreams (the ocp*-priv namespace) instead of
'ocp-private' so _tag_into_ci_imagestream() pulls from the ART private source;
update the namespace assignment for the private branch to derive/use the same
ART private namespace value that _backup_all_imagestreams uses.
🪄 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: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 1b24a9d3-54bc-41ed-b4c0-07f4f816fb82

📥 Commits

Reviewing files that changed from the base of the PR and between 0500142 and 331df40.

📒 Files selected for processing (2)
  • pyartcd/pyartcd/pipelines/build_sync.py
  • pyartcd/tests/pipelines/test_build_sync.py

Comment thread pyartcd/pyartcd/pipelines/build_sync.py Outdated
@joepvd

joepvd commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

/hold
this is not yet good

@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jun 3, 2026
@joepvd joepvd force-pushed the mirror-rhcos-to-qci branch 2 times, most recently from 558912f to ad38007 Compare June 5, 2026 08:40
@joepvd

joepvd commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

@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: 5

🤖 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 `@pyartcd/pyartcd/pipelines/build_sync.py`:
- Around line 558-564: The current loop builds a dest pullspec using
REGISTRY_QUAY_CI and runs `oc tag` which only creates an ImageStreamTag
in-cluster and does not create tags in Quay; update the loop that iterates over
qci_tag (and uses variables dest and tag_pullspec) to use the same registry
mirror/push flow used elsewhere in this module (i.e., the oc image mirror /
mirroring logic that actually pushes to external registries) instead of `oc tag
--reference`; specifically, replace the `oc tag` invocation with the
image-mirroring call/path that mirrors tag_pullspec to quay pullspec
(constructed from REGISTRY_QUAY_CI and qci_tag) so the QCI tags land in quay.io
rather than just on the ImageStream.
- Around line 529-533: The oc jsonpath expression is over-braced causing empty
tag_pullspec: change the cmd string built into cmd (used with
exectools.cmd_gather_async) to use a single jsonpath brace expression like
-o=jsonpath={.tag.from.name}. Remove passing retries into
exectools.cmd_assert_async (it forwards kwargs to create_subprocess_exec);
either implement retry logic around cmd_assert_async calls or use a helper that
retries cmd_gather_async instead. Finally, stop using a registry-style pullspec
for oc tag dest: build dest as an ImageStreamTag (namespace/imagestream:tag),
e.g., set dest to f"openshift/ci:{tag}" or f"{dest_namespace}/{dest_is}:{tag}"
before invoking oc tag so oc receives an imagestream:tag target.

In `@pyartcd/pyartcd/pipelines/rebuild_golang_rpms.py`:
- Around line 170-177: The current truthiness checks on self.rpms cause an
explicit empty --rpms list to be treated like "no filter" and widen to all RPMs;
change those boolean checks to explicitly test for None so an empty list remains
a valid explicit filter (e.g., replace "if self.rpms:" with "if self.rpms is not
None" in the filtering logic and the later checks that rely on self.rpms), and
ensure the existing exclusion/filtering code (using get_excluded_rpms and
assigning self.rpms = filtered) preserves an empty list instead of converting it
to a falsy None-like behavior.
- Around line 139-154: The code currently creates a Jira client unconditionally
via self.runtime.new_jira_client() before checking self.runtime.dry_run, which
causes Jira auth to run on dry-run paths; change the flow so the Jira client is
only created when actually needed — for example, move the call to
self.runtime.new_jira_client() inside the non-dry-run branch (after the
self.runtime.dry_run check) or create it lazily just before calling
jira_client.add_comment/close_with_resolution for each bug; update the block
around excluded_bugs, the self.runtime.dry_run check, and the uses of
jira_client.add_comment/close_with_resolution so no Jira client is instantiated
during dry runs.

In `@pyartcd/tests/test_rebuild_golang_rpms.py`:
- Around line 1-7: Remove the unused import EXCLUDED_RPMS from the test module
import list so Ruff F401 is resolved; update the import statement that currently
reads "from pyartcd.pipelines.rebuild_golang_rpms import EXCLUDED_RPMS,
RebuildGolangRPMsPipeline" to only import RebuildGolangRPMsPipeline (leave the
class name RebuildGolangRPMsPipeline unchanged so tests still reference it).
🪄 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: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 5f800289-e57c-4394-9278-be79bcf2422b

📥 Commits

Reviewing files that changed from the base of the PR and between 331df40 and 558912f.

📒 Files selected for processing (7)
  • .worktrees/autoclose-golang-bugs
  • .worktrees/provides
  • pyartcd/pyartcd/jira_client.py
  • pyartcd/pyartcd/pipelines/build_sync.py
  • pyartcd/pyartcd/pipelines/rebuild_golang_rpms.py
  • pyartcd/tests/pipelines/test_build_sync.py
  • pyartcd/tests/test_rebuild_golang_rpms.py
✅ Files skipped from review due to trivial changes (1)
  • .worktrees/provides

Comment thread pyartcd/pyartcd/pipelines/build_sync.py
Comment thread pyartcd/pyartcd/pipelines/build_sync.py
Comment thread pyartcd/pyartcd/pipelines/rebuild_golang_rpms.py Outdated
Comment thread pyartcd/pyartcd/pipelines/rebuild_golang_rpms.py Outdated
Comment thread pyartcd/tests/test_rebuild_golang_rpms.py Outdated
@joepvd joepvd force-pushed the mirror-rhcos-to-qci branch from ad38007 to fd750e8 Compare June 5, 2026 08:49

@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 `@pyartcd/tests/pipelines/test_build_sync.py`:
- Around line 288-290: The test currently asserts that the created credential
uses REGISTRY_QUAY_OPENSHIFT; update the expectation to REGISTRY_QUAY_CI when
the implementation bug is fixed: locate the assertion using
call_kwargs['credentials'], the local variable cred, and the constant
REGISTRY_QUAY_OPENSHIFT in the test_build_sync.py test and replace it with
REGISTRY_QUAY_CI so the test validates the corrected QCI credential registry.
🪄 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: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 5a5aab35-5675-4974-a992-e698961f3490

📥 Commits

Reviewing files that changed from the base of the PR and between 558912f and ad38007.

📒 Files selected for processing (7)
  • .worktrees/autoclose-golang-bugs
  • .worktrees/provides
  • pyartcd/pyartcd/jira_client.py
  • pyartcd/pyartcd/pipelines/build_sync.py
  • pyartcd/pyartcd/pipelines/rebuild_golang_rpms.py
  • pyartcd/tests/pipelines/test_build_sync.py
  • pyartcd/tests/test_rebuild_golang_rpms.py
✅ Files skipped from review due to trivial changes (1)
  • .worktrees/provides
🚧 Files skipped from review as they are similar to previous changes (3)
  • pyartcd/pyartcd/jira_client.py
  • pyartcd/tests/test_rebuild_golang_rpms.py
  • .worktrees/autoclose-golang-bugs

Comment thread pyartcd/tests/pipelines/test_build_sync.py Outdated
@joepvd joepvd force-pushed the mirror-rhcos-to-qci branch 2 times, most recently from 3307a56 to 1253bbf Compare June 5, 2026 08:57

@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 `@pyartcd/pyartcd/pipelines/build_sync.py`:
- Around line 487-499: The asyncio.gather call currently cancels all pending
mirror tasks when any _mirror_single_rhcos_to_qci(tag, ...) raises; change the
gather call to not fail-fast by using asyncio.gather(...,
return_exceptions=True) or wrap each invocation in a small coroutine that
catches and logs its own exceptions so one tag failure doesn't abort the rest —
target the block that builds tasks from tags_to_transfer and the asyncio.gather
invocation, ensure per-tag failures are logged (including exception details) and
that the overall flow still logs final success/failure summary for self.version.
🪄 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: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 51454158-ebe0-4100-bda4-7cc24562bafb

📥 Commits

Reviewing files that changed from the base of the PR and between ad38007 and 3307a56.

📒 Files selected for processing (1)
  • pyartcd/pyartcd/pipelines/build_sync.py

Comment on lines +487 to +499
tasks = []
for tag in tags_to_transfer:
# Mirror to public QCI
tasks.append(self._mirror_single_rhcos_to_qci(tag, prune_timestamp, private=False))
# Mirror to private QCI (for openshift-priv CI)
tasks.append(self._mirror_single_rhcos_to_qci(tag, prune_timestamp, private=True))

await asyncio.gather(*tasks)
self.logger.info('Successfully mirrored RHCOS images to QCI')

except Exception as e:
self.logger.error('Failed to mirror RHCOS images to QCI: %s', e)
await self.slack_client.say(f'Unable to mirror CoreOS images to QCI for {self.version}: {e}')

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don’t let one failed tag cancel the rest of the mirror batch.

Line 494 fails fast: if one _mirror_single_rhcos_to_qci() raises, asyncio.gather() cancels the remaining QCI updates. That makes this “best effort” step stop after the first failure instead of attempting the rest of the tags.

♻️ Suggested change
-            await asyncio.gather(*tasks)
-            self.logger.info('Successfully mirrored RHCOS images to QCI')
+            results = await asyncio.gather(*tasks, return_exceptions=True)
+            failures = [result for result in results if isinstance(result, Exception)]
+            if failures:
+                raise ChildProcessError(f'{len(failures)} QCI mirror task(s) failed')
+            self.logger.info('Successfully mirrored RHCOS images to QCI')
🧰 Tools
🪛 Ruff (0.15.15)

[warning] 497-497: Do not catch blind exception: Exception

(BLE001)

🤖 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 `@pyartcd/pyartcd/pipelines/build_sync.py` around lines 487 - 499, The
asyncio.gather call currently cancels all pending mirror tasks when any
_mirror_single_rhcos_to_qci(tag, ...) raises; change the gather call to not
fail-fast by using asyncio.gather(..., return_exceptions=True) or wrap each
invocation in a small coroutine that catches and logs its own exceptions so one
tag failure doesn't abort the rest — target the block that builds tasks from
tags_to_transfer and the asyncio.gather invocation, ensure per-tag failures are
logged (including exception details) and that the overall flow still logs final
success/failure summary for self.version.

@joepvd joepvd force-pushed the mirror-rhcos-to-qci branch 5 times, most recently from b7b444d to 40fe337 Compare June 5, 2026 12:21
Tag RHCOS container images (rhel-coreos, machine-os-content, etc.) to
quay.io/openshift/ci during build-sync for external CI consumption.

Uses `oc tag` with reference mode:
- --reference-policy='source'
- --import-mode='PreserveOriginal'
- --reference

QCI tag format:
- Prunable: quay.io/openshift/ci:<timestamp>_prune_art__ocp_<version>_<tag>
- Floating: quay.io/openshift/ci:art__ocp_<version>_<tag>

Requires QCI_USER/QCI_PASSWORD env vars (already in Jenkinsfile).
@joepvd joepvd force-pushed the mirror-rhcos-to-qci branch from 40fe337 to 4503eb8 Compare June 5, 2026 12:21
@openshift-ci

openshift-ci Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

@joepvd: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/art-pre-commit-check 4503eb8 link false /test art-pre-commit-check
ci/prow/security 4503eb8 link false /test security

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

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

Labels

do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant