#!/usr/bin/env bash set -euo pipefail umask 077 if [[ "$(id -u)" != 0 || "$#" != 1 ]]; then printf 'Usage (root): %s /path/to/config.json\n' "$0" >&2 exit 1 fi SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" python3 - "$1" <<'PY' import json,re,sys from pathlib import Path from uuid import UUID cfg=json.loads(Path(sys.argv[1]).read_text()) assert re.fullmatch(r'[0-9a-f]{40}',cfg['initial_revision']), 'Installed commit required' assert cfg['owner_ids'], 'Deployment owner required' for owner in cfg['owner_ids']: UUID(owner) for key in ('project_dir','ssh_key','known_hosts'): assert Path(cfg[key]).exists(), f'Missing {key}' assert Path(cfg['project_dir'],'backend/.env').exists() assert Path(cfg['project_dir'],'deploy/local/.state/dashboard/config.js').exists() assert cfg['repository'].startswith('ssh://'), 'Use authenticated SSH, not plain HTTP' Path(cfg['state_dir']).mkdir(parents=True,exist_ok=True) PY install -d -m 700 /etc/replypier-updater if [[ "$(realpath "$1")" != /etc/replypier-updater/config.json ]]; then install -m 600 "$1" /etc/replypier-updater/config.json else chmod 600 /etc/replypier-updater/config.json fi install -d -m 755 /opt/replypier-updater install -m 644 "${SCRIPT_DIR}"/updater/*.py /opt/replypier-updater/ install -m 644 "${SCRIPT_DIR}"/systemd/* /etc/systemd/system/ install -d -m 755 /etc/systemd/system/replypier-backend.service.d cat > /etc/systemd/system/replypier-backend.service.d/update-recovery.conf <<'EOF' [Unit] Requires=replypier-update-recover.service After=replypier-update-recover.service EOF python3 - <<'PY' import sys sys.path.insert(0,'/opt/replypier-updater') from state import config,transaction with transaction(config()): pass PY systemctl daemon-reload systemctl enable --now replypier-update-recover.service replypier-update-check.timer printf '\nInstalled. Check manually: python3 /opt/replypier-updater/cli.py check\n'