#!/bin/bash # ============================================================================= # Officer — install # ============================================================================= # # One command, blank machine to running platform. It runs the two halves in # order and does nothing else itself: # # setup/machine-setup/machine-setup.sh a usable machine — packages, tailnet, # runtimes, docker, shell # setup/officer-setup.sh the platform on top of it — repo, # dependencies, postgres, .env, secret # store, schema, build, pm2 # # They stay two scripts because they answer two different questions and are worth # running separately: a machine you already trust needs only the second, and a # machine you are rebuilding needs only the first. This is the wrapper for the # case where you want both, which is most first runs. # # Both are re-runnable. Each remembers the steps it finished and skips them, so # stopping halfway and coming back costs nothing. # # ── Privileges ── # # 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)" MACHINE="$SCRIPT_DIR/setup/machine-setup/machine-setup.sh" OFFICER="$SCRIPT_DIR/setup/officer-setup.sh" BOLD='\033[1m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' say() { echo -e "$*"; } die() { echo -e "${YELLOW}error:${NC} $*" >&2 exit 1 } [[ -r "$MACHINE" ]] || die "missing $MACHINE" [[ -r "$OFFICER" ]] || die "missing $OFFICER" # Which halves to run. Both by default. RUN_MACHINE=true RUN_OFFICER=true for arg in "$@"; do case "$arg" in --machine-only) RUN_OFFICER=false ;; --officer-only) RUN_MACHINE=false ;; -h | --help) say "usage: install.sh [--machine-only | --officer-only]" say "" say " no flags both halves, machine first" say " --machine-only stop after the machine is provisioned" say " --officer-only the platform only, on a machine you already trust" exit 0 ;; *) die "unknown option: $arg" ;; esac done KERNEL="$(uname -s)" 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" ;; *) die "unsupported system: $KERNEL. Officer installs on Linux and macOS." ;; esac say "" say "${BOLD}Officer install${NC}" say " system: $KERNEL" $RUN_MACHINE && say " 1/2 machine setup" $RUN_OFFICER && say " $($RUN_MACHINE && echo 2/2 || echo 1/1) officer setup" say "" say " Either half can be run on its own later:" say " scripts/setup/machine-setup/machine-setup.sh" say " scripts/setup/officer-setup.sh" say "" # Not `set -e`'s job: a half that exits non-zero should say which half, and stop # before the next one starts on a machine that is not ready for it. if $RUN_MACHINE; then bash "$MACHINE" || die "machine setup did not finish — fix what it reported, then run this again" fi if $RUN_OFFICER; then bash "$OFFICER" || die "officer setup did not finish — fix what it reported, then run this again" fi say "" say "${GREEN}Done.${NC}"