95 lines
3.4 KiB
Bash
95 lines
3.4 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"
|
|
[ -f "$CORE_CONF" ] && source "$CORE_CONF"
|
|
[ -f "$BACKUP_CONF" ] && source "$BACKUP_CONF"
|
|
|
|
is_installed() {
|
|
command -v borg > /dev/null && command -v secret-tool > /dev/null
|
|
}
|
|
|
|
# The passphrase is in the keyring under the repository's path, so the
|
|
# backup can run without asking
|
|
passphrase() {
|
|
secret-tool lookup coredesktop backup repo "$1"
|
|
}
|
|
|
|
is_configured() {
|
|
[ -n "$BORG_REPO" ] && [ -n "$(passphrase "$BORG_REPO")" ] \
|
|
&& systemctl --user is-enabled -q coredesktop-backup.timer
|
|
}
|
|
|
|
# system/backup uses borg 1.2 to 1.4; borg 2 changed its commands
|
|
borg_supported() {
|
|
local version
|
|
version="$(borg --version | awk '{print $2}')"
|
|
[[ "$version" =~ ^1\.([2-9]|[1-9][0-9])\. ]] && return 0
|
|
echo "This needs borg 1.2 to 1.4, and borg $version is installed."
|
|
return 1
|
|
}
|
|
|
|
save_passphrase() {
|
|
printf '%s' "$2" | secret-tool store --label "CoreDesktop backup ($1)" coredesktop backup repo "$1"
|
|
}
|
|
|
|
run_configure() {
|
|
local mount="/mnt/$CORE_DOMAIN" repo pass
|
|
borg_supported || return 1
|
|
if [ -z "$CORE_DOMAIN" ] || ! mountpoint -q "$mount"; then
|
|
echo "Backups go to your Nextcloud files, so set those up first (configure core), and check they're mounted."
|
|
return 1
|
|
fi
|
|
repo="$mount/.backup-$HOSTNAME"
|
|
|
|
if [ -f "$repo/config" ]; then
|
|
# Already there, e.g. after reinstalling: it needs the passphrase from then
|
|
pass="$(passphrase "$repo")"
|
|
if [ -z "$pass" ] || ! BORG_PASSPHRASE="$pass" borg info "$repo" &> /dev/null; then
|
|
echo "There's already a backup at $repo."
|
|
read -rsp "Its passphrase: " pass
|
|
echo
|
|
BORG_PASSPHRASE="$pass" borg info "$repo" > /dev/null || { echo "borg couldn't open it with that passphrase."; return 1; }
|
|
save_passphrase "$repo" "$pass" || return 1
|
|
fi
|
|
echo "Using the backup at $repo."
|
|
else
|
|
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_passphrase "$repo" "$pass" || return 1
|
|
echo "Creating the backup at $repo..."
|
|
BORG_PASSPHRASE="$pass" borg init --encryption=repokey-blake2 "$repo" || return 1
|
|
# davfs2 copies each file to a local cache before uploading it, and some
|
|
# servers refuse large uploads, so keep borg's files to 50 MB, not 500
|
|
BORG_PASSPHRASE="$pass" borg config "$repo" max_segment_size 52428800 || return 1
|
|
fi
|
|
|
|
mkdir -p "$(dirname "$BACKUP_CONF")"
|
|
{
|
|
printf 'BORG_REPO=%q\n' "$repo"
|
|
printf 'BACKUP_MOUNT=%q\n' "$mount"
|
|
} > "$BACKUP_CONF"
|
|
|
|
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 $repo."
|
|
|
|
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
|
|
}
|