Files
coredesktop/configure.d/20-backup.sh
T
2026-10-26 16:13:05 -06:00

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
}