2022-02-03 14:33:08 +01:00
|
|
|
|
#!/bin/sh
|
|
|
|
|
#
|
|
|
|
|
# Purpose {{{
|
|
|
|
|
# This script will hardlink latest Proxmox's backup with a explicit name.
|
|
|
|
|
#
|
|
|
|
|
# This script is intended to be used as a hook script for the Proxmox
|
|
|
|
|
# VZDump utility.
|
|
|
|
|
#
|
|
|
|
|
# In order to use it, use the configuration directive "script" of the
|
|
|
|
|
# vzdump utility. This can be done for scheduled backups by putting
|
|
|
|
|
# "script: /path/to/this/script" in /etc/vzdump.conf. Don't forget to
|
|
|
|
|
# set executable permission for the script file.
|
|
|
|
|
#
|
|
|
|
|
# Based on RobHost's vzdump_hook script :
|
|
|
|
|
# https://github.com/robhost/proxmox-scripts/blob/master/vzdump_hook.sh
|
|
|
|
|
# }}}
|
|
|
|
|
# Vars {{{
|
|
|
|
|
readonly PROGNAME=$(basename "${0}")
|
|
|
|
|
readonly ARGS="${*}"
|
|
|
|
|
[ -z "${DEBUG}" ] && DEBUG=0
|
|
|
|
|
## Export DEBUG for sub-script
|
|
|
|
|
export DEBUG
|
|
|
|
|
|
|
|
|
|
## Colors
|
|
|
|
|
readonly PURPLE='\033[1;35m'
|
|
|
|
|
readonly RED='\033[0;31m'
|
|
|
|
|
readonly RESET='\033[0m'
|
|
|
|
|
readonly COLOR_DEBUG="${PURPLE}"
|
|
|
|
|
# }}}
|
|
|
|
|
usage() { # {{{
|
|
|
|
|
|
|
|
|
|
cat <<- HELP
|
|
|
|
|
usage: ${PROGNAME} [-h]
|
|
|
|
|
|
|
|
|
|
Hardlink latest Proxmox's backup with a explicit name.
|
|
|
|
|
|
|
|
|
|
OPTIONS :
|
|
|
|
|
-h,--help
|
|
|
|
|
Print this help message.
|
|
|
|
|
HELP
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
# }}}
|
|
|
|
|
debug_message() { # {{{
|
|
|
|
|
|
|
|
|
|
local_debug_message="${1}"
|
2022-02-08 11:47:28 +01:00
|
|
|
|
local_temp_log="/tmp/pve.log"
|
|
|
|
|
|
|
|
|
|
if [ ! -f "${local_temp_log}" ]; then
|
|
|
|
|
true > "${local_temp_log}"
|
|
|
|
|
fi
|
2022-02-03 14:33:08 +01:00
|
|
|
|
|
|
|
|
|
## Print message if DEBUG is enable (=0)
|
2022-02-08 11:47:28 +01:00
|
|
|
|
[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6b\e[m\n' "DEBUG − ${PROGNAME} : ${local_debug_message}" >> "${local_temp_log}"
|
2022-02-03 14:33:08 +01:00
|
|
|
|
|
|
|
|
|
unset local_debug_message
|
|
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
# }}}
|
|
|
|
|
error_message() { # {{{
|
|
|
|
|
|
|
|
|
|
local_error_message="${1}"
|
|
|
|
|
local_error_code="${2}"
|
|
|
|
|
|
|
|
|
|
## Print message
|
|
|
|
|
printf '%b\n' "ERROR − ${PROGNAME} : ${RED}${local_error_message}${RESET}"
|
|
|
|
|
|
|
|
|
|
exit "${local_error_code:=66}"
|
|
|
|
|
}
|
|
|
|
|
# }}}
|
|
|
|
|
|
|
|
|
|
main() { # {{{
|
|
|
|
|
|
2022-02-07 15:07:53 +01:00
|
|
|
|
debug_message "main − \
|
|
|
|
|
ARGS=${ARGS}
|
|
|
|
|
env=$(env)"
|
|
|
|
|
|
2022-02-03 14:33:08 +01:00
|
|
|
|
# If backup is complete {{{
|
|
|
|
|
if [ "${phase}" = "backup-end" ]; then
|
|
|
|
|
## Get TARGET's file extension
|
2022-02-07 14:56:21 +01:00
|
|
|
|
target_archive_extension="$(printf '%s' "${TARGET}" | sed -n "s/.*\.\([[:alnum:]]*\.[[:alnum:]]*\)$/\1/p")"
|
2022-02-03 14:33:08 +01:00
|
|
|
|
## Set path for LATEST archive file
|
|
|
|
|
latest_archive="${dumpdir}/vzdump-${vmtype}-${vmid}-latest.${target_archive_extension}"
|
2022-02-08 11:47:28 +01:00
|
|
|
|
debug_message "backup-end − \
|
|
|
|
|
target_archive_extension=${target_archive_extension}
|
|
|
|
|
latest_archive=${latest_archive}"
|
2022-02-03 14:33:08 +01:00
|
|
|
|
|
|
|
|
|
## hardlink TARGET archive to LATEST
|
|
|
|
|
debug_message "hardlink TARGET archive (${target_archive}) to \
|
2022-02-07 15:07:53 +01:00
|
|
|
|
LATEST (${latest_archive})."
|
2022-02-03 14:33:08 +01:00
|
|
|
|
ln --force "${target_archive}" "${latest_archive}"
|
|
|
|
|
fi
|
|
|
|
|
# }}}
|
|
|
|
|
|
|
|
|
|
# If log is complete {{{
|
|
|
|
|
if [ "${phase}" = "log-end" ]; then
|
|
|
|
|
## Set path for LATEST log file
|
|
|
|
|
latest_log="${dumpdir}/vzdump-${vmtype}-${vmid}-latest.log"
|
2022-02-08 11:47:28 +01:00
|
|
|
|
debug_message "log-end − \
|
|
|
|
|
latest_log=${latest_log}"
|
2022-02-03 14:33:08 +01:00
|
|
|
|
|
|
|
|
|
## hardlink TARGET log to LATEST
|
|
|
|
|
debug_message "hardlink TARGET logs (${logfile}) to \
|
2022-02-07 15:07:53 +01:00
|
|
|
|
LATEST (${latest_log})."
|
2022-02-03 14:33:08 +01:00
|
|
|
|
ln --force "${logfile}" "${latest_log}"
|
|
|
|
|
fi
|
|
|
|
|
# }}}
|
|
|
|
|
|
2022-02-07 15:07:53 +01:00
|
|
|
|
debug_message "---"
|
2022-02-03 14:33:08 +01:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
# }}}
|
|
|
|
|
|
|
|
|
|
# Manage arguments # {{{
|
|
|
|
|
# This code can't be in a function due to argument management
|
|
|
|
|
|
|
|
|
|
phase="${1}" # (job|backup)-(start|end|abort)|log-end|pre-(stop|restart)|post-restart
|
|
|
|
|
|
|
|
|
|
case "${phase}" in
|
|
|
|
|
# set variables for the phases
|
|
|
|
|
#backup-start|backup-end|backup-abort|log-end|pre-stop|pre-restart|post-restart)
|
|
|
|
|
#;;
|
|
|
|
|
# do work
|
2022-03-24 09:53:29 +01:00
|
|
|
|
job-init|job-start|job-end|job-abort)
|
2022-02-03 14:33:08 +01:00
|
|
|
|
# Available vars {{{
|
|
|
|
|
# Arguments : job-start
|
|
|
|
|
#LVM_SUPPRESS_FD_WARNINGS=1
|
|
|
|
|
#DUMPDIR=/path/to/backup/dump
|
|
|
|
|
#STOREID=backup.id.from.storage.cfg
|
|
|
|
|
# }}}
|
|
|
|
|
;;
|
|
|
|
|
backup-start|backup-end|backup-abort)
|
|
|
|
|
# Available vars {{{
|
|
|
|
|
#ARGS=backup-start stop vm.id
|
|
|
|
|
#HOSTNAME=hostname.domain.tld
|
|
|
|
|
#TARGET=/path/to/backup/dump/vzdump-$VMTYPE_VALUE-$2_VALUE-YYYY_MM_DD-hh-mm-ss.tar.zst
|
|
|
|
|
#LOGFILE=/path/to/backup/dump/vzdump-$VMTYPE_VALUE-$2_VALUE-YYYY_MM_DD-hh-mm-ss.log
|
|
|
|
|
#LVM_SUPPRESS_FD_WARNINGS=1
|
|
|
|
|
#DUMPDIR=/path/to/backup/dump
|
|
|
|
|
#VMTYPE=lxc|qemu
|
|
|
|
|
#STOREID=backup.id.from.storage.cfg
|
|
|
|
|
# }}}
|
|
|
|
|
vmid="${3}"
|
|
|
|
|
target_archive="${TARGET}"
|
|
|
|
|
dumpdir="${DUMPDIR}"
|
|
|
|
|
vmtype="${VMTYPE}"
|
|
|
|
|
;;
|
|
|
|
|
log-end)
|
|
|
|
|
# Available vars {{{
|
|
|
|
|
#ARGS=log-end stop vm.id
|
|
|
|
|
#HOSTNAME=hostname.domain.tld
|
|
|
|
|
#TARGET=/path/to/backup/dump/vzdump-$VMTYPE_VALUE-$2_VALUE-YYYY_MM_DD-hh-mm-ss.tar.zst
|
|
|
|
|
#LOGFILE=/path/to/backup/dump/vzdump-$VMTYPE_VALUE-$2_VALUE-YYYY_MM_DD-hh-mm-ss.log
|
|
|
|
|
#LVM_SUPPRESS_FD_WARNINGS=1
|
|
|
|
|
#DUMPDIR=/path/to/backup/dump
|
|
|
|
|
#VMTYPE=lxc|qemu
|
|
|
|
|
#STOREID=backup.id.from.storage.cfg
|
|
|
|
|
# }}}
|
|
|
|
|
vmid="${3}"
|
|
|
|
|
logfile="${LOGFILE}"
|
|
|
|
|
dumpdir="${DUMPDIR}"
|
|
|
|
|
vmtype="${VMTYPE}"
|
|
|
|
|
;;
|
|
|
|
|
pre-stop)
|
|
|
|
|
;;
|
|
|
|
|
pre-restart)
|
|
|
|
|
;;
|
|
|
|
|
post-restart)
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
error_message "Unknown phase ${phase}." 1
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
|
|
|
|
|
# }}}
|
|
|
|
|
|
|
|
|
|
main
|
|
|
|
|
|
|
|
|
|
exit 0
|