Skip to content

deploy-from-self if skopeo < 1.22.2#5863

Draft
QiWang19 wants to merge 3 commits intoopenshift:mainfrom
QiWang19:multi-ostree-policy
Draft

deploy-from-self if skopeo < 1.22.2#5863
QiWang19 wants to merge 3 commits intoopenshift:mainfrom
QiWang19:multi-ostree-policy

Conversation

@QiWang19
Copy link
Copy Markdown
Member

@QiWang19 QiWang19 commented Apr 20, 2026

uses deploy-from-self when skopeo is actually older than 1.22.2 that has issue
with multi-arch sigstore verification

- What I did

- How to verify it

- Description for the changelog

Summary by CodeRabbit

  • Bug Fixes
    • Improved system update logic to properly handle cases where certain tool versions don't meet requirements. Updates will now use an alternative method when necessary tool dependencies aren't sufficiently up-to-date.

For skopeo < 1.22.2, create temp insecureAcceptAnything policy.json in rpm-ostree to avoid multi-arch release image signature errors.

Signed-off-by: Qi Wang <qiwan@redhat.com>
@openshift-merge-bot
Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Apr 20, 2026

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 Apr 20, 2026
@QiWang19
Copy link
Copy Markdown
Member Author

/test all

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 20, 2026

Walkthrough

The changes add a capability check function skopeoSupportsMultiArchSigstore() to verify if the installed skopeo version meets the minimum requirement (1.22.2), then apply this check as an additional fallback condition alongside the existing newEnough check in two update decision paths.

Changes

Cohort / File(s) Summary
Skopeo capability check addition
pkg/daemon/update.go
Introduced skopeoSupportsMultiArchSigstore() function that executes skopeo, parses version with semver, compares against 1.22.2 minimum, and memoizes result via sync.Once. Updated updateLayeredOS logic to force InplaceUpdateViaNewContainer when this check fails.
Update fallback conditions
pkg/daemon/daemon.go
Modified RunFirstbootCompleteMachineconfig to fall back to InplaceUpdateViaNewContainer when skopeoSupportsMultiArchSigstore() is false, alongside existing newEnough check. Updated associated log message to reflect combined rpm-ostree/skopeo readiness.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 11 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (11 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
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 Pull request modifies only implementation files (update.go, daemon.go) with no Ginkgo test files or test title definitions included.
Test Structure And Quality ✅ Passed PR modifies only production code files with no test code modifications, making the Ginkgo test quality check not applicable.
Microshift Test Compatibility ✅ Passed PR modifies only daemon source files (update.go, daemon.go) without adding any new Ginkgo e2e tests.
Single Node Openshift (Sno) Test Compatibility ✅ Passed Pull request modifies daemon code files that are not test files and do not contain Ginkgo e2e tests, so Single Node OpenShift test compatibility check is not applicable.
Topology-Aware Scheduling Compatibility ✅ Passed Pull request modifies only internal daemon logic for OS update compatibility checking without introducing topology-aware scheduling changes.
Ote Binary Stdout Contract ✅ Passed The new skopeoSupportsMultiArchSigstore() function uses klog for logging (stderr by default) and is called from runtime daemon operations, not binary initialization or suite setup, therefore does not violate OTE Binary Stdout Contract.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed PR modifies daemon implementation code only; no new Ginkgo e2e tests are added.
Title check ✅ Passed The title 'deploy-from-self if skopeo < 1.22.2' directly reflects the main functional change: using deploy-from-self mode when skopeo version is below 1.22.2, which aligns with the commit message and code changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

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

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

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Apr 20, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: QiWang19
Once this PR has been reviewed and has the lgtm label, please assign djoshy 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

Copy link
Copy Markdown

@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)
pkg/daemon/rpm-ostree.go (1)

305-317: Consider reducing fallback policy blast radius.

