feat(packagemanager): allow vendor change on zypper install - #419
feat(packagemanager): allow vendor change on zypper install#419james-nesbitt wants to merge 1 commit into
Conversation
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>
|
Replaces #418 , which I messed up in a rebase |
There was a problem hiding this comment.
Pull request overview
Adds zypper vendor switching to support non-interactive dependency resolution.
Changes:
- Adds
--allow-vendor-changeto 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.
| // 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") |
| // 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") |
|
Hmm. Does not sound like it would be good to enable always. |
|
SLES exposes this as host policy in two places: 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 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. |
Fixes #417.
What
Pass
--allow-vendor-changeon the zypper install action inNewZypper, soPackageManager.Installsucceeds 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 change is deliberately aggressive about package adoption. Passing
--allow-vendor-changeunconditionally 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(todayInstall(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/...andgo test ./packagemanager/...pass.--allow-vendor-changesucceeds (exit 0).Written by AI: claude-sonnet-5