Skip to content

Filter Konflux golang-builder search by hermetic flag#3048

Open
thegreyd wants to merge 2 commits into
openshift-eng:mainfrom
thegreyd:better-golang-builder-search
Open

Filter Konflux golang-builder search by hermetic flag#3048
thegreyd wants to merge 2 commits into
openshift-eng:mainfrom
thegreyd:better-golang-builder-search

Conversation

@thegreyd

Copy link
Copy Markdown
Contributor

Summary

  • Adds _get_effective_network_mode() to UpdateGolangPipeline that reads the network mode from ocp-build-data config (CLI override > image config > group config > default "open"), matching doozer's precedence
  • Modifies get_existing_builders_konflux() to filter by hermetic=True/False based on the effective network mode, preventing reuse of non-hermetic builds when config requires hermetic (or vice versa)
  • Fixes boolean handling in search_builds_by_fields to use Column(col_name, Boolean) instead of String for bool values in the where dict

Test plan

  • All 78 existing + new unit tests pass (uv run pytest pyartcd/tests/pipelines/test_update_golang.py)
  • Lint passes (make lint)
  • Verify with a dry-run of update_golang against an OCP version with hermetic golang-builder config

🤖 Generated with Claude Code

@openshift-ci

openshift-ci Bot commented Jun 10, 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 ashwindasr 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 10, 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

Resolve network mode per image target (CLI > image > group > default), compute a hermetic boolean per target, pass it into Konflux build searches as where["hermetic"], add SQL boolean where handling, and add tests for resolver precedence and hermetic-filter behavior.

Changes

Network Mode Resolution and Hermetic Build Filtering

Layer / File(s) Summary
Network mode resolver
artcommon/artcommonlib/metadata.py
Add VALID_NETWORK_MODES and resolve_network_mode(); delegate MetadataBase.get_konflux_network_mode() to this helper to apply CLI > image > group > default precedence and validate values.
Konflux DB boolean support
artcommon/artcommonlib/konflux/konflux_db.py
search_builds_by_fields() now treats Python bool values as SQL boolean predicates using Column(..., Boolean) == value instead of string-typed comparisons.
Pipeline integration: compute effective mode and hermetic flag
pyartcd/pyartcd/pipelines/update_golang.py
Import resolver; add _get_effective_network_mode() to load image/group config from ocp-build-data via GitData, call resolve_network_mode(), log the result; get_existing_builders_konflux() precomputes per-target effective network mode, derives hermetic, and includes where['hermetic'] in Konflux searches.
Test coverage for resolver precedence and hermetic filter
pyartcd/tests/pipelines/test_update_golang.py, doozer/tests/test_image.py
Patch builder-lookup tests to mock _get_effective_network_mode; add TestGetEffectiveNetworkMode for precedence cases and TestGetExistingBuildersKonfluxHermeticFilter to assert where["hermetic"] is True for "hermetic" and False for "open".

🎯 3 (Moderate) | ⏱️ ~20 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 (1)
pyartcd/pyartcd/pipelines/update_golang.py (1)

1009-1020: ⚡ Quick win

Narrow the exception handling to specific exception types.

Lines 1012 and 1019 use bare except Exception: which catches too broadly, including KeyboardInterrupt and other exceptions that shouldn't be suppressed. Consider catching more specific exceptions based on what _load_yaml_from_repo and the GitHub API can raise (e.g., github.GithubException, yaml.YAMLError, KeyError).

♻️ Proposed fix to narrow exception handling
+from github import GithubException
+from yaml import YAMLError
+
 image_config_network_mode = None
 try:
     image_config = self._load_yaml_from_repo(repo, f"images/{image_key}.yml", ref)
     image_config_network_mode = (image_config.get("konflux") or {}).get("network_mode")
-except Exception:
+except (GithubException, YAMLError, KeyError, FileNotFoundError):
     _LOGGER.debug(f"Could not load image config for {image_key} from ref {ref}")

 group_config_network_mode = None
 try:
     group_config = self._load_yaml_from_repo(repo, "group.yml", ref)
     group_config_network_mode = (group_config.get("konflux") or {}).get("network_mode")
-except Exception:
+except (GithubException, YAMLError, KeyError, FileNotFoundError):
     _LOGGER.debug(f"Could not load group config from ref {ref}")
