#!/bin/bash log() { local message="$1" echo "$(date '+%Y-%m-%d %H:%M:%S') - $message" | tee -a "$LOG_FILE" } stop_container() { local c="$1" log "Stopping $c..." docker stop "$c" || { log "Error stopping $c"; exit 1; } } start_container() { local c="$1" log "Starting $c..." docker start "$c" || { log "Error starting $c"; exit 1; } } enable_maintenance_mode() { local c="$1" local cmd="$2" log "Enabling maintenance mode for $c..." # we explcitly do not want to stringify here # shellcheck disable=SC2086 docker exec -u www-data "$c" $cmd || { log "Error enabling maintenance mode"; exit 1; } } disable_maintenance_mode() { local c="$1" local cmd="$2" log "Disabling maintenance mode for $c..." # we explcitly do not want to stringify here # shellcheck disable=SC2086 docker exec -u www-data "$c" $cmd || { log "Error disabling maintenance mode"; exit 1; } } dump_postgres_db() { local c="$1" local user="$2" local path="$3" log "Dumping PostgreSQL db for $c..." docker exec -t "$c" pg_dumpall --clean --if-exists --username="$user" --file="$path" || { log "Error dumping PostgreSQL"; exit 1; } } dump_mariadb_db() { local c="$1" local user="$2" local pass="$3" local db="$4" local path="$5" log "Dumping MariaDB/MySQL db..." docker exec "$c" mariadb-dump --single-transaction -h localhost -u "$user" -p"$pass" "$db" > "$path" || { log "Error dumping MariaDB/MySQL"; exit 1; } } dump_sqlite_db() { local src="$1" local dst="$2" log "Dumping SQLite db..." sqlite3 "$src" ".backup $dst" || { log "Error dumping SQLite"; exit 1; } } run_duplicati_backup() { local dest="$1" local name="$2" local versions="$3" local sftp_user="$4" local sftp_pass="$5" local fingerprint="$6" local passphrase="$7" shift 7 local sources=("$@") log "Running duplicati backup for $name..." docker exec duplicati duplicati-cli backup "ssh://$dest" "${sources[@]}" \ --backup-name="$name backup" \ --keep-versions="$versions" \ --auth-username="$sftp_user" \ --auth-password="$sftp_pass" \ --passphrase="$passphrase" \ --ssh-fingerprint="$fingerprint" \ --prefix="$name" || { log "Error in duplicati backup for $name"; exit 1; } log "$name backup complete." } tar_and_encrypt() { local source_dir="$1" local output_file="$2" local passphrase="$3" log "Compressing and encrypting $source_dir..." sudo tar --absolute-names -czf - "$source_dir" | \ openssl enc -aes-256-cbc -pbkdf2 -pass "pass:$passphrase" > "$output_file" || { log "Error: Failed to create encrypted archive." exit 1 } } scp_transfer() { local local_file="$1" local ssh_user="$2" local ssh_host="$3" local ssh_key="$4" local ssh_port="$5" local remote_path="$6" log "Transferring $local_file to $ssh_user@$ssh_host:$remote_path" scp -P "$ssh_port" -i "$ssh_key" "$local_file" \ "$ssh_user@$ssh_host:$remote_path" || { log "Error: Failed to transfer file." exit 1 } } remove_old_backups() { local ssh_user="$1" local ssh_host="$2" local ssh_key="$3" local ssh_port="$4" local backup_folder="$5" local max_backups="$6" log "Removing old backups..." local existing_backups existing_backups=$(ssh -p "$ssh_port" -i "$ssh_key" "$ssh_user@$ssh_host" \ "ls -1 $backup_folder") || { log "Error: Failed to count existing backups." exit 1 } files_to_delete=$(echo "$existing_backups" | sort -t'-' -k2 | head -n -"$max_backups") if [[ -n "$files_to_delete" ]]; then for file in $files_to_delete; do ssh -p "$ssh_port" -i "$ssh_key" "$ssh_user@$ssh_host" \ "rm -f $backup_folder$file" done else echo "No files to delete" fi }