fix(bootstrap): don't invoke sudo when already running as root

The pipx/mcp-CLI step and the Hermes goose installer both called
`sudo -u <user> ...` 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 <noreply@anthropic.com>
This commit is contained in:
2026-07-01 12:33:19 +02:00
parent e4b529b71b
commit fdab6282e6

View File

@@ -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