#!/bin/bash # Script to automate Proxmox PVE node backups to a PBS machine. # # Author: Xavi LleĆ³ # Copyright (c) 2025 Verdnatura S.L. All rights reserved. # Version: 1.0.3 # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # A configuration file is required in the user's home directory who runs this command. # The file should be sourced using CONFIG_FILE before execution. # # Example of a configuration file: # # Default values # USER_API="root@pam!api" # USER="root@pam" # IP_PBS="192.168.1.250" # POOL="backup-pool" # BACKUP_ITEMS="etc-pve.pxar:/etc/pve,interfaces.pxar:/etc/network" # LOG_FILE="/var/log/proxmox-backup-node-pve.log" # KEY_FILE="mykeyfile.key" #In case you want encrypted backups # PBS_PASSWORD='mypass or api token' # PBS_FINGERPRINT='b0:69:24:75:f0:92:a2:72:37:7c:c1:cb:0d:ba:8e:14:EE:XX:AA:MM:PP:LL:EE:e4:2b:07:02:18:86:9a:df:45' # # If you prefer to use switches in a one-liner, refer to the help section (--help) for available options. # Remember to add the port after the IP address when using an API user for authentication. # Example: IP_PBS="192.168.1.250:8007" CONFIG_FILE="$HOME/.backup_config.conf" # https://pbs.proxmox.com/docs/backup-client.html#environment-variables export PBS_PASSWORD export PBS_FINGERPRINT if [ -f "$CONFIG_FILE" ]; then source "$CONFIG_FILE" else echo "Error: Configuration file not found at $CONFIG_FILE" exit 1 fi show_help() { echo "Usage: $0 [options]" echo echo "Options:" echo " --standard Perform a standard backup." echo " --encrypt Perform an encrypted backup (requires a key file)." echo " --ip Repository IP address (overrides configuration)." echo " --pool Name of the backup pool (overrides configuration)." echo " --items List of backup items in 'name1:source1,name2:source2' format." echo " --user-api Specify user API credentials for backup." echo " --user Specify user credentials for backup." echo " --help Show this help." exit 0 } exit_from_repo() { proxmox-backup-client logout --repository "$REPOSITORY" 2>>"$LOG_FILE" && echo "$(date '+%Y-%m-%d %H:%M:%S') - Logged out from repository $REPOSITORY" | tee -a "$LOG_FILE" } # Check if PBS_PASSWORD and PBS_FINGERPRINT are set if [ -z "$PBS_PASSWORD" ] || [ -z "$PBS_FINGERPRINT" ]; then echo "Error: PBS_PASSWORD or PBS_FINGERPRINT is not set." exit 1 fi while [[ $# -gt 0 ]]; do case "$1" in --standard) MODE="standard" ;; --encrypt) MODE="encrypt" ;; --ip) IP_PBS="$2" shift ;; --pool) POOL="$2" shift ;; --items) BACKUP_ITEMS="$2" shift ;; --user-api) USER_API="$2" shift ;; --user) USER="$2" shift ;; --help) show_help ;; *) echo "Error: Unrecognized option '$1'" show_help ;; esac shift done if [ -z "$MODE" ]; then echo "You must specify --standard or --encrypt." show_help fi if [ -n "$USER_API" ]; then REPOSITORY="$USER_API@$IP_PBS:$POOL" else REPOSITORY="$USER@$IP_PBS:$POOL" fi echo "$(date '+%Y-%m-%d %H:%M:%S') - Starting backup to repository $REPOSITORY" | tee -a "$LOG_FILE" for item in $(echo "$BACKUP_ITEMS" | tr ',' '\n'); do BACKUP_NAME=$(echo "$item" | cut -d':' -f1) TARGET_DIR=$(echo "$item" | cut -d':' -f2) if [ "$MODE" == "encrypt" ]; then if [ ! -f "$KEY_FILE" ]; then echo "The key file $KEY_FILE does not exist." | tee -a "$LOG_FILE" exit 1 fi proxmox-backup-client backup "$BACKUP_NAME:$TARGET_DIR" --repository "$REPOSITORY" --crypt-mode encrypt --keyfile "$KEY_FILE" --backup-type 'host' 2>>"$LOG_FILE" else proxmox-backup-client backup "$BACKUP_NAME:$TARGET_DIR" --repository "$REPOSITORY" --backup-type 'host' 2>>"$LOG_FILE" fi if [ $? -ne 0 ]; then echo "Backup failed for $BACKUP_NAME" | tee -a "$LOG_FILE" exit 1 fi sleep 5 done if [ $? -eq 0 ]; then exit_from_repo echo -e "$(date '+%Y-%m-%d %H:%M:%S') - Backup completed successfully. You can check the log at $LOG_FILE\n" | tee -a "$LOG_FILE" else exit_from_repo echo -e "$(date '+%Y-%m-%d %H:%M:%S') - Error during backup. You can check the log at $LOG_FILE\n" | tee -a "$LOG_FILE" exit 1 fi