🤖 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/update_golang.py` around lines 1009 - 1020, The
bare `except Exception:` blocks around calls to _load_yaml_from_repo (affecting
image_config_network_mode and group_config_network_mode) are too broad; change
them to catch the specific exceptions that _load_yaml_from_repo and the
underlying GitHub/YAML code may raise (for example github.GithubException,
yaml.YAMLError, FileNotFoundError, KeyError), and include the exception details
in the _LOGGER.debug message so failures are recorded; keep the behavior of
falling back to None but avoid swallowing unexpected system-level exceptions
like KeyboardInterrupt or SystemExit.

Source: Linters/SAST tools

🤖 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/update_golang.py`:
- Around line 1009-1020: The bare `except Exception:` blocks around calls to
_load_yaml_from_repo (affecting image_config_network_mode and
group_config_network_mode) are too broad; change them to catch the specific
exceptions that _load_yaml_from_repo and the underlying GitHub/YAML code may
raise (for example github.GithubException, yaml.YAMLError, FileNotFoundError,
KeyError), and include the exception details in the _LOGGER.debug message so
failures are recorded; keep the behavior of falling back to None but avoid
swallowing unexpected system-level exceptions like KeyboardInterrupt or
SystemExit.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: f633d636-78ca-4297-856b-77c92a29d900

📥 Commits

Reviewing files that changed from the base of the PR and between 60bba93 and 10fbf35.

📒 Files selected for processing (3)
  • artcommon/artcommonlib/konflux/konflux_db.py
  • pyartcd/pyartcd/pipelines/update_golang.py
  • pyartcd/tests/pipelines/test_update_golang.py

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pyartcd/pyartcd/pipelines/update_golang.py (1)

581-600: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Don't collapse internal-only into the non-hermetic search bucket.

Line 584 maps every non-hermetic mode to False, so an internal-only target will query where["hermetic"] = False and can reuse a builder previously produced with open egress. That skips a rebuild even though the requested network policy is stricter. Either query on a persisted full network_mode field, or conservatively disable reuse for internal-only until Konflux records can distinguish it.

Possible conservative fix
         el_hermetic_map: dict[int, bool] = {}
         for el_v in el_nvr_map:
             network_mode = self._get_effective_network_mode(el_v, go_version)
+            if network_mode == "internal-only":
+                _LOGGER.info(
+                    "Skipping Konflux builder reuse for el%s because the DB filter only distinguishes hermetic vs non-hermetic",
+                    el_v,
+                )
+                continue
             el_hermetic_map[el_v] = network_mode == "hermetic"
             _LOGGER.info(
                 f"Searching for el{el_v} golang-builder with hermetic={el_hermetic_map[el_v]} "
                 f"(network_mode={network_mode})"
             )
@@
-                for el_v in el_nvr_map
+                for el_v in el_hermetic_map
             )
         )
