diff --git a/scripts/install.sh b/scripts/install.sh index 558b8543..accc651d 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -20,14 +20,8 @@ # Both are re-runnable. Each remembers the steps it finished and skips them, so # stopping halfway and coming back costs nothing. # -# ── Privileges ── +# Run it as yourself — it asks for administrator rights when it needs them. # -# Linux needs root: apt, systemd units, useradd, netplan, ufw, and creating -# directories owned by the service account. macOS must NOT be root: Homebrew -# refuses to run as one, and there is nothing to chown because the account -# running this IS the owner. Both scripts enforce that themselves; this checks -# first so the failure arrives before anything has been done. - set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" @@ -72,12 +66,39 @@ case "$KERNEL" in Darwin) [[ "$EUID" -eq 0 ]] && die "do not run this with sudo on macOS — Homebrew refuses to run as root. Run it as yourself." ;; - Linux) - [[ "$EUID" -ne 0 ]] && die "please run as root: sudo ./scripts/install.sh" - ;; + Linux) ;; *) die "unsupported system: $KERNEL. Officer installs on Linux and macOS." ;; esac +SELF="$SCRIPT_DIR/install.sh" + +# ── Privileges: asked for, not demanded ── +# +# Run this as YOURSELF. On Linux it needs root for apt, systemd units, useradd, +# netplan, ufw and for creating directories owned by the service account — so it +# asks, once, through sudo, and re-executes itself. Typing `sudo` yourself works +# too and changes nothing, but it should not be the price of starting. +# +# Variables are passed to sudo explicitly rather than with -E. `env_reset` is the +# sudoers default and strips the environment, which is how DATA_PATH was lost +# once already; naming them on the command line survives it. +# +# macOS never escalates. Homebrew refuses to run as root, and nothing in the +# macOS path needs it — the account running this IS the owner, so there is +# nothing to chown and nothing to drop privileges to. +if [[ "$KERNEL" != "Darwin" && "$EUID" -ne 0 ]]; then + command -v sudo >/dev/null 2>&1 || die "this needs root and sudo is not installed — run it as root" + say "" + say " This needs administrator rights. You will be asked for your password." + say "" + exec sudo \ + OFFICER_ROOT="${OFFICER_ROOT:-}" \ + SETUP_USERNAME="${SETUP_USERNAME:-}" \ + MACHINE_ROLE="${MACHINE_ROLE:-}" \ + bash "$SELF" "$@" +fi + + say "" say "${BOLD}Officer install${NC}" say " system: $KERNEL" diff --git a/scripts/setup/machine-setup/machine-setup.sh b/scripts/setup/machine-setup/machine-setup.sh index 8b8c2f0a..881ca605 100755 --- a/scripts/setup/machine-setup/machine-setup.sh +++ b/scripts/setup/machine-setup/machine-setup.sh @@ -129,14 +129,30 @@ fi # It works out because the macOS path skips everything that needed root in the # first place (see MACOS_SKIP in lib/base.sh). What is left — brew, the Xcode # command line tools, the agent CLIs, bun — is all per-user by design. +# ── Privileges: asked for, not demanded ── +# +# Run this as YOURSELF. Linux needs root for apt, systemd units, useradd, netplan +# and ufw, so it asks through sudo and re-executes itself rather than making you +# type it. Variables go to sudo by name rather than with -E: `env_reset` is the +# sudoers default and strips the environment, which is how DATA_PATH was lost +# once already. +# +# macOS never escalates — Homebrew refuses to run as root, and the sections that +# needed root are the ones the macOS path skips. if [[ "$OS" == "macos" ]]; then if [[ "$EUID" -eq 0 ]]; then fail "Do not run this with sudo on macOS — Homebrew refuses to run as root. Run it as yourself." fi -else - if [[ "$EUID" -ne 0 ]]; then - fail "Please run as root: sudo ./machine-setup.sh" - fi +elif [[ "$EUID" -ne 0 ]]; then + command -v sudo >/dev/null 2>&1 || fail "This needs root and sudo is not installed — run it as root." + echo "" + echo " This needs administrator rights. You will be asked for your password." + echo "" + exec sudo \ + OFFICER_ROOT="${OFFICER_ROOT:-}" \ + SETUP_USERNAME="${SETUP_USERNAME:-}" \ + MACHINE_ROLE="${MACHINE_ROLE:-}" \ + bash "$SCRIPT_DIR/machine-setup.sh" "$@" fi # On macOS the account running the script IS the account, and there is nothing to diff --git a/scripts/setup/officer-setup.sh b/scripts/setup/officer-setup.sh index ef6c5501..8b7b461c 100755 --- a/scripts/setup/officer-setup.sh +++ b/scripts/setup/officer-setup.sh @@ -66,18 +66,29 @@ echo -e "${BOLD}╔════════════════════ echo -e "${BOLD}║ Officer Setup ║${NC}" echo -e "${BOLD}╚══════════════════════════════════════════════════╝${NC}" -# root on Linux, NOT root on macOS — the same split machine-setup makes, for the -# same reason. On Linux this creates directories owned by another account and -# drops privileges with `sudo -u`. On macOS the account running the script IS the -# owner, so there is nothing to chown and nothing to drop to — and Homebrew, which -# machine-setup ran just before this, refuses to run as root at all. -OFFICER_OS="$(uname -s)" -if [[ "$OFFICER_OS" == "Darwin" ]]; then +# ── Privileges: asked for, not demanded ── +# +# Run this as YOURSELF. It needs root on Linux, so it asks through sudo and +# re-executes itself rather than making you type it. Variables are passed to sudo +# by name rather than with -E, because `env_reset` is the sudoers default and +# strips the environment — which is how DATA_PATH was lost once already. +# +# macOS never escalates: Homebrew refuses to run as root, and the account running +# this IS the owner, so there is nothing to chown and nothing to drop to. +if [[ "$(uname -s)" == "Darwin" ]]; then if [[ "$EUID" -eq 0 ]]; then fail "Do not run this with sudo on macOS — run it as yourself." fi elif [[ "$EUID" -ne 0 ]]; then - fail "Please run as root: sudo ./officer-setup.sh" + command -v sudo >/dev/null 2>&1 || fail "This needs root and sudo is not installed — run it as root." + echo "" + echo " This needs administrator rights. You will be asked for your password." + echo "" + exec sudo \ + OFFICER_ROOT="${OFFICER_ROOT:-}" \ + SETUP_USERNAME="${SETUP_USERNAME:-}" \ + MACHINE_ROLE="${MACHINE_ROLE:-}" \ + bash "$SCRIPT_DIR/officer-setup.sh" "$@" fi # ── what machine-setup already established ──