diff --git a/manage-server/install.sh b/manage-server/install.sh index c1b92a4..7f66d9e 100755 --- a/manage-server/install.sh +++ b/manage-server/install.sh @@ -4,12 +4,8 @@ # Idempotent. Generates secrets on first run, reuses .env afterwards. # Container-based via Podman or Docker (auto-detected). # -# Supported: Linux (amd64/arm64), macOS (Intel/Apple Silicon). -# For Windows use install.ps1 instead. -# # Usage: -# Linux: sudo bash install.sh -# macOS: bash install.sh +# sudo bash install.sh # # Flags (all optional): # --gateway-hostname HOST Agent mTLS hostname (defaults to current FQDN). @@ -24,14 +20,6 @@ cd "$SCRIPT_DIR" info() { printf '[manage-server] %s\n' "$*"; } die() { printf '[manage-server] error: %s\n' "$*" >&2; exit 1; } -# Portable in-place sed: BSD sed (macOS) requires an explicit empty backup suffix. -OS=$(uname -s) -if [[ "$OS" == "Darwin" ]]; then - sed_inplace() { sed -i '' "$@"; } -else - sed_inplace() { sed -i "$@"; } -fi - # ── arg parsing ────────────────────────────────────────────────────────── GATEWAY_HOST="" HOST_IP="" @@ -48,17 +36,7 @@ while [[ $# -gt 0 ]]; do esac done -# Docker/Podman Desktop on macOS runs rootless; only Linux needs root. -[[ "$OS" != "Linux" || $EUID -eq 0 ]] || die "must run as root (on Linux use: sudo bash install.sh)" - -# ── architecture detection ─────────────────────────────────────────────── -case "$(uname -m)" in - x86_64) ARCH=amd64 ;; - aarch64|arm64) ARCH=arm64 ;; # aarch64 = Linux, arm64 = macOS Apple Silicon - *) die "unsupported architecture: $(uname -m) (supported: x86_64, aarch64, arm64)" ;; -esac -OS_LABEL=$(echo "$OS" | tr '[:upper:]' '[:lower:]') -info "architecture: ${OS_LABEL}/$ARCH" +[[ $EUID -eq 0 ]] || die "must run as root" # ── runtime detection ──────────────────────────────────────────────────── if command -v podman-compose >/dev/null 2>&1; then @@ -71,7 +49,7 @@ elif docker compose version >/dev/null 2>&1; then COMPOSE=(docker compose) RUNTIME=docker else - die "no compose runtime found. Install Docker Desktop or podman-compose." + die "no compose runtime found. Install podman-compose or docker compose." fi info "using runtime: $RUNTIME" @@ -87,7 +65,7 @@ if [[ ! -f "$ENV_FILE" ]]; then WORKER_KEY=$(openssl rand -hex 16) VAULT_KEY=$(openssl rand -hex 32) - sed_inplace \ + sed -i \ -e "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$PG_PASS|" \ -e "s|^TRITON_MANAGE_JWT_SIGNING_KEY=.*|TRITON_MANAGE_JWT_SIGNING_KEY=$JWT_KEY|" \ -e "s|^TRITON_MANAGE_WORKER_KEY=.*|TRITON_MANAGE_WORKER_KEY=$WORKER_KEY|" \ @@ -95,10 +73,9 @@ if [[ ! -f "$ENV_FILE" ]]; then "$ENV_FILE" info "vault key generated (PostgreSQL AES-256-GCM)" - [[ -n "$GATEWAY_HOST" ]] && sed_inplace "s|^TRITON_MANAGE_GATEWAY_HOSTNAME=.*|TRITON_MANAGE_GATEWAY_HOSTNAME=$GATEWAY_HOST|" "$ENV_FILE" - [[ -n "$HOST_IP" ]] && sed_inplace "s|^TRITON_MANAGE_HOST_IP=.*|TRITON_MANAGE_HOST_IP=$HOST_IP|" "$ENV_FILE" - # IMAGE has no placeholder line in env.template — append it directly. - [[ -n "$IMAGE" ]] && printf '\nTRITON_MANAGE_IMAGE=%s\n' "$IMAGE" >> "$ENV_FILE" + [[ -n "$GATEWAY_HOST" ]] && sed -i "s|^TRITON_MANAGE_GATEWAY_HOSTNAME=.*|TRITON_MANAGE_GATEWAY_HOSTNAME=$GATEWAY_HOST|" "$ENV_FILE" + [[ -n "$HOST_IP" ]] && sed -i "s|^TRITON_MANAGE_HOST_IP=.*|TRITON_MANAGE_HOST_IP=$HOST_IP|" "$ENV_FILE" + [[ -n "$IMAGE" ]] && sed -i "s|^TRITON_MANAGE_IMAGE=.*|TRITON_MANAGE_IMAGE=$IMAGE|" "$ENV_FILE" info ".env created at $ENV_FILE" info " back this up — it contains the JWT signing key, worker key, and vault key" diff --git a/manage-server/uninstall.sh b/manage-server/uninstall.sh index 1e0d721..52d87af 100755 --- a/manage-server/uninstall.sh +++ b/manage-server/uninstall.sh @@ -1,17 +1,12 @@ #!/usr/bin/env bash # uninstall.sh — stop and remove Manage Server containers. # -# By default, KEEPS the PostgreSQL volume (scan history, hosts, users) -# and the installer directory (preserves .env secrets for reinstall). -# Pass --purge-data to delete volumes + installer directory — irreversible. -# -# Supported: Linux (amd64/arm64), macOS (Intel/Apple Silicon). -# For Windows use uninstall.ps1 instead. +# By default, KEEPS the PostgreSQL volume (scan history, hosts, users). +# Pass --purge-data to delete the volumes as well — irreversible. # # Usage: -# Linux: sudo bash uninstall.sh # stop + remove containers, keep DB + .env -# Linux: sudo bash uninstall.sh --purge-data # also delete DB, volumes, and installer dir -# macOS: bash uninstall.sh [--purge-data] +# sudo bash uninstall.sh # stop + remove containers, keep DB +# sudo bash uninstall.sh --purge-data # also delete DB + binaries volume set -euo pipefail SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)" @@ -20,10 +15,7 @@ cd "$SCRIPT_DIR" info() { printf '[manage-server] %s\n' "$*"; } die() { printf '[manage-server] error: %s\n' "$*" >&2; exit 1; } -OS=$(uname -s) - -# Docker/Podman Desktop on macOS runs rootless; only Linux needs root. -[[ "$OS" != "Linux" || $EUID -eq 0 ]] || die "must run as root (on Linux use: sudo bash uninstall.sh)" +[[ $EUID -eq 0 ]] || die "must run as root" PURGE=0 while [[ $# -gt 0 ]]; do @@ -34,9 +26,9 @@ while [[ $# -gt 0 ]]; do esac done -if command -v podman-compose >/dev/null 2>&1; then COMPOSE=(podman-compose); RUNTIME=podman -elif podman compose version >/dev/null 2>&1; then COMPOSE=(podman compose); RUNTIME=podman -elif docker compose version >/dev/null 2>&1; then COMPOSE=(docker compose); RUNTIME=docker +if command -v podman-compose >/dev/null 2>&1; then COMPOSE=(podman-compose) +elif podman compose version >/dev/null 2>&1; then COMPOSE=(podman compose) +elif docker compose version >/dev/null 2>&1; then COMPOSE=(docker compose) else die "no compose runtime found"; fi if [[ -f .env ]]; then @@ -44,22 +36,23 @@ if [[ -f .env ]]; then "${COMPOSE[@]}" --env-file .env down else info ".env not found, attempting raw container cleanup..." - "$RUNTIME" rm -f triton-manageserver triton-manage-db 2>/dev/null || true + podman rm -f triton-manageserver triton-manage-db 2>/dev/null || true fi if [[ $PURGE -eq 1 ]]; then info "DESTRUCTIVE: removing manage server volumes..." info " this deletes: scan history, hosts, users, worker binaries" + read -r -p " Are you sure? Type 'yes' to confirm: " CONFIRM + [[ "$CONFIRM" == "yes" ]] || die "aborted" for vol in triton-manage-db-data triton-manage-bins; do - "$RUNTIME" volume rm -f "$vol" 2>/dev/null || true + podman volume rm -f "$vol" 2>/dev/null \ + || docker volume rm -f "$vol" 2>/dev/null \ + || true done info " volumes removed" - info " removing installer directory $SCRIPT_DIR..." - rm -rf "$SCRIPT_DIR" - info " installer directory removed" + info " .env still on disk at $SCRIPT_DIR/.env — delete manually if desired" else info "DB + bins volumes retained (run with --purge-data to delete)" - info ".env preserved at $SCRIPT_DIR/.env — secrets reused on reinstall" fi info "uninstall complete"