🤖 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/update_golang.py` around lines 581 - 600, The
current mapping in el_hermetic_map (set via _get_effective_network_mode) treats
any non-"hermetic" mode as False, causing "internal-only" targets to be treated
like open-egress and allowing reuse; change the search logic in the
build_records gather/konflux_db.search_builds_by_fields call so it does not
collapse "internal-only" into hermetic=False — either query using a persisted
full network_mode field (e.g., add where["network_mode"]=network_mode) or, if
that field isn't available yet, conservatively disable reuse for "internal-only"
by omitting the hermetic filter for el_v when network_mode == "internal-only"
(or otherwise ensure you do not set where["hermetic"]=False for internal-only)
so builders with open egress are not reused for stricter internal-only requests.
🤖 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.

Outside diff comments:
In `@pyartcd/pyartcd/pipelines/update_golang.py`:
- Around line 581-600: The current mapping in el_hermetic_map (set via
_get_effective_network_mode) treats any non-"hermetic" mode as False, causing
"internal-only" targets to be treated like open-egress and allowing reuse;
change the search logic in the build_records
gather/konflux_db.search_builds_by_fields call so it does not collapse
"internal-only" into hermetic=False — either query using a persisted full
network_mode field (e.g., add where["network_mode"]=network_mode) or, if that
field isn't available yet, conservatively disable reuse for "internal-only" by
omitting the hermetic filter for el_v when network_mode == "internal-only" (or
otherwise ensure you do not set where["hermetic"]=False for internal-only) so
builders with open egress are not reused for stricter internal-only requests.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: d0fc9265-07fd-4705-88a2-6fab9882c179

📥 Commits

Reviewing files that changed from the base of the PR and between ebe67fd and 11c50b6.

📒 Files selected for processing (2)
  • pyartcd/pyartcd/pipelines/update_golang.py
  • pyartcd/tests/pipelines/test_update_golang.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • pyartcd/tests/pipelines/test_update_golang.py

@thegreyd thegreyd force-pushed the better-golang-builder-search branch from 11c50b6 to ec2856c Compare June 10, 2026 15:04

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

🤖 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 `@artcommon/artcommonlib/metadata.py`:
- Line 640: The code currently reads runtime_override = getattr(self.runtime,
"network_mode_override", None) which can return a MagicMock in tests; update the
logic so you only pass a real string to resolve_network_mode: after fetching
runtime_override, validate its type (e.g., isinstance(runtime_override, str))
and if it is not a str, set runtime_override = None (or omit it) before calling
resolve_network_mode; locate the usage around the attribute access on
self.runtime and the subsequent call to resolve_network_mode to apply this
guard.

In `@pyartcd/pyartcd/pipelines/update_golang.py`:
- Around line 996-999: The try/except around calling self._load_yaml_from_repo
that sets image_config should not swallow all errors silently; modify the except
to log the caught exception (including its message/stack) before falling back to
image_config = {}. Use an appropriate logger (e.g., self.logger.exception or the
module-level logging.exception) in the except block to record the error and
context (repo, path f"images/{image_key}.yml", ref) and then continue with
image_config = {} so debugging GitHub/API/YAML parse failures is possible.
- Around line 1002-1005: The current bare except around calling
self._load_yaml_from_repo(repo, "group.yml", ref) swallows all errors and
silently falls back to group_config = {}, so change the except to capture the
exception (e.g., except Exception as e) and log the failure before assigning the
empty dict; use the existing logger on the object (self.logger.exception or
self.logger.error with the exception) or the module logger to record the
repo/ref and error message/stacktrace so failures in _load_yaml_from_repo are
visible while preserving the fallback to group_config = {}.
🪄 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: a2b0ce90-0d6a-41f5-a090-d530399fd867

📥 Commits

Reviewing files that changed from the base of the PR and between 11c50b6 and ec2856c.

📒 Files selected for processing (4)
  • artcommon/artcommonlib/konflux/konflux_db.py
  • artcommon/artcommonlib/metadata.py
  • pyartcd/pyartcd/pipelines/update_golang.py
  • pyartcd/tests/pipelines/test_update_golang.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • artcommon/artcommonlib/konflux/konflux_db.py

Comment thread artcommon/artcommonlib/metadata.py
Comment thread pyartcd/pyartcd/pipelines/update_golang.py
Comment thread pyartcd/pyartcd/pipelines/update_golang.py
When searching for existing golang-builder builds in the Konflux DB,
consider the effective network mode from ocp-build-data config. If
the builder is configured as hermetic, only match hermetic builds.

- Extract resolve_network_mode() into artcommonlib for shared use
- Add _get_effective_network_mode() to update_golang pipeline
- Add hermetic field to search_builds_by_fields where clause
- Fix boolean handling in search_builds_by_fields (was using String
  column type for all values, now uses Boolean for bool values)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

rh-pre-commit.version: 2.4.0
rh-pre-commit.check-secrets: ENABLED
@thegreyd thegreyd force-pushed the better-golang-builder-search branch from 8bb5aed to 18d3dda Compare June 10, 2026 16:07
Comment thread artcommon/artcommonlib/metadata.py Outdated

Precedence: cli_override > image_config > group_config > "open"
"""
cli_override = cli_override if isinstance(cli_override, str) else None

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.

mmm....

The function signature says str | None. Passing a MagicMock is a test bug, not a function bug.
The right fix would be to set runtime.network_mode_override = None in those 4 tests IMHO

…isinstance guards

Per review feedback, the function signature says `str | None` — passing
MagicMock is a test bug, not a function bug. Mock `get_konflux_network_mode`
in the 4 lockfile tests that use MagicMock configs, matching the pattern
already used by the passing tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

rh-pre-commit.version: 2.4.0
rh-pre-commit.check-secrets: ENABLED
@thegreyd thegreyd force-pushed the better-golang-builder-search branch from 18d3dda to 2b76493 Compare June 10, 2026 16:22
@openshift-ci

openshift-ci Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

@thegreyd: The following test 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/security 2b76493 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.

@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/update_golang.py`:
- Around line 996-1011: When loading image/group YAML fails in
_load_yaml_from_repo, don't swallow the exception into {} because that lets
resolve_network_mode(image_config_network_mode, group_config_network_mode) fall
back to "open"; instead after logging the warning re-raise the exception (or
raise a new descriptive exception) so the pipeline fails closed and avoid
matching a non-hermetic builder; update the two except blocks around
_load_yaml_from_repo (the ones that set image_config = {} and group_config = {})
to log and then raise, so resolve_network_mode receives only valid config values
or the pipeline stops.
🪄 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: 772bb2ce-3a8d-4885-b8fd-6fb4c8d1a1bb

