Native ApisCP integration, adapted from apiscp-kopia's Layer 2 against the real borg Layer 1 subcommands: - Borg_Module_Surrogate: admin + PRIVILEGE_SITE verbs, sudo boundary, config whitelist (now enforced), site-owner verbs derive the site from the auth context only, ownsDatabase gate, confirm-guarded destructive import. - Admin GUI (apps/borg, "Borg Backups"): repository (BORG_REPO/passphrase/ encryption/RSH, check-access, init, one-time recovery-key panel + download + irrecoverable tick), backup selection, retention + excludes + prune-now, schedule, maintenance (compact) + verify (check), notifications, tabbed layout, running overlay, double-submit guard, consolidated Restore workflow. - Site-owner GUI (apps/myborgbackups, "My Borg Backups"): restore files / whole account / databases, run own backup, scoped to the caller's own site. - Account hooks, install-layer2.sh, uninstall.sh (safe default, --purge). Borg differences vs kopia are handled: no backend types/sftp/server, no browse/ subpath or point-in-time (restores newest archive; archive dates shown for info), retention via config + `borg prune` (no global policy), import-db takes no dumpfile. All PHP lints clean; controller verb calls all resolve to the module.
114 lines
4.7 KiB
Bash
114 lines
4.7 KiB
Bash
#!/bin/sh
|
|
#
|
|
# uninstall.sh: remove apiscp-borg (Layer 1 engine + Layer 2 panel integration).
|
|
#
|
|
# What it ALWAYS removes:
|
|
# - the systemd timer/service (disabled + stopped first) and any schedule drop-in
|
|
# - the Layer 1 binaries and shared library
|
|
# - the Layer 2 module, both GUI apps, our menu links, account hooks, and the
|
|
# scoped sudoers file
|
|
# - the Prometheus textfile metric
|
|
#
|
|
# What it KEEPS by default (so an uninstall never destroys your ability to
|
|
# recover): the Borg repository and all its archives (never touched), the borg
|
|
# binary itself, /etc/apiscp-borg/config (holds the repository passphrase),
|
|
# the staging dir, and the key backup dir.
|
|
#
|
|
# Pass --purge to ALSO delete /etc/apiscp-borg (config + passphrase!), the
|
|
# staging dir (/var/lib/apiscp-borg), and the key backup dir. The Borg
|
|
# repository and its archives are STILL not touched; remove those yourself with
|
|
# borg if you really want the backups gone.
|
|
#
|
|
# Run as root on the ApisCP host. Idempotent.
|
|
|
|
set -u
|
|
|
|
PURGE=0
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--purge) PURGE=1 ;;
|
|
-h|--help) sed -n '2,22p' "$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; }
|
|
|
|
LIBDIR=/usr/local/lib/apiscp-borg
|
|
BINDIR=/usr/local/bin
|
|
UNITDIR=/etc/systemd/system
|
|
CFGDIR=/etc/apiscp-borg
|
|
STAGE=/var/lib/apiscp-borg
|
|
CP_ROOT="${CP_ROOT:-/usr/local/apnscp}"
|
|
|
|
echo "== Layer 2: ApisCP panel integration =="
|
|
# Module.
|
|
rm -f "$CP_ROOT/lib/modules/surrogates/borg.php" && echo "removed module surrogate" || true
|
|
# GUI apps (both editions).
|
|
rm -rf "$CP_ROOT/config/custom/apps/borg" "$CP_ROOT/config/custom/apps/myborgbackups" && echo "removed GUI apps" || true
|
|
# Menu links: strip our create_link lines (and their marker comment); drop the
|
|
# file only if it becomes effectively empty.
|
|
for _tpl in admin site; do
|
|
_f="$CP_ROOT/config/custom/templates/$_tpl.php"
|
|
[ -f "$_f" ] || continue
|
|
if grep -q "apps/borg\|apps/myborgbackups\|apiscp-borg" "$_f"; then
|
|
_tmp=$(mktemp)
|
|
# Drop our marker comments and any create_link referencing our apps.
|
|
grep -v "apiscp-borg" "$_f" | grep -v "create_link(.*apps/borg" | grep -v "create_link(.*apps/myborgbackups" > "$_tmp"
|
|
# If nothing but "<?php" and whitespace remains, remove the file entirely.
|
|
if [ -z "$(grep -vE '^\s*(<\?php)?\s*$' "$_tmp")" ]; then
|
|
rm -f "$_f"; echo "removed $_tpl.php menu (was ours only)"
|
|
else
|
|
install -m 0644 "$_tmp" "$_f"; echo "stripped our link from $_tpl.php"
|
|
fi
|
|
rm -f "$_tmp"
|
|
fi
|
|
done
|
|
# Account hooks (only the ones that are ours).
|
|
for _hook in addDomain suspendDomain deleteDomain; do
|
|
_h="$CP_ROOT/config/custom/hooks/$_hook.sh"
|
|
[ -f "$_h" ] && grep -q apiscp-borg "$_h" 2>/dev/null && { rm -f "$_h"; echo "removed hook $_hook.sh"; }
|
|
done
|
|
# Sudoers.
|
|
rm -f /etc/sudoers.d/apiscp-borg && echo "removed sudoers drop-in" || true
|
|
# Restart the panel so it forgets the app/menu.
|
|
systemctl restart apnscp 2>/dev/null || echo " restart apnscp yourself to drop the menu entry" >&2
|
|
|
|
echo "== Layer 1: engine =="
|
|
# Stop + disable + remove the timer/service and any schedule drop-in.
|
|
systemctl disable --now borg-apiscp-backup.timer 2>/dev/null || true
|
|
systemctl stop borg-apiscp-backup.service 2>/dev/null || true
|
|
rm -f "$UNITDIR/borg-apiscp-backup.timer" "$UNITDIR/borg-apiscp-backup.service"
|
|
rm -rf "$UNITDIR/borg-apiscp-backup.timer.d"
|
|
systemctl daemon-reload 2>/dev/null || true
|
|
echo "removed systemd units"
|
|
# Binaries + library.
|
|
rm -f "$BINDIR/borg-apiscp-backup" "$BINDIR/borg-apiscp-restore" "$BINDIR/borg-apiscp-repo"
|
|
rm -rf "$LIBDIR"
|
|
echo "removed binaries and library"
|
|
# Prometheus metric, if any.
|
|
for d in /var/lib/node_exporter/textfile_collector /var/lib/prometheus/node-exporter /var/lib/prometheus/node_exporter; do
|
|
rm -f "$d/apiscp-borg.prom" 2>/dev/null || true
|
|
done
|
|
|
|
if [ "$PURGE" = 1 ]; then
|
|
echo "== purge: removing config, staging, and key backups =="
|
|
# Read KEY_BACKUP_DIR from the config before deleting it.
|
|
_keydir=/root/apiscp-borg-keys
|
|
[ -r "$CFGDIR/config" ] && _keydir=$(sed -n "s/^[[:space:]]*KEY_BACKUP_DIR[[:space:]]*=[[:space:]]*['\"]\{0,1\}\([^'\"]*\)['\"]\{0,1\}.*/\1/p" "$CFGDIR/config" | head -1)
|
|
[ -n "$_keydir" ] || _keydir=/root/apiscp-borg-keys
|
|
rm -rf "$CFGDIR" "$STAGE"
|
|
echo "removed $CFGDIR and $STAGE"
|
|
echo "NOTE: the key backup dir ($_keydir) is your ONLY offline copy of the repository passphrase/key."
|
|
echo " Remove it yourself if you are certain: rm -rf '$_keydir'"
|
|
else
|
|
echo "kept $CFGDIR (repository passphrase), $STAGE, and the key backup dir."
|
|
echo "Re-run with --purge to remove them too."
|
|
fi
|
|
|
|
cat <<'EOF'
|
|
|
|
Uninstalled. The Borg repository and all its archives were NOT touched: your
|
|
backups are intact and can still be restored with plain borg, or by
|
|
reinstalling apiscp-borg. borg itself was left installed.
|
|
EOF
|