From 74c952b87907a36d84d404ad17a0695be4ac55df Mon Sep 17 00:00:00 2001 From: Sven van Ginkel Date: Mon, 5 Oct 2026 17:49:05 +0200 Subject: [PATCH] fix(agent): don't detect zypper-aptitude's apt-get wrapper as apt (#2523) --- agent/package_updates.go | 5 ++++- agent/package_updates_test.go | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/agent/package_updates.go b/agent/package_updates.go index da00419c5..9697f6392 100644 --- a/agent/package_updates.go +++ b/agent/package_updates.go @@ -141,7 +141,10 @@ func runningInContainer() bool { func detectPackageManager(dataDir string) (string, packageUpdatesCheck) { switch { - case commandExists("apt-get"): + // openSUSE's zypper-aptitude provides an apt-get wrapper around zypper, so + // apt also requires the apt package in dpkg's database. dpkg alone is not + // enough because openSUSE packages it too. + case commandExists("apt-get") && exec.Command("dpkg-query", "-W", "apt").Run() == nil: return "apt", checkApt case commandExists("dnf"): return "dnf", checkDnf diff --git a/agent/package_updates_test.go b/agent/package_updates_test.go index bb49f39d3..68d67134b 100644 --- a/agent/package_updates_test.go +++ b/agent/package_updates_test.go @@ -245,6 +245,29 @@ exit 100`, }) } +func TestDetectPackageManager(t *testing.T) { + tests := []struct { + name string + commands map[string]string + manager string + }{ + {"apt", map[string]string{"apt-get": "", "dpkg-query": "exit 0"}, "apt"}, + {"zypper-aptitude", map[string]string{"apt-get": "", "zypper": ""}, "zypper"}, + {"zypper-aptitude with dpkg", map[string]string{"apt-get": "", "dpkg-query": "exit 1", "zypper": ""}, "zypper"}, + {"dnf", map[string]string{"dnf": "", "rpm": ""}, "dnf"}, + {"none", nil, ""}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + fakeCommands(t, tt.commands) + // only the fake commands, so the host's package managers are not found + t.Setenv("PATH", strings.SplitN(os.Getenv("PATH"), string(os.PathListSeparator), 2)[0]) + manager, _ := detectPackageManager(t.TempDir()) + assert.Equal(t, tt.manager, manager) + }) + } +} + func TestParseZypperTable(t *testing.T) { tests := []struct { file string