Repository navigation
fix(install): stop requiring sudo when the driver install is already root - #305
Conversation
…root Every command in the native driver plan carried a literal `sudo ` prefix, applied unconditionally. As root that prefix is redundant; on a root host with no `sudo` binary it is fatal, and the first command dies with `sudo: not found` before any driver work happens. Containers and minimal cloud images are exactly that shape — root, no sudo — and `install driver` is the documented Linux driver path, so on those hosts it could not run. The command's own preflight already distinguished the two cases, promising `sudo` was needed only "when not running as root". Only the generator disagreed, so the preflight passed and execution then contradicted it. Resolve the escalation into a prefix that is empty when already root, and thread it through every distro plan builder. Resolution happens when the plan is built rather than when it runs, so the plan `--dry-run` prints, the plan the approval prompt shows, and the commands recorded in state.json are all the commands that actually execute. The preflight no longer claims a `sudo` binary is required when the plan has stopped using one. Non-root behaviour is unchanged: the existing plan tests pass untouched under an explicit non-root escalation. The new coverage asserts the absence of `sudo` across every supported distro rather than checking commands one by one, so a templating site missed on some distro fails the suite instead of shipping. Signed-off-by: Eugene Volen <Eugene.Volen@amd.com>
95a3bc9 to
fae3fef
Compare
r0x0r
left a comment
There was a problem hiding this comment.
LGTM.
Resolving the privilege escalation at plan-build time (via PrivilegeEscalation::detect()) rather than stripping a prefix at execution is the right design — it keeps --dry-run output, the approval prompt, and the commands persisted to state.json all consistent with what actually runs. The empty-prefix-when-already-root approach threads cleanly through every distro builder.
The test coverage is the strong point: the absence-of-sudo sweep across every distro from dkms_planning_os_releases(), the inverse off-root contract correctly scoped to Prepare/Execute (Verify probes stay unprivileged), and the mid-pipeline | sudo tee / | sudo gpg guard all mean a missed templating site fails the suite rather than shipping. The preflight correction (dropping the sudo-binary precondition when the plan won't use one) closes the stated-vs-actual contradiction. Platform gating on running_as_root() (#[cfg(target_os = "linux")], false elsewhere) checks out, and the off-Linux validate-only Windows path makes the default harmless.
Non-blocking: (1) the two self-hosted Strix Halo E2E lanes were still in progress at review time — worth confirming they finish green before merge; (2) please coordinate merge order with #291 so the shared xfail row doesn't XPASS the merge queue.
main's #305 (f2c3477) already fixed EAI-8053 — the driver install no longer prepends `sudo` when it is already running as root — and shipped unit tests over the install plan covering both the root and non-root cases. The e2e scenario this branch carried is therefore redundant, and no CI lane runs as uid 0, so it could never have executed anyway. Remove the scenario, its `@requires-root` tag, the `is_root` capability probe, the `mock-root` fixture and the expectations row. What remains is the EAI-8051 ComfyUI contract: - Register `comfyui.feature` in `FEATURE_KEYS` and renumber its scenario to `comfyui-01`, per the per-feature naming guard main added. - Require the install to exit 0 before asserting runtime health. Since #298 it does; without that premise a bail-out (no managed runtime, a failed download) would leave the runtime trivially unchanged and the scenario would report green having installed nothing. - Correct the now-stale comments claiming the install exits non-zero, and describe `find_venv_python` accurately: the documented layout is the first frontier entry, so the depth-capped walk is a fallback, not a cost the normal path pays. Signed-off-by: fredespi <fredrik.espinoza@gmail.com>
tests/e2e-cucumber/expectations.tomlfor the fixed ticket ID and removed/narrowed any now-stale xfail rows. — no such row exists onmainyet; see Coordination.Summary
rocm install driver --dkmsbuilt every command in its plan with a literalsudoprefix, applied unconditionally. As root that prefix is redundant; on a root host with nosudobinary it is fatal:Containers and minimal cloud images are exactly that shape — uid 0, no
sudo— and this is the documented Linux driver path, so on those hosts it could not run at all.Root cause: only the command generator was wrong. The command's own preflight already distinguished the two cases, promising
sudowas needed "when not running as root". The preflight passed and execution then contradicted it.What changed:
--dry-runprints, the plan the approval prompt shows, and the commands recorded instate.jsonare all the commands that actually execute. Stripping the prefix at execution instead would leave all three misreporting what ran.sudobinary is required when the plan has stopped using one.Non-root behaviour is unchanged — all 25 pre-existing driver plan tests pass untouched under an explicit non-root escalation, rather than having their expectations rewritten.
Risk: low. No change to execution, approval, or the state-file shape; only the text of the generated commands, and only when already root.
Test plan
sudoacross all eight supported distro paths rather than checking commands one by one, so a templating site missed on some distro fails the suite instead of shipping. The others cover the inverse (off root, every privileged command still escalates), shell-pipeline integrity (| tee,| gpg— which a naive leading-prefix strip would miss),state.jsonagreement, and the preflight change.rhel: a plan built as root must not invoke sudo, got 'sudo dnf clean all'. A green assertion that cannot fail would have been worse than none.cargo test -p rocm557 passed;clippy --workspace --all-targets -D warnings,fmtclean.mainafter therepo_version/package_releasesplit landed. The escalation parameter takesdnf_driver_plananddriver_plan_via_id_liketo 8 arguments, so both carry#[allow(clippy::too_many_arguments)]— the same treatment five other builders in this file already have. Every parameter is one already-resolved fact the command templates read; a struct would move the same list one level out without shortening it.--reconcilepath never reads the persisted command strings, so plans differing by uid cannot break it.Not verified locally, stated rather than skipped: the apt/DKMS path end to end. Every container on my machine inherits a WSL
/proc/version, sois_wsl_host()matches and the plan short-circuits to the ROCDXG branch before distro dispatch — the DKMS path is unreachable here regardless of the container image. I confirmed that short-circuit still behaves after this change, but that is a guard on the branch above the fix, not evidence the fix works. End-to-end verification is the root-runner scenario described below.Coordination
#291 adds a root-gated e2e scenario for this defect plus an
expectations.tomlxfail row. It is still open as of 2026-09-08, so there is no stale row for this PR to remove. Whichever merges second must reconcile: