scripts/proxmox/backup.pve.content.sh

228 lines
5.8 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/sh
# This script will backup /etc/pve content :
# 1. Make an archive to a first directory (default: /etc/proxmox.pve/backup/).
# 2. Hard link a fix archive name (pve.latest.tar.gz) to new archive
# Easy to monitor (this path can be expected).
# 3. Clean backups older than retention time (default: 7).
# This script can be call by a cronjob (eg. daily).
# Vars {{{
readonly PROGNAME=$(basename "${0}")
readonly PROGDIR=$(readlink -m $(dirname "${0}"))
readonly ARGS="${*}"
readonly NBARGS="${#}"
[ -z "${DEBUG}" ] && DEBUG=1
readonly DEFAULT_LOCAL_BKP_DIR="/etc/proxmox.pve/backup"
readonly TODAY_VAR=$(date +%Y%m%d)
readonly DEFAULT_RETENTION_TIME="7"
## Colors
readonly PURPLE='\033[1;35m'
readonly RED='\033[0;31m'
readonly RESET='\033[0m'
readonly COLOR_DEBUG="${PURPLE}"
# }}}
usage() { # {{{
cat <<- EOF
usage: $PROGNAME [-d|-h|-l|-r]
Backup /etc/pve content
EXAMPLES:
- Backup /etc/pve content to ${DEFAULT_LOCAL_BKP_DIR} directory
${PROGNAME}
- Backup /etc/pve content to /var/backups/pve directory
${PROGNAME} --local /var/backups/pve
- Backup to default path and keep backups for 14 days
${PROGNAME} --retention 14
OPTIONS:
-d,--debug
Enable debug messages.
-h,--help
Print this help message.
-l,--local
Path to a local directory to store backup and override
default path (${DEFAULT_LOCAL_BKP_DIR}).
-r,--retention,--retention-time
Backups older than retention time (default: ${DEFAULT_RETENTION_TIME})
will be delete.
EOF
}
# }}}
debug_message() { # {{{
local_message="${1}"
## Print message if DEBUG is enable (=0)
[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6b\e[m\n' "DEBUG ${PROGNAME}: ${local_message}"
return 0
}
# }}}
define_vars() { # {{{
## If local_bkp_dir wasn't defined {{{
if [ -z "${local_bkp_dir}" ]; then
## Use default path to store backup
local_bkp_dir="${DEFAULT_LOCAL_BKP_DIR}"
fi
## }}}
## If retention_time wasn't defined {{{
if [ -z "${retention_time}" ]; then
## Use default retention time to clean backups
retention_time="${DEFAULT_RETENTION_TIME}"
fi
## }}}
}
# }}}
is_directory_absent() { # {{{
local_directory_absent="${1}"
## Directory exists by default
return_is_directory_absent="1"
### Check if the directory exists
# shellcheck disable=SC2086
if test -d "${local_directory_absent}"; then
return_is_directory_absent="1"
debug_message "is_directory_absent \
The directory ${RED}${local_directory_absent}${COLOR_DEBUG} exists."
else
return_is_directory_absent="0"
debug_message "is_directory_absent \
The directory ${RED}${local_directory_absent}${COLOR_DEBUG} doesn't exist."
fi
return "${return_is_directory_absent}"
}
# }}}
main() { # {{{
## Define all vars
define_vars
## Verify if /etc/pve directory is absent {{{
### Display an explicit error message
### AND exit with error code 1
is_directory_absent /etc/pve \
&& printf '%b\n' "${RED}/etc/pve directory doesn't seems available. Are you sure you run this script on a Proxmox host?${RESET}" \
&& exit 1
## }}}
## Verify if the local destination directory is absent {{{
### AND create it
is_directory_absent "${local_bkp_dir}" \
&& mkdir -p -- ${local_bkp_dir}
## }}}
## Create an archive of /etc/pve to $local_bkp_dir {{{
### OR exit with error code 2 if it fails
tar czf "${local_bkp_dir}/pve.${TODAY_VAR}.tar.gz" -C /etc/ pve/ \
|| exit 2
## }}}
## Create an hard link to pve.latest.tar.gz {{{
### OR exit with error code 3 if it fails
ln --force -- "${local_bkp_dir}/pve.${TODAY_VAR}.tar.gz" "${local_bkp_dir}/pve.latest.tar.gz" \
|| exit 3
## }}}
## Fix backups permissions {{{
### Only readable by backup (user) and adm (group)
chown -R backup:adm -- "${local_bkp_dir}" \
&& chmod 'u+rwX,g+rX,o-rwx' -R -- "${local_bkp_dir}"
## }}}
## Clean files older than $retention_time {{{
### OR exit with error code 4 if it fails
find "${local_bkp_dir}" -maxdepth 1 -type f -mtime +"${retention_time}" -iname "pve.*.tar.gz" -delete \
|| exit 4
## }}}
}
# }}}
# Manage arguments # {{{
# This code can't be in a function due to argument management
if [ ! "${NBARGS}" -eq "0" ]; then
manage_arg="0"
## If the first argument is not an option
if ! printf -- '%s' "${1}" | grep -q -E -- "^-+";
then
## Print help message and exit
printf '%b\n' "${RED}Invalid option: ${1}${RESET}"
printf '%b\n' "---"
usage
exit 1
fi
# Parse all options (start with a "-") one by one
while printf -- '%s' "${1}" | grep -q -E -- "^-+"; do
case "${1}" in
-d|--debug ) ## debug
DEBUG=0
;;
-h|--help ) ## help
usage
## Exit after help informations
exit 0
;;
-l|--local ) ## local directory to store backup
## Move to the next argument
shift
## Define local_bkp_dir
local_bkp_dir="${1}"
;;
-r|--retention,--retention-time ) ## clean backups older than retention time
## Move to the next argument
shift
## Define retention_time
retention_time="${1}"
;;
* ) ## unknow option
printf '%b\n' "${RED}Invalid option: ${1}${RESET}"
printf '%b\n' "---"
usage
exit 1
;;
esac
debug_message "Arguments management \
${RED}${1}${COLOR_DEBUG} option managed."
## Move to the next argument
shift
manage_arg=$((manage_arg+1))
done
debug_message "Arguments management \
${RED}${manage_arg}${COLOR_DEBUG} argument(s) successfully managed."
else
debug_message "Arguments management \
No arguments/options to manage."
fi
# }}}
main
exit 255