#!/usr/bin/env bash # ═══════════════════════════════════════════════════════════ # install.sh — bootstrap Breakglass Mirror on a fresh Ubuntu # ═══════════════════════════════════════════════════════════ # Run as root (or with sudo) on a fresh Ubuntu 22.04+ VM. # # What this does: # 1. Installs git, git-lfs, curl, jq # 2. Creates a dedicated 'breakglass' system user # 3. Copies scripts to /opt/breakglass/ # 4. Sets up config directory at /etc/breakglass/ # 5. Creates data and log directories # 6. Installs and enables systemd timers # 7. Prompts for Gitea token and writes initial config # # Usage: # sudo bash install.sh # ═══════════════════════════════════════════════════════════ set -euo pipefail # ── Colour helpers ─────────────────────────────────────── RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' CYAN='\033[0;36m' NC='\033[0m' info() { printf "${CYAN}▸${NC} %s\n" "$*"; } ok() { printf "${GREEN}✓${NC} %s\n" "$*"; } warn() { printf "${YELLOW}⚠${NC} %s\n" "$*"; } err() { printf "${RED}✗${NC} %s\n" "$*" >&2; } # ── Preflight ──────────────────────────────────────────── if [[ $EUID -ne 0 ]]; then err "This script must be run as root (use sudo)" exit 1 fi SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" info "Breakglass Mirror installer" echo "" # ── 1. System packages ────────────────────────────────── info "Installing system packages …" apt-get update -qq apt-get install -y -qq git git-lfs curl jq msmtp msmtp-mta >/dev/null 2>&1 || \ apt-get install -y -qq git git-lfs curl jq >/dev/null 2>&1 git lfs install --system >/dev/null 2>&1 ok "Packages installed" # ── 2. System user ────────────────────────────────────── info "Creating breakglass system user …" if id breakglass &>/dev/null; then ok "User already exists" else useradd --system --shell /usr/sbin/nologin --home-dir /var/lib/breakglass --create-home breakglass ok "User created" fi # ── 3. Directory structure ────────────────────────────── info "Creating directories …" mkdir -p /opt/breakglass/scripts mkdir -p /etc/breakglass mkdir -p /var/lib/breakglass/repos mkdir -p /var/lib/breakglass/audit mkdir -p /var/log/breakglass chown -R breakglass:breakglass /var/lib/breakglass /var/log/breakglass # Make audit directory append-only at the filesystem level # (root can still override, but it prevents accidental deletion) chattr +a /var/lib/breakglass/audit 2>/dev/null || \ warn "Could not set append-only attribute on audit dir (needs ext4/xfs)" ok "Directories ready" # ── 4. Copy scripts ───────────────────────────────────── info "Installing scripts …" cp "$SCRIPT_DIR/scripts/breakglass-sync.sh" /opt/breakglass/scripts/ cp "$SCRIPT_DIR/scripts/breakglass-healthcheck.sh" /opt/breakglass/scripts/ chmod +x /opt/breakglass/scripts/*.sh ok "Scripts installed to /opt/breakglass/scripts/" # ── 5. Copy config templates ──────────────────────────── info "Setting up configuration …" cp "$SCRIPT_DIR/config/sources.yml" /etc/breakglass/sources.yml ok "sources.yml → /etc/breakglass/sources.yml" # ── 6. Interactive config ─────────────────────────────── echo "" info "Let's configure your mirror. You can edit /etc/breakglass/mirror.env later." echo "" read -rp " Gitea URL [https://git.mineracks.com]: " INPUT_GITEA_URL GITEA_URL="${INPUT_GITEA_URL:-https://git.mineracks.com}" read -rp " Gitea username [mineracks]: " INPUT_GITEA_USER GITEA_USER="${INPUT_GITEA_USER:-mineracks}" read -rp " Gitea personal access token: " INPUT_GITEA_TOKEN if [[ -z "$INPUT_GITEA_TOKEN" ]]; then warn "No token entered — you'll need to edit /etc/breakglass/mirror.env before first run" fi read -rp " GitHub token (optional, for rate limits): " INPUT_GH_TOKEN read -rp " Notification method [none/ntfy/email/telegram]: " INPUT_NOTIFY NOTIFY="${INPUT_NOTIFY:-none}" NTFY_TOPIC="" NTFY_SERVER="https://ntfy.sh" NOTIFY_EMAIL="" TG_TOKEN="" TG_CHAT="" case "$NOTIFY" in ntfy) read -rp " ntfy topic: " NTFY_TOPIC read -rp " ntfy server [https://ntfy.sh]: " INPUT_NTFY_SERVER NTFY_SERVER="${INPUT_NTFY_SERVER:-https://ntfy.sh}" ;; email) read -rp " Notification email address: " NOTIFY_EMAIL ;; telegram) read -rp " Telegram bot token: " TG_TOKEN read -rp " Telegram chat ID: " TG_CHAT ;; esac cat > /etc/breakglass/mirror.env <