#!/usr/bin/env bash # SPDX-FileCopyrightText: 2022 Patrick Spek # # SPDX-License-Identifier: AGPL-3.0-or-later subcommand() { # Retrieve the passphrase used by Borg BORG_PASSPHRASE="$(config "bashtard.backup.passphrase")" if [[ -z "$BORG_PASSPHRASE" ]] then emerg "$BASHTARD_NAME/backup" "No passphrase set in bashtard.backup.passphrase" return 3 fi export BORG_PASSPHRASE # Run backups for all configured elements, if none were explicitly # specified if (( $# < 1 )) then debug "$BASHTARD_NAME/backup" "Retrieving elements from config" while read -r element do set -- "$@" "$(config "$element")" done < <(config_subkeys "bashtard.backup.elements") fi # If there are still no configured elements, this is a good time to # return an error instead if (( $# < 1 )) then emerg "$BASHTARD_NAME/backup" "No elements to back up" return 3 fi # Loop over all repositories, and run backup functions for each of them while read -r key do index="$(awk -F. '{ print $NF }' <<< "$key")" for element in "$@" do "backup_$element" "$index" done info "$BASHTARD_NAME/backup/$index" "Backups completed" done < <(config_subkeys "bashtard.backup.repositories") } backup_filesystem() { local index=$1 ; shift local borg local cmd_create local cmd_prune local indexes borg="$(config "bashtard.backup.borg.command" "borg")" remote="$(config "bashtard.backup.borg.remote_paths.$index" "borg")" repo="$(config "bashtard.backup.repositories.$index")" if ! command -v "$borg" > /dev/null 2>&1 then emerg "$BASHTARD_NAME/backup/$index" "The backup command depends on '$borg' being installed and available in your \$PATH" return 4 fi # Prune old backups info "$BASHTARD_NAME/backup/$index" "Pruning filesystem backups in $repo" cmd_prune=( "$borg" "prune" "--keep-daily" "$(config "bashtard.backup.keep.daily")" "--keep-weekly" "$(config "bashtard.backup.keep.weekly")" "--keep-monthly" "$(config "bashtard.backup.keep.monthly")" "--keep-yearly" "$(config "bashtard.backup.keep.yearly")" "--prefix" "{fqdn}-" "--remote-path" "$remote" "$repo/hostfs" ) notice "$BASHTARD_NAME/backup/$index" "> ${cmd_prune[*]}" ${cmd_prune[@]} # Create new backups info "$BASHTARD_NAME/backup/$index" "Writing new filesystem backup to $repo" cmd_create=( "$borg" "create" "--one-file-system" "--remote-path" "$remote" "$repo/hostfs::{fqdn}-$(datetime)" ) # Add all paths to the command while read -r path do cmd_create+=("$(config "$path")") done < <(config_subkeys "bashtard.backup.fs.paths") notice "$BASHTARD_NAME/backup/$index" "> ${cmd_create[*]}" ${cmd_create[@]} } backup_database_postgresql() { local index=$1 ; shift local borg local remote local repo if ! command -v "psql" > /dev/null 2>&1 then emerg "$BASHTARD_NAME/backup/$index" "The backup command depends on 'psql' being installed and available in your \$PATH" return 4 fi if ! command -v "pg_dump" > /dev/null 2>&1 then emerg "$BASHTARD_NAME/backup/$index" "The backup command depends on 'pg_dump' being installed and available in your \$PATH" return 4 fi PGPASSWORD="$(config "bashtard.backup.db.postgresql.password" "")" PGUSER="$(config "bashtard.backup.db.postgresql.user" "postgres")" borg="$(config "bashtard.backup.borg.command" "borg")" remote="$(config "bashtard.backup.borg.remote_paths.$index" "borg")" repo="$(config "bashtard.backup.repositories.$index")" [[ -n $PGPASSWORD ]] && export PGPASSWORD export PGUSER while read -r database do [[ $database == "postgres" ]] && continue [[ $database =~ template* ]] && continue local cmd_create local cmd_prune # Prune old backups info "$BASHTARD_NAME/backup/$index" "Pruning PostgreSQL backups of $database in $repo" cmd_prune=( "$borg" "prune" "--keep-daily" "$(config "bashtard.backup.keep.daily")" "--keep-weekly" "$(config "bashtard.backup.keep.weekly")" "--keep-monthly" "$(config "bashtard.backup.keep.monthly")" "--keep-yearly" "$(config "bashtard.backup.keep.yearly")" "--prefix" "$database-" "--remote-path" "$remote" "$repo/postgresql-$database" ) notice "$BASHTARD_NAME/backup/$index" "> ${cmd_prune[*]}" ${cmd_prune[@]} # Create new backups info "$BASHTARD_NAME/backup/$index" "Writing new PostgreSQL backup of $database to $repo" cmd_create=( "borg" "create" "--remote-path" "$remote" "$repo/postgresql-$database::$database-$(datetime)" "-" ) notice "$BASHTARD_NAME/backup/$index" "> pg_dump "$database" | ${cmd_create[*]}" pg_dump "$database" | ${cmd_create[@]} done < <(psql -AXt -d template1 -c "SELECT datname FROM pg_database") }