112 lines
4.0 KiB
Bash
112 lines
4.0 KiB
Bash
#!/bin/bash
|
|
|
|
TITLE="Backup"
|
|
DESCRIPTION="Back up your home folder daily to your Nextcloud files"
|
|
|
|
CORE_CONF="$HOME/.config/coredesktop/core.conf"
|
|
BACKUP_CONF="$HOME/.config/coredesktop/backup.conf"
|
|
UNITS="$HOME/.config/systemd/user"
|
|
source "$COREDESKTOP/configure.d/lib/nextcloud.sh"
|
|
[ -f "$CORE_CONF" ] && source "$CORE_CONF"
|
|
|
|
is_installed() {
|
|
command -v restic > /dev/null && command -v rclone > /dev/null && command -v secret-tool > /dev/null
|
|
}
|
|
|
|
is_configured() {
|
|
source "$COREDESKTOP/system/backup-env.sh" > /dev/null || return 1
|
|
[ -n "$RESTIC_PASSWORD_COMMAND" ] && systemctl --user is-enabled -q coredesktop-backup.timer
|
|
}
|
|
|
|
save_secret() {
|
|
printf '%s' "$3" | secret-tool store --label "CoreDesktop backup $1 ($2)" \
|
|
coredesktop backup item "$1" url "$2"
|
|
}
|
|
|
|
# The backup gets its own app password, so revoking it stops only backups
|
|
nextcloud_login() {
|
|
local tries
|
|
[ -n "$(backup_secret nextcloud "$WEBDAV")" ] \
|
|
&& rclone lsf --max-depth 1 ":webdav:" > /dev/null 2>&1 && return 0
|
|
for tries in 1 2 3; do
|
|
read -rsp "Your Core password: " PASSWORD
|
|
echo
|
|
nextcloud_app_password "CoreDesktop backup on $HOSTNAME"
|
|
case $? in
|
|
0) break ;;
|
|
2) echo "Nextcloud says that password is wrong." ;;
|
|
*) echo "Couldn't reach Nextcloud at $NEXTCLOUD."; return 1 ;;
|
|
esac
|
|
done
|
|
unset PASSWORD
|
|
[ -n "$APP_PASSWORD" ] || return 1
|
|
save_secret nextcloud "$WEBDAV" "$APP_PASSWORD" || return 1
|
|
unset APP_PASSWORD
|
|
RCLONE_WEBDAV_PASS="$(backup_secret nextcloud "$WEBDAV" | rclone obscure -)"
|
|
}
|
|
|
|
new_passphrase() {
|
|
local pass
|
|
pass="$(head -c 24 /dev/urandom | base64)"
|
|
echo "Your backup is encrypted with this passphrase:"
|
|
echo
|
|
echo " $pass"
|
|
echo
|
|
echo "Save it somewhere other than this computer, such as Bitwarden. Without it, the"
|
|
echo "backup can't be read if this computer is lost. It's kept in your keyring so the"
|
|
echo "daily backup can run."
|
|
until confirm "Have you saved it?"; do :; done
|
|
save_secret passphrase "$WEBDAV/$BACKUP_DIR" "$pass"
|
|
}
|
|
|
|
run_configure() {
|
|
local pass
|
|
if [ -z "$CORE_DOMAIN" ] || [ -z "$CORE_EMAIL" ]; then
|
|
echo "Backups go to your Nextcloud files, so set up your Core first: configure core"
|
|
return 1
|
|
fi
|
|
CORE_USER="${CORE_EMAIL%@*}"
|
|
NEXTCLOUD="https://nextcloud.$CORE_DOMAIN"
|
|
WEBDAV="$NEXTCLOUD/remote.php/dav/files/$CORE_USER"
|
|
BACKUP_DIR=".backup-$HOSTNAME"
|
|
|
|
mkdir -p "$(dirname "$BACKUP_CONF")"
|
|
{
|
|
printf 'BACKUP_WEBDAV=%q\n' "$WEBDAV"
|
|
printf 'BACKUP_USER=%q\n' "$CORE_USER"
|
|
printf 'BACKUP_DIR=%q\n' "$BACKUP_DIR"
|
|
} > "$BACKUP_CONF"
|
|
source "$COREDESKTOP/system/backup-env.sh"
|
|
|
|
nextcloud_login || { echo "Couldn't sign in to Nextcloud."; return 1; }
|
|
|
|
if rclone lsf --files-only ":webdav:$BACKUP_DIR" 2> /dev/null | grep -qx config; then
|
|
# Already there, e.g. after reinstalling: it needs the passphrase from then
|
|
if [ -z "$RESTIC_PASSWORD_COMMAND" ] || ! restic cat config &> /dev/null; then
|
|
echo "There's already a backup in $BACKUP_DIR in your Nextcloud files."
|
|
read -rsp "Its passphrase: " pass
|
|
echo
|
|
RESTIC_PASSWORD_COMMAND= RESTIC_PASSWORD="$pass" restic cat config > /dev/null \
|
|
|| { echo "restic couldn't open it with that passphrase."; return 1; }
|
|
save_secret passphrase "$WEBDAV/$BACKUP_DIR" "$pass" || return 1
|
|
fi
|
|
echo "Using the backup in $BACKUP_DIR."
|
|
else
|
|
new_passphrase || return 1
|
|
source "$COREDESKTOP/system/backup-env.sh"
|
|
echo "Creating the backup in $BACKUP_DIR in your Nextcloud files..."
|
|
restic init || return 1
|
|
fi
|
|
|
|
mkdir -p "$UNITS"
|
|
cp "$COREDESKTOP"/system/systemd/coredesktop-backup.{service,timer} "$UNITS/" || return 1
|
|
systemctl --user daemon-reload
|
|
systemctl --user enable --now coredesktop-backup.timer || return 1
|
|
echo "Your home folder will be backed up daily to $BACKUP_DIR in your Nextcloud files."
|
|
|
|
if confirm_yes "Start the first backup now? It runs in the background and can take hours."; then
|
|
systemctl --user start --no-block coredesktop-backup.service
|
|
echo "Started. To follow it: journalctl --user -fu coredesktop-backup"
|
|
fi
|
|
}
|