This fallback sets wildcard insecureAcceptAnything for all docker and containers-storage refs in rpm-ostreed. If not strictly required, scoping to the specific generated transport key would reduce temporary exposure.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/daemon/rpm-ostree.go` around lines 305 - 317, The fallback policy
currently applies signature.NewPRInsecureAcceptAnything() to the wildcard ""
scope for both "docker" and imagePolicyTransportContainerStorage, which opens
all refs; instead, narrow the blast radius by assigning the insecure
AcceptAnything requirement only to the specific transport key(s) used for
rpm-ostree in this routine (i.e., replace the "" map key with the generated
transport reference string used elsewhere in the function — the exact transport
key variable/name used for the rpm-ostree image refs — and do not add a global
wildcard entry), keeping the rest of signature.Policy unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/daemon/update.go`:
- Around line 2951-2987: The probe currently treats any skopeo --version parse
error as "false" which enables the permissive fallback; modify
skopeoSupportsMultiArchSigstore by introducing a probe-success flag (e.g.,
skopeoMultiArchSigstoreProbeSucceeded) that is only set to true when the command
runs and the version comparison completes successfully (use existing symbols
skopeoMultiArchSigstoreSupported.Do, skopeoMultiArchSigstoreSupportedValue,
minSkopeoVersionForMultiArchSigstore and semver parsing), and do not flip
skopeoMultiArchSigstoreSupportedValue on parse/exec errors; then update the code
path in rpm-ostree.go that currently gates permissive fallback on
skopeoMultiArchSigstoreSupportedValue to require the probe-success flag as well
(i.e., only allow the permissive branch when the probe succeeded and the version
is below the minimum).

---

Nitpick comments:
In `@pkg/daemon/rpm-ostree.go`:
- Around line 305-317: The fallback policy currently applies
signature.NewPRInsecureAcceptAnything() to the wildcard "" scope for both
"docker" and imagePolicyTransportContainerStorage, which opens all refs;
instead, narrow the blast radius by assigning the insecure AcceptAnything
requirement only to the specific transport key(s) used for rpm-ostree in this
routine (i.e., replace the "" map key with the generated transport reference
string used elsewhere in the function — the exact transport key variable/name
used for the rpm-ostree image refs — and do not add a global wildcard entry),
keeping the rest of signature.Policy unchanged.
🪄 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: Pro Plus

Run ID: fdc191e4-cfdd-4baa-81af-158a041031fa

📥 Commits

Reviewing files that changed from the base of the PR and between c3a9db7 and 90019b0.

📒 Files selected for processing (2)
  • pkg/daemon/rpm-ostree.go
  • pkg/daemon/update.go

