diff --git a/CHANGELOG.md b/CHANGELOG.md index bd99125..b9fe290 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,16 @@ All notable changes to RigForge are documented here. The format is based on ## [Unreleased] +### Fixed + +- **Debian: dependency install no longer fails on `linux-tools-common` (#327).** The apt dependency + list named `linux-tools-common` unconditionally, but that package is Ubuntu-only — Debian ships + cpupower as `linux-cpupower` — and apt's install transaction is all-or-nothing, so the one unknown + name failed the ENTIRE install: git, build-essential and cmake never arrived either. `setup` now + probes with `apt-cache show` (the same guard the kernel-versioned `linux-tools-$(uname -r)` + package already had) and adds whichever name the distro actually ships; when neither exists it + warns and moves on — cpupower is a tuning aid, never worth losing the compiler toolchain over. + ## [1.13.1] - 2026-08-01 ### Fixed diff --git a/rigforge.sh b/rigforge.sh index f6fa9e0..2fefea9 100755 --- a/rigforge.sh +++ b/rigforge.sh @@ -738,7 +738,20 @@ _detect_pkg_manager() { DEP_LIST="git build-essential cmake libuv1-dev libssl-dev libhwloc-dev gettext-base python3" if [ "$OS_TYPE" == "Linux" ]; then # msr-tools (rdmsr): lets `doctor` verify the prefetcher MSR mod actually applied (#66). - DEP_LIST="$DEP_LIST linux-tools-common msr-tools" + DEP_LIST="$DEP_LIST msr-tools" + # cpupower's package name differs by distro: linux-tools-common on Ubuntu, + # linux-cpupower on Debian. apt's install transaction is all-or-nothing, so one unknown + # name would fail the ENTIRE dependency install — gcc/cmake included (#327). Probe with + # apt-cache show (same guard as the kernel-versioned package below) and add only the + # name this distro actually ships; when neither exists, warn and carry on — cpupower is + # a tuning aid, never worth losing the compiler toolchain over. + if apt-cache show linux-tools-common &>/dev/null; then + DEP_LIST="$DEP_LIST linux-tools-common" + elif apt-cache show linux-cpupower &>/dev/null; then + DEP_LIST="$DEP_LIST linux-cpupower" + else + warn "No cpupower package found (tried linux-tools-common, linux-cpupower) — skipping it. Frequency tuning via cpupower may be unavailable." + fi if apt-cache show "linux-tools-$(uname -r)" &>/dev/null; then DEP_LIST="$DEP_LIST linux-tools-$(uname -r)" fi diff --git a/tests/run.sh b/tests/run.sh index 10c3d02..b01cec6 100644 --- a/tests/run.sh +++ b/tests/run.sh @@ -2534,6 +2534,56 @@ chmod +x "$LT"/* PATH="$LT" CALL_LOG="$LT/calls.log" install_dependencies /dev/null 2>&1 assert_contains "apt install list includes linux-tools- (#74)" "$(cat "$LT/calls.log")" "linux-tools-6.0.0-rig" +# The same run doubles as the Ubuntu cpupower shape (#327): apt-cache says linux-tools-common +# exists, so it's picked and the Debian name never enters the list. +assert_contains "Ubuntu shape: cpupower via linux-tools-common (#327)" "$(cat "$LT/calls.log")" "linux-tools-common" +assert_absent "Ubuntu shape: linux-cpupower stays out (#327)" "$(cat "$LT/calls.log")" "linux-cpupower" + +# #327: cpupower's apt package is distro-dependent — linux-tools-common (Ubuntu) vs linux-cpupower +# (Debian) — and apt's all-or-nothing transaction means one unknown name kills the ENTIRE dependency +# install (gcc/cmake included). The probe must pick the name the distro ships, and a double miss must +# warn without touching the toolchain install. Ubuntu shape is asserted on the #74 run above. +echo "== unit: apt cpupower package probe — Debian / neither exists (#327) ==" +DEB="$(mktemp -d "$SANDBOX/deb327.XXXXXX")" +printf '#!/bin/sh\nexit 1\n' >"$DEB/dpkg" # every dep "missing" -> all go to the install list +cat >"$DEB/apt-cache" <<'EOF' +#!/bin/sh +# Debian trixie shape: linux-cpupower exists; linux-tools-common and linux-tools- do not. +case "$*" in *linux-cpupower*) exit 0 ;; *) exit 1 ;; esac +EOF +printf '#!/bin/sh\necho "[apt-get] $*" >>"$CALL_LOG"\n' >"$DEB/apt-get" +printf '#!/bin/sh\nwhile [ "${1#*=}" != "$1" ]; do export "$1"; shift; done\nexec "$@"\n' >"$DEB/sudo" +printf '#!/bin/sh\necho 6.0.0-rig\n' >"$DEB/uname" +chmod +x "$DEB"/* +: >"$DEB/calls.log" +( + source "$SCRIPT" + OS_TYPE=Linux REAL_USER=test + PATH="$DEB" CALL_LOG="$DEB/calls.log" install_dependencies /dev/null 2>&1 +assert_contains "Debian shape: cpupower via linux-cpupower (#327)" "$(cat "$DEB/calls.log")" "linux-cpupower" +assert_absent "Debian shape: linux-tools-common stays out (#327)" "$(cat "$DEB/calls.log")" "linux-tools-common" + +# Neither name exists (apt-cache always says no): warn, keep going, and the toolchain still installs. +NC="$(mktemp -d "$SANDBOX/nc327.XXXXXX")" +printf '#!/bin/sh\nexit 1\n' >"$NC/dpkg" +printf '#!/bin/sh\nexit 1\n' >"$NC/apt-cache" # no cpupower package under ANY name +printf '#!/bin/sh\necho "[apt-get] $*" >>"$CALL_LOG"\n' >"$NC/apt-get" +printf '#!/bin/sh\nwhile [ "${1#*=}" != "$1" ]; do export "$1"; shift; done\nexec "$@"\n' >"$NC/sudo" +printf '#!/bin/sh\necho 6.0.0-rig\n' >"$NC/uname" +chmod +x "$NC"/* +: >"$NC/calls.log" +nc_out="$( ( + source "$SCRIPT" + OS_TYPE=Linux REAL_USER=test + PATH="$NC" CALL_LOG="$NC/calls.log" install_dependencies &1)" +rc=$? +assert_rc "no cpupower package never fails the install (#327)" "$rc" "0" +assert_contains "warns when no cpupower package exists (#327)" "$nc_out" "No cpupower package found" +assert_contains "toolchain still installs without a cpupower package (#327)" "$(cat "$NC/calls.log")" "build-essential" +assert_absent "no cpupower name reaches apt when neither exists (#327)" "$(cat "$NC/calls.log")" "linux-tools-common" +assert_absent "linux-cpupower also stays out when absent (#327)" "$(cat "$NC/calls.log")" "linux-cpupower" # check_prerequisites (the jq bootstrap) had NO test. jq is deliberately kept OFF the scenario PATH so the # install branch runs; each dir holds ONLY the package manager(s) under test, so `command -v` selects the