Skip to content

lockfile: align RPM versions across architectures to highest common EVR - #3219

Closed
redhat-chai-bot wants to merge 1 commit into
openshift-eng:mainfrom
redhat-chai-bot:fix/cross-arch-rpm-version-alignment
Closed

lockfile: align RPM versions across architectures to highest common EVR#3219
redhat-chai-bot wants to merge 1 commit into
openshift-eng:mainfrom
redhat-chai-bot:fix/cross-arch-rpm-version-alignment

Conversation

@redhat-chai-bot

@redhat-chai-bot redhat-chai-bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Add cross-architecture RPM version alignment to the lockfile generator so that all architectures use the same RPM version in the lockfile. This prevents Conforma rpm_packages.unique_version violations during Konflux release pipelines.

Problem

The current generate_lockfile() flow resolves RPMs independently per architecture via _fetch_rpms_info_per_arch(). Each arch picks its own highest available EVR from the configured repos. When an RPM update has propagated to one arch's repos but not another's, the lockfile ends up with different versions per arch. This causes the verify-conforma release task to reject the build with rpm_packages.unique_version violations.

_validate_cross_arch_version_sets() (added in PR #2593 for ART-14488) detects these mismatches but only logs a WARNING — there is no reconciliation step.

This gap caused MTA 8.2 build failures (build/layered-products #12088) where all Konflux builds succeeded but the release pipeline rejected them due to cross-arch RPM version mismatches.

Changes

doozer/doozerlib/lockfile.py:

  • New method _align_cross_arch_versions(rpms_info_by_arch, repo_names) on RPMLockfileGenerator:

    • Identifies packages resolved to different "latest" EVRs across architectures
    • Computes the target EVR as the minimum of per-arch maximums (i.e. the highest version available on ALL architectures)
    • For arches that resolved higher, searches loaded repos for the target version and swaps the entry
    • NVR-pinned entries are never modified — only the "latest" pick per package name is aligned
    • Logs INFO on successful downgrade, WARNING if target version not found in repos
  • New helper _find_rpm_by_evr_in_repos(pkg_name, target_evr, arch, repo_names) that searches loaded repos in canonical order for a specific package+EVR+arch combination

  • Integration: single-line call in generate_lockfile() after the existing _validate_cross_arch_version_sets() warning and before lockfile YAML is written

doozer/tests/test_lockfile_alignment.py:

  • 20 new tests covering: no-op (already aligned), basic alignment, NVR-pinned entry preservation, multi-package scenarios, multi-arch (3+ arches), epoch-aware comparison, repo preference ordering, noarch handling, and logging verification

Testing

All 76 tests pass (56 existing + 20 new).

Related Issues


AI-generated. Review for accuracy.

@rayfordj requested in Slack thread

Summary by CodeRabbit

  • Bug Fixes
    • Improved lockfile consistency across architectures by aligning package versions to the highest available version.
    • Preserved explicitly pinned package versions during alignment.
    • Improved handling of architecture-specific, noarch, epoch-based, and repository-specific packages.
    • Added safeguards for packages or repositories without matching versions.

@openshift-ci

openshift-ci Bot commented Aug 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 thegreyd 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 Aug 3, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@redhat-chai-bot, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 10 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro Plus

Run ID: a837beeb-8127-4a5e-ac1d-425a310b1d24

📥 Commits

Reviewing files that changed from the base of the PR and between 87a01d0 and 8f1e569.

📒 Files selected for processing (2)
  • doozer/doozerlib/lockfile.py
  • doozer/tests/test_lockfile_alignment.py

Walkthrough

Lockfile generation now aligns mismatched RPM versions across architectures. It selects the highest EVR available for all applicable architectures, replaces entries from loaded repositories, preserves pinned entries, and validates repository lookup behavior with comprehensive tests.

Changes

Cross-architecture RPM alignment

Layer / File(s) Summary
Alignment implementation and lockfile integration
doozer/doozerlib/lockfile.py
The lockfile module aligns mismatched RPM EVRs, finds replacement metadata, preserves pinned entries, logs alignment results, and runs alignment before cross-architecture inclusion and serialization.
Alignment and repository lookup validation
doozer/tests/test_lockfile_alignment.py
Tests cover EVR comparison, architecture and noarch matching, repository preference, pinned entries, logging, missing targets, and exact RPM lookup behavior.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant LockfileGeneration
  participant Alignment
  participant RepositoryLookup
  participant LoadedRepositories
  LockfileGeneration->>Alignment: align resolved RPM entries
  Alignment->>RepositoryLookup: locate target EVR
  RepositoryLookup->>LoadedRepositories: search RPM metadata
  LoadedRepositories-->>RepositoryLookup: return matching RPM
  RepositoryLookup-->>Alignment: return replacement metadata
  Alignment-->>LockfileGeneration: return aligned entries
Loading
🚥 Pre-merge checks | ✅ 10 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Ai-Attribution ⚠️ Warning The HEAD commit credits Claude Opus with Co-Authored-By, but has no Assisted-by or Generated-by trailer. Replace the AI Co-Authored-By trailer with a Red Hat-approved Assisted-by or Generated-by trailer.
✅ Passed checks (10 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: aligning RPM versions across architectures to the highest common EVR.
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.
No-Weak-Crypto ✅ Passed The change adds no cryptographic implementation; the only SHA-1 text is a dummy test checksum, and the pre-existing artifact hash uses SHA-256.
Container-Privileges ✅ Passed The PR changes only Python code and tests; the diff contains no container/Kubernetes manifests or prohibited privilege settings.
No-Sensitive-Data-In-Logs ✅ Passed New alignment logs contain only RPM names, architectures, and EVRs; they do not log passwords, tokens, PII, URLs, hostnames, or customer data.
No-Hardcoded-Secrets ✅ Passed Changed Python files contain only public/example URLs; scans found no credential-bearing URLs, secret-named literal assignments, private keys, or long base64 strings.
No-Injection-Vectors ✅ Passed The added lockfile logic only reads RPM metadata and writes with yaml.safe_dump; scans found no SQL concatenation, shell=True, eval/exec, pickle.loads, os.system, or unsafe YAML load.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@rayfordj

rayfordj commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

/hold for tests
/override ci/prow/art-pre-commit-check

@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 Aug 3, 2026
@openshift-ci

openshift-ci Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

@rayfordj: Overrode contexts on behalf of rayfordj: ci/prow/art-pre-commit-check

Details

In response to this:

/hold for tests
/override ci/prow/art-pre-commit-check

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.

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

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

851-879: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Consider validating the target on all affected arches before replacing any.

The loop replaces each arch independently. If the target EVR is missing from one arch's loaded repos, that arch keeps its higher version while the other arches are downgraded. The result is still mismatched, and the downgrades were then unnecessary. test_alignment_warns_when_target_version_not_found covers the two-arch case only, where no replacement happens.

Collect the candidate replacements per package first. Apply them only when every arch above the target resolves the target EVR. Otherwise skip that package and log one warning.

🤖 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 `@doozer/doozerlib/lockfile.py` around lines 851 - 879, Update the replacement
logic around replacement_rpms and _find_rpm_by_evr_in_repos to collect
candidates per package across all affected arches before mutating
replacement_rpms. Apply replacements only when every arch above the target
resolves the target EVR; if any arch is missing it, skip that package entirely
and emit one warning, preserving all existing versions. Keep already-aligned
arches excluded from validation.
🤖 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 `@doozer/doozerlib/lockfile.py`:
- Around line 790-808: Update the docstring for the RPM alignment method to
describe selecting the minimum of the per-architecture latest EVRs, matching the
implementation and inline comment near the target-version calculation. Remove
the claim that this value is the highest EVR available on all architectures,
while preserving the documented handling of pinned entries and returned
structure.
- Around line 890-899: Update the rebuild loop in _fetch_rpms_info_per_arch’s
alignment logic to deduplicate each arch list by (rpm.name, rpm.evr), matching
the existing invariant used when fetching RPM metadata. Ensure replacing the
latest entry does not append a duplicate when a pinned entry already has the
target EVR, while preserving distinct packages and sorting the resulting list.

---

Nitpick comments:
In `@doozer/doozerlib/lockfile.py`:
- Around line 851-879: Update the replacement logic around replacement_rpms and
_find_rpm_by_evr_in_repos to collect candidates per package across all affected
arches before mutating replacement_rpms. Apply replacements only when every arch
above the target resolves the target EVR; if any arch is missing it, skip that
package entirely and emit one warning, preserving all existing versions. Keep
already-aligned arches excluded from validation.
🪄 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-eng/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e64aa445-6c32-49c1-a993-001131dbf79a

📥 Commits

Reviewing files that changed from the base of the PR and between 7ee863a and 87a01d0.

📒 Files selected for processing (2)
  • doozer/doozerlib/lockfile.py
  • doozer/tests/test_lockfile_alignment.py

Comment thread doozer/doozerlib/lockfile.py Outdated
Comment thread doozer/doozerlib/lockfile.py Outdated
@rayfordj

rayfordj commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

/override ci/prow/art-pre-commit-check

@openshift-ci

openshift-ci Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

@rayfordj: Overrode contexts on behalf of rayfordj: ci/prow/art-pre-commit-check

Details

In response to this:

/override ci/prow/art-pre-commit-check

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.

@redhat-chai-bot
redhat-chai-bot force-pushed the fix/cross-arch-rpm-version-alignment branch from 87a01d0 to 32ac21b Compare August 3, 2026 19:01
@rayfordj

rayfordj commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

/override ci/prow/art-pre-commit-check

@openshift-ci

openshift-ci Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

@rayfordj: Overrode contexts on behalf of rayfordj: ci/prow/art-pre-commit-check

Details

In response to this:

/override ci/prow/art-pre-commit-check

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.

When independent per-arch RPM resolution picks different "latest"
versions, Conforma rpm_packages.unique_version violations occur at
release time because multi-arch images end up with different RPM
versions per architecture.

Add _align_cross_arch_versions() to RPMLockfileGenerator that runs
after validation and before the lockfile is written. For each package
appearing on 2+ arches with mismatched latest EVRs, it downgrades
the higher arches to the highest version available on ALL arches
by scanning loaded repos for the target version. NVR-pinned entries
are preserved unchanged.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@redhat-chai-bot
redhat-chai-bot force-pushed the fix/cross-arch-rpm-version-alignment branch from 32ac21b to 8f1e569 Compare August 3, 2026 19:33
@rayfordj

rayfordj commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

/override ci/prow/art-pre-commit-check

@openshift-ci

openshift-ci Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

@rayfordj: Overrode contexts on behalf of rayfordj: ci/prow/art-pre-commit-check

Details

In response to this:

/override ci/prow/art-pre-commit-check

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.

@openshift-ci

openshift-ci Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

@redhat-chai-bot: 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 8f1e569 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.

@rayfordj

rayfordj commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

/override ci/prow/art-pre-commit-check

@openshift-ci

openshift-ci Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

@rayfordj: Overrode contexts on behalf of rayfordj: ci/prow/art-pre-commit-check

Details

In response to this:

/override ci/prow/art-pre-commit-check

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.

@rayfordj

rayfordj commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

/close
-> #2967

@openshift-ci openshift-ci Bot closed this Aug 4, 2026
@openshift-ci

openshift-ci Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

@rayfordj: Closed this PR.

Details

In response to this:

/close
-> #2967

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

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.

2 participants