Initial scaffold: Borg engine + docs (Layer 1 milestone)

apiscp-borg is a sibling of apiscp-kopia built on BorgBackup. This first
milestone lands the project scaffold and the Layer 1 engine:
- borg-apiscp-backup: per-site named archives (siteN-shadow/info/db), fresh
  per-site DB dumps via ApisCP site-context export, system + custom archives,
  borg prune retention per prefix, Prometheus metrics, email notifications.
- apiscp-borg-common.sh: logging, mail, site/owner helpers.
- config example, systemd service+timer, install.sh, README, DESIGN.

Borg preserves POSIX ACLs and xattrs natively, so (unlike the kopia engine) no
metadata sidecar is required; DESIGN.md records how Borg reshapes the design.
Repository/restore tools, Layer 2 panel integration, hooks, uninstall, and the
full reference are the next milestones.
This commit is contained in:
Laurence Horrocks-Barlow 2026-07-24 22:33:37 +01:00
commit 2f0d93a0ae
10 changed files with 743 additions and 0 deletions

70
install.sh Normal file
View file

@ -0,0 +1,70 @@
#!/bin/sh
#
# install.sh: install the apiscp-borg Layer 1 engine (backup + timer).
#
# Idempotent. Run as root on an ApisCP server. It:
# - installs the shared library under /usr/local/lib/apiscp-borg
# - installs bin/ scripts into /usr/local/bin
# - installs the systemd service + timer
# - seeds /etc/apiscp-borg/config from the example (never overwrites yours)
#
# It does NOT install borg itself (install it with your package manager:
# `dnf install borgbackup` / `apt install borgbackup`), enable the timer, or
# create the Borg repository. Do those once you have reviewed the config.
#
# Layer 2 (the ApisCP panel module + GUIs + hooks) installs separately via
# install-layer2.sh once that milestone lands. See docs/DESIGN.md.
set -eu
for arg in "$@"; do
case "$arg" in
-h|--help) sed -n '2,18p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
*) echo "unknown option: $arg" >&2; exit 2 ;;
esac
done
[ "$(id -u)" = 0 ] || { echo "run as root" >&2; exit 1; }
SRC=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
command -v borg >/dev/null 2>&1 || echo "WARNING: borg not found on PATH; install borgbackup before running the engine" >&2
LIBDIR=/usr/local/lib/apiscp-borg
BINDIR=/usr/local/bin
UNITDIR=/etc/systemd/system
CFGDIR=/etc/apiscp-borg
echo "installing library -> $LIBDIR"
mkdir -p "$LIBDIR"
install -m 0644 "$SRC/lib/apiscp-borg-common.sh" "$LIBDIR/apiscp-borg-common.sh"
echo "installing binaries -> $BINDIR"
for b in borg-apiscp-backup borg-apiscp-repo borg-apiscp-restore; do
[ -f "$SRC/bin/$b" ] && install -m 0755 "$SRC/bin/$b" "$BINDIR/$b"
done
echo "installing systemd units -> $UNITDIR"
install -m 0644 "$SRC/systemd/borg-apiscp-backup.service" "$UNITDIR/borg-apiscp-backup.service"
install -m 0644 "$SRC/systemd/borg-apiscp-backup.timer" "$UNITDIR/borg-apiscp-backup.timer"
systemctl daemon-reload
echo "seeding config -> $CFGDIR/config"
mkdir -p "$CFGDIR"
if [ -f "$CFGDIR/config" ]; then
echo " $CFGDIR/config exists; leaving it untouched"
else
install -m 0600 "$SRC/etc/apiscp-borg.config.example" "$CFGDIR/config"
echo " seeded from example (0600, root); set BORG_REPO and BORG_PASSPHRASE before enabling"
fi
cat <<'EOF'
Installed. Next steps:
1. Install borgbackup if not already present.
2. Set BORG_REPO and BORG_PASSPHRASE in /etc/apiscp-borg/config.
3. Initialise the repository: borg-apiscp-repo init (once the repo tool lands)
or for now: BORG_REPO=... borg init --encryption=repokey-blake2 ::
4. Back up the passphrase/key OFF this machine.
5. Test a run: borg-apiscp-backup ; echo "exit=$?"
6. Enable nightly: systemctl enable --now borg-apiscp-backup.timer
EOF