Repository files, collaboration, releases and project activity.
archforge-external-status / scripts/restore.shmain
▤ scripts/restore.sh1702 bytes
25 lines · Select a line number for a permalink
1
#!/usr/bin/env bash2
set -Eeuo pipefail3
umask 0774
[[ $EUID -eq 0 ]] || { echo 'Run with sudo.' >&2; exit 1; }5
[[ $# -eq 1 && -f "$1" ]] || { echo "Usage: sudo $0 /var/backups/archforge-status/backup-....tar.gz"; exit 1; }6
FILE=$(realpath -- "$1")7
[[ "$FILE" == /var/backups/archforge-status/backup-*.tar.gz ]] || { echo 'Backups must be from the managed backup directory' >&2; exit 1; }8
TMP=$(mktemp -d)9
trap 'rm -rf "$TMP"' EXIT10
# Reject unexpected entries, symlinks and paths before extracting as root.11
while IFS= read -r item; do case "$item" in ./|./status.db|./status.env|./msmtprc) ;; *) echo "Unsafe archive path: $item" >&2; exit 1;; esac; done < <(tar -tzf "$FILE")12
while IFS= read -r type; do [[ "$type" == '-' || "$type" == 'd' ]] || { echo 'Unsupported archive file type' >&2;exit 1;}; done < <(tar -tvzf "$FILE" | cut -c1)13
tar -xzf "$FILE" -C "$TMP" --no-same-owner --no-same-permissions14
[[ -s "$TMP/status.env" ]] || { echo 'Backup does not contain status.env'; exit 1; }15
echo 'This will replace the live database and configuration.'16
read -rp "Type RESTORE to continue: " OK17
[[ "$OK" == RESTORE ]] || exit 118
systemctl stop archforge-status19
rm -f /var/lib/archforge-status/status.db-wal /var/lib/archforge-status/status.db-shm20
if [[ -f "$TMP/status.db" ]]; then install -o archforge-status -g archforge-status -m 600 "$TMP/status.db" /var/lib/archforge-status/status.db; fi21
install -o root -g archforge-status -m 640 "$TMP/status.env" /etc/archforge-status/status.env22
if [[ -f "$TMP/msmtprc" ]]; then install -o archforge-status -g archforge-status -m 600 "$TMP/msmtprc" /etc/archforge-status/msmtprc; fi23
systemctl start archforge-status24
systemctl --no-pager --full status archforge-status