📥 Commits

Reviewing files that changed from the base of the PR and between ec2856c and 2b76493.

📒 Files selected for processing (5)
  • artcommon/artcommonlib/konflux/konflux_db.py
  • artcommon/artcommonlib/metadata.py
  • doozer/tests/test_image.py
  • pyartcd/pyartcd/pipelines/update_golang.py
  • pyartcd/tests/pipelines/test_update_golang.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • artcommon/artcommonlib/metadata.py
  • artcommon/artcommonlib/konflux/konflux_db.py

Comment on lines +996 to +1011
try:
image_config = self._load_yaml_from_repo(repo, f"images/{image_key}.yml", ref)
except Exception as e:
_LOGGER.warning(f"Failed to load image config for {image_key}: {e}")
image_config = {}
image_config_network_mode = (image_config.get("konflux") or {}).get("network_mode")

try:
group_config = self._load_yaml_from_repo(repo, "group.yml", ref)
except Exception as e:
_LOGGER.warning(f"Failed to load group config from {ref}: {e}")
group_config = {}
group_config_network_mode = (group_config.get("konflux") or {}).get("network_mode")

network_mode = resolve_network_mode(None, image_config_network_mode, group_config_network_mode)
_LOGGER.info(f"Effective network mode for el{el_v} golang-builder: {network_mode}")

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

Failing to read build-data currently fails open to non-hermetic matching.

At Line 1004 and Line 997, exceptions are converted to {}, which can make resolve_network_mode(...) fall back to "open" and query hermetic=False. That can incorrectly reuse a non-hermetic builder when hermetic config exists but could not be fetched.

🔧 Suggested fix
-        try:
-            image_config = self._load_yaml_from_repo(repo, f"images/{image_key}.yml", ref)
-        except Exception as e:
-            _LOGGER.warning(f"Failed to load image config for {image_key}: {e}")
-            image_config = {}
+        try:
+            image_config = self._load_yaml_from_repo(repo, f"images/{image_key}.yml", ref)
+        except Exception as e:
+            _LOGGER.exception("Failed to load image config for %s at ref %s", image_key, ref)
+            raise RuntimeError(f"Unable to resolve network mode from images/{image_key}.yml at {ref}") from e
@@
-        try:
-            group_config = self._load_yaml_from_repo(repo, "group.yml", ref)
-        except Exception as e:
-            _LOGGER.warning(f"Failed to load group config from {ref}: {e}")
-            group_config = {}
+        try:
+            group_config = self._load_yaml_from_repo(repo, "group.yml", ref)
+        except Exception as e:
+            _LOGGER.exception("Failed to load group config at ref %s", ref)
+            raise RuntimeError(f"Unable to resolve network mode from group.yml at {ref}") from e
🧰 Tools
🪛 Ruff (0.15.15)

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

(BLE001)


[warning] 1005-1005: 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/update_golang.py` around lines 996 - 1011, When
loading image/group YAML fails in _load_yaml_from_repo, don't swallow the
exception into {} because that lets
resolve_network_mode(image_config_network_mode, group_config_network_mode) fall
back to "open"; instead after logging the warning re-raise the exception (or
raise a new descriptive exception) so the pipeline fails closed and avoid
matching a non-hermetic builder; update the two except blocks around
_load_yaml_from_repo (the ones that set image_config = {} and group_config = {})
to log and then raise, so resolve_network_mode receives only valid config values
or the pipeline stops.

@fgallott

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jun 10, 2026
@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 4, 2026
@openshift-ci

openshift-ci Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

PR needs rebase.

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.

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

Labels

lgtm Indicates that a PR is ready to be merged. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants