Skip to content

Conversation

@locriandev
Copy link
Contributor

Reverts #2220

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Dec 24, 2025

[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 ximinhan 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
Copy link
Contributor

coderabbitai bot commented Dec 24, 2025

Walkthrough

The changes refactor upstream-aware matching logic for canonical builders by relocating version determination and configuration merging responsibilities from the Image class to the ImageDistGitRepo class. The rebaser is updated to gate upstream resolution with a should_match_upstream flag and simplify image transformation logic. Tests are adjusted to verify distgit config updates and legacy image tests are removed.

Changes

Cohort / File(s) Summary
Rebaser upstream-matching refactoring
doozer/doozerlib/backend/rebaser.py
Refactored _resolve_stream_parent signature to remove metadata parameter; integrated stream image transformation (brew registry prefixing, openshift-golang-builder rewriting) directly into the method; introduced upstream-based resolution path via _resolve_image_from_upstream_parent when should_match_upstream is true; removed static _transform_stream_pullspec method; updated _update_dockerfile to use should_match_upstream instead of canonical_builders_enabled; simplified _resolve_image_from_upstream_parent to always fetch labels via oc_image_info_for_arch_async__caching and added Dockerfile error annotation on upstream matching failure; added should_match_upstream attribute initialization in KonfluxRebaser.__init__.
ImageDistGitRepo upstream versioning and config
doozer/doozerlib/distgit.py
Added three new attributes (art_intended_el_version, upstream_intended_el_version, should_match_upstream) to track RHEL version matching; introduced _determine_art_rhel_version method to compute ART's intended RHEL version from distgit branch; introduced _determine_upstream_rhel_version method to inspect upstream Dockerfile labels for RHEL version; introduced _update_image_config method to merge alternative upstream configuration when versions differ; replaced canonical_builders_enabled gating with should_match_upstream in key decision points for controlling upstream-based resolution and rebase behavior.
Image initialization simplification
doozer/doozerlib/image.py
Removed imports (pathlib, re, DockerfileParser, SourceResolver); eliminated _apply_alternative_upstream_config method and its early invocation in __init__; removed _determine_upstream_rhel_version helper method; simplified initialization to unconditionally invoke runtime.source_resolver.resolve_source(self) when clone_source is true, removing upstream-detection side-effects from Image class initialization.
ImageDistGitRepo config update tests
doozer/tests/test_distgit/test_image_distgit/test_image_distgit.py
Added test_update_image_config test method verifying configuration updates based on alternative upstream clauses with matching and non-matching when-conditions; test exercises _update_image_config method behavior for branch updates and should_match_upstream flag changes.
Image class test removals
doozer/tests/test_image.py
Removed five test methods related to alternative upstream configuration: test_apply_alternative_upstream_config_matching_rhel_version, test_apply_alternative_upstream_config_no_match, test_apply_alternative_upstream_config_no_source, test_apply_alternative_upstream_config_no_alternative_config, and test_determine_upstream_rhel_version_ubi_pattern.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch revert-2220-feat-konflux-canonical-builders

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

@locriandev locriandev requested a review from vfreex December 24, 2025 13:18
@locriandev locriandev merged commit efb822b into main Dec 24, 2025
5 of 8 checks passed
@fgallott fgallott deleted the revert-2220-feat-konflux-canonical-builders branch December 24, 2025 13:19
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
doozer/doozerlib/distgit.py (1)

1886-1909: Consider explicit check for empty parent_images.

Accessing parent_images[-1] at line 1892 will raise IndexError if the Dockerfile has no FROM statements. While the broad except Exception handler catches this, the warning message at line 1907 would be misleading ("Could not determine rhel version") rather than indicating a malformed Dockerfile.

Also, regarding the static analysis hint on line 1901: the broad exception catch is intentional here since failure to determine RHEL version is non-fatal. However, consider catching more specific exceptions for better diagnostics.

🔎 Optional: Add explicit check and narrow exception types
             with open(df_path) as f:
                 dfp = DockerfileParser(fileobj=f)
                 parent_images = dfp.parent_images
 
+            if not parent_images:
+                self.logger.warning('No parent images found in upstream Dockerfile for %s', self.name)
+                return None
+
             # We will infer the rhel version from the last build layer in the upstream Dockerfile
             last_layer_pullspec = parent_images[-1]
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between c48038f and 35e8ce2.

📒 Files selected for processing (5)
  • doozer/doozerlib/backend/rebaser.py
  • doozer/doozerlib/distgit.py
  • doozer/doozerlib/image.py
  • doozer/tests/test_distgit/test_image_distgit/test_image_distgit.py
  • doozer/tests/test_image.py
💤 Files with no reviewable changes (1)
  • doozer/tests/test_image.py
🧰 Additional context used
🧬 Code graph analysis (3)
doozer/doozerlib/image.py (1)
doozer/doozerlib/rpmcfg.py (1)
  • clone_source (53-93)
doozer/tests/test_distgit/test_image_distgit/test_image_distgit.py (2)
artcommon/artcommonlib/model.py (1)
  • Model (116-155)
doozer/doozerlib/distgit.py (1)
  • _update_image_config (1911-1957)
doozer/doozerlib/backend/rebaser.py (4)
doozer/doozerlib/runtime.py (1)
  • resolve_stream (1135-1158)
artcommon/artcommonlib/variants.py (1)
  • BuildVariant (4-6)
doozer/doozerlib/distgit.py (1)
  • _resolve_image_from_upstream_parent (1654-1707)
doozer/doozerlib/util.py (2)
  • oc_image_info_for_arch_async__caching (736-753)
  • extract_version_fields (218-228)
🪛 Ruff (0.14.10)
doozer/doozerlib/distgit.py

1901-1901: Do not catch blind exception: Exception

(BLE001)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: tests
  • GitHub Check: Analyze (python)
🔇 Additional comments (11)
doozer/doozerlib/backend/rebaser.py (4)

92-92: Acknowledge the placeholder for disabled functionality.

The should_match_upstream is hardcoded to False with a FIXME. This effectively disables the upstream matching feature as part of the revert, which aligns with the PR objective.


476-504: Refactored stream parent resolution with gated upstream matching.

The logic correctly:

  1. Resolves the stream image with brew registry URL transformations
  2. Returns early for OKD variant
  3. Gates the upstream resolution behind should_match_upstream flag (currently always False)

Since should_match_upstream is hardcoded to False, lines 498-504 are effectively dead code, but this is intentional for the revert.


1012-1020: RHEL version assertion gated by should_match_upstream.

The condition was changed from metadata.canonical_builders_enabled to self.should_match_upstream. Since should_match_upstream is always False, this assertion block will never execute, which is the intended behavior for the revert.


1909-1910: Critical bug: await on coroutine followed by immediate dict access.

Line 1910 attempts to await the coroutine and then immediately index into the result on the same line. This is syntactically incorrect in Python - the await expression must be parenthesized before indexing, otherwise it tries to index the coroutine object before awaiting it.

🔎 Proposed fix
-            self._logger.debug('Retrieving image info for image %s', original_parent)
-            labels = await util.oc_image_info_for_arch_async__caching(original_parent)['config']['config']['Labels']
+            self._logger.debug('Retrieving image info for image %s', original_parent)
+            image_info = await util.oc_image_info_for_arch_async__caching(original_parent)
+            labels = image_info['config']['config']['Labels']

Likely an incorrect or invalid review comment.

doozer/tests/test_distgit/test_image_distgit/test_image_distgit.py (1)

661-688: Test covers both matching and non-matching alternative_upstream scenarios.

The test validates _update_image_config behavior:

  1. When when: 'el8' matches upstream_intended_el_version = '8' → config is updated, should_match_upstream stays True
  2. When when: 'el7' doesn't match upstream_intended_el_version = 8 → config unchanged, should_match_upstream set to False

The test also verifies type coercion works correctly by using string '8' in one case and integer 8 in another.

doozer/doozerlib/image.py (2)

52-53: Simplified initialization removes upstream-merge pathway.

The revert removes the complex _apply_alternative_upstream_config logic that was previously called during __init__. Now, when clone_source=True, it simply resolves the source without any upstream version detection or config merging.

This aligns with the revert objective - the upstream-aware logic is now disabled/removed.


664-679: canonical_builders_enabled property is still actively used in the codebase.

The property correctly implements the configuration hierarchy (image config → group config) and is used at doozer/doozerlib/distgit.py:519 in a conditional check. Since the initialization logic that relied on this property was removed, it now serves only to evaluate the configuration state without triggering side effects. This is consistent with the revert approach.

doozer/doozerlib/distgit.py (4)

509-530: Initialization logic looks correct.

The conditional flow properly handles:

  1. Distgit-only images (no source) - version attributes remain None
  2. _update_image_config() is safely called unconditionally since it handles None upstream version by returning early

The inline comment block (lines 509-514) provides good context for the rationale.


1842-1852: Stream resolution logic is sound.

The gating on should_match_upstream correctly:

  • Returns typical stream resolution when not matching upstream
  • Attempts upstream parent resolution with fallback to stream.image

1854-1865: LGTM.

The fallback to group config branch when distgit branch is undefined is appropriate. The Optional[int] return type correctly accounts for cases where isolate_rhel_major_from_distgit_branch cannot extract a version.


2232-2240: LGTM - RHEL version assertion is a good safety check.

The runtime assertion ensures the final image's RHEL version matches ART's configuration when matching upstream. This prevents misconfigurations from producing images built on the wrong RHEL base.

Comment on lines +1950 to +1958
else:
# We found an alternative_upstream config stanza. We can match upstream
self.should_match_upstream = True
# Distgit branch must be changed to track the alternative one
self.branch = self.config.distgit.branch
# Also update metadata config
self.metadata.config = self.config
self.metadata.targets = self.metadata.determine_targets()

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Potential issue: distgit.branch may be Missing after config merge.

At line 1954, self.branch = self.config.distgit.branch is assigned directly without checking if it's Missing. While alternative_upstream configs should logically include a distgit.branch override (since they target different RHEL versions), there's no enforcement.

Compare with _determine_art_rhel_version() (lines 1861-1864) which handles the Missing case:

if branch is Missing:
    self.logger.warning(...)
    branch = self.runtime.group_config.branch
🔎 Suggested defensive check
         else:
             # We found an alternative_upstream config stanza. We can match upstream
             self.should_match_upstream = True
             # Distgit branch must be changed to track the alternative one
-            self.branch = self.config.distgit.branch
+            if self.config.distgit.branch is Missing:
+                raise ValueError(
+                    f"alternative_upstream config for {self.name} matched but does not define distgit.branch"
+                )
+            self.branch = self.config.distgit.branch
             # Also update metadata config
             self.metadata.config = self.config
             self.metadata.targets = self.metadata.determine_targets()
🤖 Prompt for AI Agents
In doozer/doozerlib/distgit.py around lines 1950 to 1958, the assignment
self.branch = self.config.distgit.branch should defensively handle the case
where config.distgit.branch is Missing; check if branch is Missing, log a
warning, and fall back to self.runtime.group_config.branch (or other appropriate
default) before setting self.branch, then proceed to update metadata.config and
metadata.targets as before.

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.

1 participant