Comment thread pkg/daemon/update.go
Comment on lines +2951 to +2987
func skopeoSupportsMultiArchSigstore() bool {
skopeoMultiArchSigstoreSupported.Do(func() {
// Multi-arch Sigstore verification requires skopeo >= 1.22.2.
// Older boot images will fail with "A signature was required, but no signature exists"
// when rpm-ostree attempts to pull multi-arch images with Sigstore enforcement.
cmd := exec.Command("skopeo", "--version")
out, err := cmd.CombinedOutput()
if err != nil {
klog.Errorf("failed to run skopeo --version: %v", err)
skopeoMultiArchSigstoreSupportedValue = false
return
}
// Example output: "skopeo version 1.21.0-dev commit: d8be59c1ecc5c1860b7bab4f60721d55da2cda9a"
outStr := strings.TrimSpace(string(out))
fields := strings.Fields(outStr)
if len(fields) < 3 {
klog.Errorf("failed to parse skopeo version output: %s", outStr)
skopeoMultiArchSigstoreSupportedValue = false
return
}

versionStr := fields[2]
if dashIdx := strings.Index(versionStr, "-"); dashIdx != -1 {
versionStr = versionStr[:dashIdx]
}

skopeoVersion, err := semver.NewVersion(versionStr)
if err != nil {
klog.Errorf("failed to parse skopeo version %s: %v", versionStr, err)
skopeoMultiArchSigstoreSupportedValue = false
return
}
skopeoMultiArchSigstoreSupportedValue = skopeoVersion.Compare(*semver.New(minSkopeoVersionForMultiArchSigstore)) >= 0
klog.Infof("skopeo version %s, multi-arch Sigstore support: %v", versionStr, skopeoMultiArchSigstoreSupportedValue)
})
return skopeoMultiArchSigstoreSupportedValue
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid fail-open downgrade when the skopeo probe fails.

At Line 2958, Line 2967, and Line 2978, probe/parsing errors force false, and that directly triggers the fully permissive policy branch in pkg/daemon/rpm-ostree.go Line 305. Detection failures should not silently disable verification.

🔧 Suggested direction
-var (
-	skopeoMultiArchSigstoreSupported      sync.Once
-	skopeoMultiArchSigstoreSupportedValue bool
-)
+var (
+	skopeoMultiArchSigstoreSupported      sync.Once
+	skopeoMultiArchSigstoreSupportedValue bool
+	skopeoMultiArchSigstoreProbeErr       error
+)

-func skopeoSupportsMultiArchSigstore() bool {
+func skopeoSupportsMultiArchSigstore() (bool, error) {
 	skopeoMultiArchSigstoreSupported.Do(func() {
 		cmd := exec.Command("skopeo", "--version")
 		out, err := cmd.CombinedOutput()
 		if err != nil {
-			klog.Errorf("failed to run skopeo --version: %v", err)
-			skopeoMultiArchSigstoreSupportedValue = false
+			skopeoMultiArchSigstoreProbeErr = fmt.Errorf("failed to run skopeo --version: %w", err)
 			return
 		}
 		...
 		if err != nil {
-			klog.Errorf("failed to parse skopeo version %s: %v", versionStr, err)
-			skopeoMultiArchSigstoreSupportedValue = false
+			skopeoMultiArchSigstoreProbeErr = fmt.Errorf("failed to parse skopeo version %s: %w", versionStr, err)
 			return
 		}
 		skopeoMultiArchSigstoreSupportedValue = skopeoVersion.Compare(*semver.New(minSkopeoVersionForMultiArchSigstore)) >= 0
 	})
-	return skopeoMultiArchSigstoreSupportedValue
+	return skopeoMultiArchSigstoreSupportedValue, skopeoMultiArchSigstoreProbeErr
 }

Then gate permissive fallback only when probe succeeded and version is truly below minimum.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/daemon/update.go` around lines 2951 - 2987, The probe currently treats
any skopeo --version parse error as "false" which enables the permissive
fallback; modify skopeoSupportsMultiArchSigstore by introducing a probe-success
flag (e.g., skopeoMultiArchSigstoreProbeSucceeded) that is only set to true when
the command runs and the version comparison completes successfully (use existing
symbols skopeoMultiArchSigstoreSupported.Do,
skopeoMultiArchSigstoreSupportedValue, minSkopeoVersionForMultiArchSigstore and
semver parsing), and do not flip skopeoMultiArchSigstoreSupportedValue on
parse/exec errors; then update the code path in rpm-ostree.go that currently
gates permissive fallback on skopeoMultiArchSigstoreSupportedValue to require
the probe-success flag as well (i.e., only allow the permissive branch when the
probe succeeded and the version is below the minimum).

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Apr 21, 2026

@QiWang19: all tests passed!

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.

uses deploy-from-self when skopeo is actually older than 1.22.2 that has issue
with multi-arch sigstore verification

Signed-off-by: Qi Wang <qiwan@redhat.com>
@QiWang19 QiWang19 changed the title Updated policy handling in rpm-ostree if skopeo < 1.22.2 deploy-from-self if skopeo < 1.22.2 Apr 21, 2026
Copy link
Copy Markdown

@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)
pkg/daemon/daemon.go (1)

1241-1242: Make fallback logs explicit about which capability failed.

The current message merges two failure modes. Logging both predicates improves triage when firstboot falls back to container mode.

🔎 Suggested refactor
- if !newEnough || !skopeoSupportsMultiArchSigstore() {
- 	logSystem("rpm-ostree or skopeo is not new enough for new-format image; forcing an update via container and queuing immediate reboot")
+ skopeoSupports := skopeoSupportsMultiArchSigstore()
+ if !newEnough || !skopeoSupports {
+ 	logSystem("forcing update via container and queuing immediate reboot (rpm-ostree-container-feature=%t, skopeo-multiarch-sigstore=%t)", newEnough, skopeoSupports)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/daemon/daemon.go` around lines 1241 - 1242, The fallback log message in
daemon.go currently conflates two checks; update the logSystem call in the
branch guarded by newEnough and skopeoSupportsMultiArchSigstore() to explicitly
state which capability failed by referencing the boolean newEnough and the
predicate skopeoSupportsMultiArchSigstore(), e.g., include both conditions or
their values in the message so the log indicates whether rpm-ostree is too old,
skopeo lacks multi-arch sigstore support, or both; modify the logSystem
invocation accordingly in the same conditional block where it currently emits
the combined message.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/daemon/daemon.go`:
- Around line 1239-1240: Update the comment that begins "If Skopeo used by
rpm-ostree..." to correct the typo and reverse the meaning: state that older
skopeo versions do NOT support multi-arch Sigstore verification (replace
"supporting" with "do not support" and fix "verificaiton" to "verification"), so
the comment accurately explains why we fall back to running a privileged
container. Keep the rest of the context and links unchanged.

---

Nitpick comments:
In `@pkg/daemon/daemon.go`:
- Around line 1241-1242: The fallback log message in daemon.go currently
conflates two checks; update the logSystem call in the branch guarded by
newEnough and skopeoSupportsMultiArchSigstore() to explicitly state which
capability failed by referencing the boolean newEnough and the predicate
skopeoSupportsMultiArchSigstore(), e.g., include both conditions or their values
in the message so the log indicates whether rpm-ostree is too old, skopeo lacks
multi-arch sigstore support, or both; modify the logSystem invocation
accordingly in the same conditional block where it currently emits the combined
message.
🪄 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: Pro Plus

Run ID: fae61a2d-3ff6-4259-9789-a07166a83738

📥 Commits

Reviewing files that changed from the base of the PR and between 90019b0 and e0bb024.

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

Comment thread pkg/daemon/daemon.go
Comment on lines +1239 to +1240
// If Skopeo used by rpm-ostree is an older version supporting multi-arch Sigstore verificaiton, run as a privileged container which has updated skopeo.
// See https://redhat.atlassian.net/browse/OCPBUGS-83826 and https://redhat.atlassian.net/browse/OCPBUGS-81187
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix fallback comment wording (reversed meaning + typo).

The comment currently says older skopeo versions are “supporting” multi-arch Sigstore verification and has a typo (“verificaiton”). It should say older versions do not support it.

✏️ Proposed comment fix
- // If Skopeo used by rpm-ostree is an older version supporting multi-arch Sigstore verificaiton, run as a privileged container which has updated skopeo.
+ // If skopeo used by rpm-ostree is an older version not supporting multi-arch Sigstore verification,
+ // run as a privileged container which has updated skopeo.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// If Skopeo used by rpm-ostree is an older version supporting multi-arch Sigstore verificaiton, run as a privileged container which has updated skopeo.
// See https://redhat.atlassian.net/browse/OCPBUGS-83826 and https://redhat.atlassian.net/browse/OCPBUGS-81187
// If skopeo used by rpm-ostree is an older version not supporting multi-arch Sigstore verification,
// run as a privileged container which has updated skopeo.
// See https://redhat.atlassian.net/browse/OCPBUGS-83826 and https://redhat.atlassian.net/browse/OCPBUGS-81187
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/daemon/daemon.go` around lines 1239 - 1240, Update the comment that
begins "If Skopeo used by rpm-ostree..." to correct the typo and reverse the
meaning: state that older skopeo versions do NOT support multi-arch Sigstore
verification (replace "supporting" with "do not support" and fix "verificaiton"
to "verification"), so the comment accurately explains why we fall back to
running a privileged container. Keep the rest of the context and links
unchanged.

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

Labels

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.

1 participant