Skip to content

feat(packagemanager): allow vendor change on zypper install - #419

Open
james-nesbitt wants to merge 1 commit into
k0sproject:mainfrom
james-nesbitt:zypper-allow-vendor-change
Open

feat(packagemanager): allow vendor change on zypper install#419
james-nesbitt wants to merge 1 commit into
k0sproject:mainfrom
james-nesbitt:zypper-allow-vendor-change

Conversation

@james-nesbitt

Copy link
Copy Markdown
Contributor

Fixes #417.

What

Pass --allow-vendor-change on the zypper install action in NewZypper, so PackageManager.Install succeeds non-interactively when the only dependency-resolution solution replaces a package from a different vendor.

Why

rig always runs zypper's non-interactive install (zypper install -y). By default zypper will not switch a package's vendor during an install, and non-interactively it does not accept the vendor-changing solution — it cancels and exits 4, with no actionable error. This affects any rig consumer installing a package whose resolution crosses a vendor boundary on SLES/openSUSE; it is not specific to any tool, repo, or package. Full mechanism, repro, and logs are in #417.

⚠️ This may be undesirable — RFC

This change is deliberately aggressive about package adoption. Passing --allow-vendor-change unconditionally lets zypper switch a package's vendor/origin on any install, which some operators may consider undesirable as a global default (it weakens the same-vendor guarantee zypper gives out of the box).

Raising as an RFC. If a global default isn't acceptable, the alternative is to gate it behind an opt-in install option — but that requires extending PackageManager.Install (today Install(ctx, packageNames ...string), no room for per-call options), a larger, breaking-ish API change affecting every manager and caller. Happy to implement whichever shape you prefer; this one-line version is the minimal demonstration.

Testing

  • go build ./packagemanager/... and go test ./packagemanager/... pass.
  • Manually verified on a SLES 15 instance: the un-flagged install exits 4 on a vendor-change resolution, and the same install with --allow-vendor-change succeeds (exit 0).

Written by AI: claude-sonnet-5

SLES cloud images (e.g. SUSE's SLES 15 SP7 AMIs) ship a SUSE-vendor
containerd package pre-installed. Installing a package that obsoletes it
from a different vendor (e.g. Mirantis/Docker containerd.io) makes zypper
treat the operation as a vendor change; non-interactively it refuses the
solution and exits 4, surfacing as an opaque install failure.

Pass --allow-vendor-change on the zypper install action so these installs
resolve without interaction.

NOTE: this is deliberately aggressive about package adoption and may be
undesirable as a global default -- it lets zypper switch a package's
vendor/origin during a normal install. Raising as an RFC: happy to gate it
behind an opt-in install option instead if maintainers prefer.

Written by AI: claude-sonnet-5

Signed-off-by: James Nesbitt <jnesbitt@mirantis.com>
@james-nesbitt

Copy link
Copy Markdown
Contributor Author

Replaces #418 , which I messed up in a rebase

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds zypper vendor switching to support non-interactive dependency resolution.

Changes:

  • Adds --allow-vendor-change to zypper installs.
  • Documents the resulting behavior.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packagemanager/zypper.go
// instead of cancelling with exit code 4.
func NewZypper(c cmd.ContextRunner) PackageManager {
return newUniversalPackageManager(c, "zypper", "zypper", "install -y", "remove -y", "refresh")
return newUniversalPackageManager(c, "zypper", "zypper", "install -y --allow-vendor-change", "remove -y", "refresh")
Comment thread packagemanager/zypper.go
// instead of cancelling with exit code 4.
func NewZypper(c cmd.ContextRunner) PackageManager {
return newUniversalPackageManager(c, "zypper", "zypper", "install -y", "remove -y", "refresh")
return newUniversalPackageManager(c, "zypper", "zypper", "install -y --allow-vendor-change", "remove -y", "refresh")
@kke

kke commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Hmm. Does not sound like it would be good to enable always.

@kke

kke commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

SLES exposes this as host policy in two places: solver.allowVendorChange in /etc/zypp/zypp.conf, and vendor equivalence classes in /etc/zypp/vendors.d/. The second is the better fit for as it whitelists just the one vendor equivalence you've decided to trust instead of disabling the check wholesale.

This vendor-change situation only arises once you've added a third-party repo, so that's the point where the vendor policy should be configured too, just like configuring the GPG keys etc in dpkg. As rig has no repo management API at all, adding the repo in the first place is already done in launchpad, configuring the vendor equivalence belongs in the same step in my opinion.

What I do think rig could do is to re-run zypper with --allow-vendor-change and --dry-run after zypper install failures and return a differrent error. If that was done, you could do something like:

if errors.Is(err, packagemanager.ErrVendorChangeRequired) {
    err = h.Sudo().ExecContext(ctx, "zypper install -y --allow-vendor-change foofoo")
}

instead of going through configuring the equivalence.

Can you confirm on a SLES box that the dry-run with the flag exits 0 in the case where the real install exits 4? Rig doesn't currently provide any (sane) way to inspect exit codes (just zero or error), maybe it should.

What comes to the "RFC" part here, I don't think rig should force the flag for everyone.

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.

zypper Install fails on vendor-change (from mirantis/launchpad)

3 participants