From fdab6282e6437186eae8ea7353288a6692433bc7 Mon Sep 17 00:00:00 2001 From: dtoro Date: Wed, 1 Jul 2026 12:33:19 +0200 Subject: [PATCH] fix(bootstrap): don't invoke sudo when already running as root MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pipx/mcp-CLI step and the Hermes goose installer both called `sudo -u ...` unconditionally. On minimal Linux images reached via `ssh root@host` (no SUDO_USER, and often no `sudo` binary at all — seen live on strong), this failed with "sudo: command not found" and silently no-opped the mcp CLI install. Added a run_as() helper that only shells out to sudo when there's a real invoking user distinct from root. Co-Authored-By: Claude Sonnet 5 --- bootstrap.sh | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index 643171f..2dcdd0b 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -83,6 +83,21 @@ run() { fi } +# Run a command as the enrolling human user when one exists (i.e. this +# script was invoked via `sudo bash bootstrap.sh` from a real login), and +# directly otherwise. Minimal Linux images (bare Proxmox/Debian installs +# reached via `ssh root@host`) often don't even have a `sudo` binary +# installed — calling `sudo -u root ...` on those unconditionally fails +# with "sudo: command not found" even though we're already root and don't +# need to switch users at all. +run_as() { + if [ -n "${SUDO_USER:-}" ] && [ "$SUDO_USER" != "root" ]; then + sudo -u "$SUDO_USER" -- "$@" + else + "$@" + fi +} + # -------- preflight -------- if [ "$(id -u)" -ne 0 ]; then echo "bootstrap.sh must run as root (use sudo)." >&2 @@ -430,9 +445,9 @@ if [ "$WITH_HERMES" -eq 1 ]; then echo "+ would run upstream goose installer and symlink to /usr/local/bin/goose" else # Upstream installer drops the binary at ~/.local/bin/goose for the - # invoking user. We run it as $H_USER then symlink system-wide. - sudo -u "$H_USER" \ - env CONFIGURE=false \ + # invoking user. We run it as $H_USER (via run_as) then symlink + # system-wide. + run_as env CONFIGURE=false \ bash -c 'curl -fsSL https://github.com/aaif-goose/goose/releases/download/stable/download_cli.sh | bash' if [ -x "$H_HOME/.local/bin/goose" ]; then ln -sfn "$H_HOME/.local/bin/goose" /usr/local/bin/goose @@ -595,7 +610,7 @@ if [ "$HKIND" != "lxc" ] && [ "$HKIND" != "vm" ]; then # Make sure pipx is available; OS-specific install. if ! command -v pipx >/dev/null 2>&1; then if [ "$OS" = "Darwin" ] && command -v brew >/dev/null 2>&1; then - sudo -u "${SUDO_USER:-$USER}" brew install pipx 2>&1 | tail -2 || true + run_as brew install pipx 2>&1 | tail -2 || true elif command -v dnf >/dev/null 2>&1; then dnf install -y pipx 2>&1 | tail -2 || true elif command -v apt-get >/dev/null 2>&1; then @@ -603,9 +618,9 @@ if [ "$HKIND" != "lxc" ] && [ "$HKIND" != "vm" ]; then fi fi if command -v pipx >/dev/null 2>&1; then - INVOKING_USER="${SUDO_USER:-$USER}" - sudo -u "$INVOKING_USER" -- bash -lc "pipx install 'mcp[cli]'" 2>&1 | tail -3 || true - sudo -u "$INVOKING_USER" -- bash -lc "pipx ensurepath" >/dev/null 2>&1 || true + INVOKING_USER="${SUDO_USER:-root}" + run_as bash -lc "pipx install 'mcp[cli]'" 2>&1 | tail -3 || true + run_as bash -lc "pipx ensurepath" >/dev/null 2>&1 || true echo "[bootstrap] mcp CLI installed for $INVOKING_USER via pipx" else echo "[bootstrap] WARNING: pipx unavailable; install manually: pipx install 'mcp[cli]'" >&2