#!/usr/bin/env bash # install.sh — Linux installer for the restic-manager agent. # # Usage (paste in shell): # curl -fsSL https://restic.lab.example/install.sh | \ # sudo RM_SERVER=https://restic.lab.example RM_TOKEN= sh # # What it does: # 1. detects arch (amd64 / arm64) # 2. fetches the matching agent binary from the server # 3. creates the restic-manager-agent service user # 4. lays down /etc/restic-manager/, /var/lib/restic-manager/ # 5. enrolls (POST /api/agents/enroll) using RM_TOKEN # 6. installs the systemd unit, enables, starts # 7. surfaces (but does NOT disable) any existing restic timers / # cron entries so the operator can decide what to do # # Idempotent — safe to re-run; will refuse if already enrolled # unless RM_FORCE_REENROLL=1 is set. set -euo pipefail : "${RM_SERVER:?must be set, e.g. https://restic.lab.example}" : "${RM_TOKEN:?must be set, the one-time token from the operator UI}" : "${RM_INSTALL_PREFIX:=/usr/local/bin}" : "${RM_CONFIG_DIR:=/etc/restic-manager}" : "${RM_STATE_DIR:=/var/lib/restic-manager}" : "${RM_USER:=restic-manager-agent}" : "${RM_GROUP:=restic-manager-agent}" : "${RM_FORCE_REENROLL:=0}" require_root() { if [ "$(id -u)" -ne 0 ]; then echo "install.sh: must be run as root" >&2 exit 1 fi } detect_arch() { case "$(uname -m)" in x86_64|amd64) echo amd64 ;; aarch64|arm64) echo arm64 ;; *) echo "unsupported architecture: $(uname -m)" >&2; exit 1 ;; esac } ensure_user() { if ! getent group "$RM_GROUP" >/dev/null; then groupadd --system "$RM_GROUP" fi if ! getent passwd "$RM_USER" >/dev/null; then useradd --system --gid "$RM_GROUP" \ --home-dir "$RM_STATE_DIR" --no-create-home \ --shell /usr/sbin/nologin \ "$RM_USER" fi } ensure_dirs() { install -d -m 0750 -o "$RM_USER" -g "$RM_GROUP" "$RM_CONFIG_DIR" install -d -m 0750 -o "$RM_USER" -g "$RM_GROUP" "$RM_STATE_DIR" } detect_existing_schedulers() { echo echo "==> Scanning for existing restic schedules (we will NOT touch them)" local found=0 if command -v systemctl >/dev/null 2>&1; then while IFS= read -r unit; do [ -n "$unit" ] || continue echo " [systemd] $unit" echo " disable with: systemctl disable --now $unit" found=1 done < <(systemctl list-unit-files --no-legend --type=timer 2>/dev/null \ | awk 'tolower($1) ~ /restic/ {print $1}') fi for f in /etc/cron.d/* /etc/cron.daily/* /etc/cron.hourly/* /etc/cron.weekly/*; do [ -f "$f" ] || continue if grep -qiI restic "$f" 2>/dev/null; then echo " [cron] $f" echo " review and remove or rename if you want this agent to take over" found=1 fi done if root_cron=$(crontab -l 2>/dev/null); then if echo "$root_cron" | grep -qi restic; then echo " [crontab -l] root crontab contains a restic entry" echo " review with: crontab -l" found=1 fi fi if [ $found -eq 0 ]; then echo " (none found)" fi echo } download_agent() { local arch out arch=$(detect_arch) out="$RM_INSTALL_PREFIX/restic-manager-agent" echo "==> Downloading restic-manager-agent (linux/$arch) from $RM_SERVER" # The server's /agent/binary endpoint serves the matching binary # for the requesting agent's arch. (P1-31; until then this URL # may need to be a static download.) curl -fsSL --retry 3 \ "$RM_SERVER/agent/binary?os=linux&arch=$arch" \ -o "$out.new" chmod +x "$out.new" mv -f "$out.new" "$out" echo " installed $out ($(file -b "$out" | head -1))" } enroll_agent() { local cfg="$RM_CONFIG_DIR/agent.yaml" if [ -s "$cfg" ] && [ "$RM_FORCE_REENROLL" != "1" ]; then echo "==> $cfg already exists; skipping enrollment" echo " (set RM_FORCE_REENROLL=1 to overwrite)" return fi echo "==> Enrolling agent with $RM_SERVER" sudo -u "$RM_USER" \ "$RM_INSTALL_PREFIX/restic-manager-agent" \ -config "$cfg" \ -enroll-server "$RM_SERVER" \ -enroll-token "$RM_TOKEN" } install_unit() { local unit="/etc/systemd/system/restic-manager-agent.service" echo "==> Installing systemd unit at $unit" curl -fsSL --retry 3 \ "$RM_SERVER/install/restic-manager-agent.service" \ -o "$unit" chmod 0644 "$unit" systemctl daemon-reload systemctl enable --now restic-manager-agent.service echo " started; tail with: journalctl -fu restic-manager-agent" } main() { require_root ensure_user ensure_dirs download_agent detect_existing_schedulers enroll_agent install_unit echo echo "==> done." echo " config: $RM_CONFIG_DIR/agent.yaml" echo " binary: $RM_INSTALL_PREFIX/restic-manager-agent" echo " service: systemctl status restic-manager-agent" echo " logs: journalctl -fu restic-manager-agent" } main "$@"