Files
duplicati/Duplicati/Library/Modules/Builtin/run-script-example.sh
T
Kenneth Skovhede 39636c6364 Added post-backup script
This PR adds a new `--run-script-post-backup` option that allows running a script after the main backup operation has completed, but before locking, compacting and verification is done.

The use for this is intended for cases where you want to stop or pause some service, run a backup, and then resume the service. Prior to this PR you would need to wait for the entire backup operation to complete, but with the new option you can resume as soon as the source data is no longer needed.
2026-05-01 07:06:12 +02:00

242 lines
9.3 KiB
Bash
Executable File

#!/bin/bash
###############################################################################
# How to run scripts before or after backups
###############################################################################
# Duplicati is able to run scripts before and after backups. This
# functionality is available in the advanced options of any backup job (UI) or
# as option (CLI). The (advanced) options to run scripts are
# --run-script-before = <filename>
# --run-script-before-required = <filename>
# --run-script-timeout = <time>
# --run-script-after = <filename>
# --run-script-post-backup = <filename>
# --run-script-with-arguments = <boolean>
#
# --run-script-before-required = <filename>
# Duplicati will run the script before the backup job and wait for its
# completion for 60 seconds (default timeout value). The backup will only be
# run if the script completes with an allowed exit code (0, 2, or 4).
# A timeout or any other exit code will abort the backup.
# The following exit codes are supported:
#
# - 0: OK, run operation
# - 1: OK, don't run operation
# - 2: Warning, run operation
# - 3: Warning, don't run operation
# - 4: Error, run operation
# - 5: Error don't run operation
# - other: Error don't run operation
#
# --run-script-before = <filename>
# Duplicati will run the script before the backup job and waits for its
# completion for 60 seconds (default timeout value). After a timeout a
# warning is logged and the backup is started.
# Any other exit code than 0 will be logged as a warning.
#
# --run-script-timeout = <time>
# Specify a new value for the timeout. Default is 60s. Accepted values are
# e.g. 30s, 1m15s, 1h12m03s, and so on. To turn off the timeout set the value
# to 0. Duplicati will then wait endlessly for the script to finish.
#
# --run-script-after = <filename>
# Duplicati will run the script after the backup job and wait for its
# completion for 60 seconds (default timeout value). After a timeout a
# warning is logged.
# Any other exit code than 0 will be logged as a warning.
#
# --run-script-post-backup = <filename>
# Duplicati will run the script after the backup data has been written and
# source resources (like VSS snapshots) have been released, but before the
# remote verification is performed. This allows scripts to run at the earliest
# point where the backup is complete but verification has not yet started.
# This is useful for scenarios where you want to minimize the time that
# operations are suspended or paused. The script will wait for its completion
# for 60 seconds (default timeout value). After a timeout a warning is logged.
# Any other exit code than 0 will be logged as a warning.
#
# --run-script-with-arguments = <boolean>
# If set to true, the script path will be parsed as a command line, and the
# arguments will be passed to the script. If set to false (default),
# the script path will used as a single path.
# If you do not have spaces in your script path or arguments, simply enter
# it as a string:
# Example: --run-script-before="/path/to/script.sh arg1 arg2 --option=a"
# If you have spaces in the path or arguements, use double- or single-quotes
# around the elements that have spaces, similar to how you would do in a shell:
# Example: --run-script-before="\"/path to/script.sh\" \"arg1 \" arg2"
###############################################################################
# Changing options from within the script
###############################################################################
# Within a script, all Duplicati options are exposed as environment variables
# with the prefix "DUPLICATI__". Please notice that the dash (-) character is
# not allowed in environment variable keys, so it is replaced with underscore
# (_). For a list of available options, have a look at the output of
# "duplicati.commandline.exe help".
#
# For instance the current value of the option --encryption-module can be
# accessed in the script by
# ENCRYPTIONMODULE=$DUPLICATI__encryption_module
# All Duplicati options can be changed by the script by writing options to
# stdout (with echo or similar). Anything not starting with a double dash (--)
# will be ignored:
# echo "Hello! -- test, this line is ignored"
# echo "--new-option=\"This will be a setting\""
# Filters are supplied in the DUPLICATI__FILTER variable.
# The variable contains all filters supplied with --include and --exclude,
# combined into a single string, separated with colon (:).
# Filters set with --include will be prefixed with a plus (+),
# and filters set with --exclude will be prefixed with a minus (-).
#
# Example:
# --include=*.txt --exclude=[.*\.abc] --include=*
#
# Will be encoded as:
# DUPLICATI__FILTER=+*.txt:-[.*\.abc]:+*
#
# You can set the filters by writing --filter=<new filter> to stdout.
# You may want to append to the existing filter like this:
# echo "--filter=+*.123:%DUPLICATI__FILTER%:-*.xyz"
###############################################################################
# Special Environment Variables
###############################################################################
# DUPLICATI__EVENTNAME
# Eventname is BEFORE if invoked as --run-script-before, AFTER if
# invoked as --run-script-after, and POST-BACKUP if invoked as
# --run-script-post-backup. This value cannot be changed by writing
# it back!
# DUPLICATI__OPERATIONNAME
# Operation name can be any of the operations that Duplicati supports. For
# example it can be "Backup", "Cleanup", "Restore", or "DeleteAllButN".
# This value cannot be changed by writing it back!
# DUPLICATI__RESULTFILE
# If invoked as --run-script-after this will contain the name of the
# file where result data is placed. This value cannot be changed by
# writing it back!
# DUPLICATI__REMOTEURL
# This is the remote url for the target backend. This value can be changed by
# echoing --remoteurl = "new value".
# DUPLICATI__LOCALPATH
# This is the path to the folders being backed up or restored. This variable
# is empty operations other than backup or restore. The local path can
# contain : to separate multiple folders. This value can be changed by echoing
# --localpath = "new value".
# DUPLICATI__PARSED_RESULT
# This is a value indicating how well the operation was performed.
# It can take the values: Unknown, Success, Warning, Error, Fatal.
###############################################################################
# Example script
###############################################################################
# We read a few variables first.
EVENTNAME=$DUPLICATI__EVENTNAME
OPERATIONNAME=$DUPLICATI__OPERATIONNAME
REMOTEURL=$DUPLICATI__REMOTEURL
LOCALPATH=$DUPLICATI__LOCALPATH
# Basic setup, we use the same file for both before and after,
# so we need to figure out which event has happened
if [ "$EVENTNAME" == "BEFORE" ]
then
# If the operation is a backup starting,
# then we check if the --dblock-size option is unset
# or 50mb, and change it to 25mb, otherwise we
# leave it alone
if [ "$OPERATIONNAME" == "Backup" ]
then
if [ "$DUPLICATI__dblock_size" == "" ] || ["$DUPLICATI__dblock_size" == "50mb"]
then
# Write the option to stdout to change it
echo "--dblock-size=25mb"
else
# We write this to stderr, and it will show up as a warning in the logfile
echo "Not setting volumesize, it was already set to $DUPLICATI__dblock_size" >&2
fi
else
# This will be ignored
echo "Got operation \"OPERATIONNAME\", ignoring"
fi
elif [ "$EVENTNAME" == "POST-BACKUP" ]
then
# This event is triggered after the backup data has been written and
# source resources (like VSS snapshots) have been released, but before
# the remote verification is performed. This is the earliest point where
# you can safely resume operations that were suspended for the backup.
if [ "$OPERATIONNAME" == "Backup" ]
then
echo "Backup data written, resuming normal operations before verification"
# Add your post-backup logic here, e.g., resuming services
fi
elif [ "$EVENTNAME" == "AFTER" ]
then
# If this is a finished backup, we send an email
if [ "$OPERATIONNAME" == "Backup" ]
then
# Basic email setup
EMAIL="admin@example.com"
SUBJECT="Duplicati backup"
# We use a temp file to store the email body
MESSAGE="/tmp/duplicati-mail.txt"
echo "Duplicati finished a backup."> $MESSAGE
echo "This is the result :" >> $MESSAGE
echo "" >> $MESSAGE
# We append the result of the operation to the email
cat "$DUPLICATI__RESULTFILE" >> $MESSAGE
# If the log-file is enabled, we append it
if [ -f "$DUPLICATI__log_file" ]
then
echo "The log file looks like this: " >> $MESSAGE
cat "$DUPLICATI__log_file" >> $MESSAGE
fi
# If the backend-log-database file is enabled, we append that as well
if [ -f "$DUPLICATI__backend_log_database" ]
then
echo "The backend-log file looks like this: " >> $MESSAGE
cat "$DUPLICATI__backend_log_database" >> $MESSAGE
fi
# Finally send the email using /bin/mail
/bin/mail -s "$SUBJECT" "$EMAIL" < $MESSAGE
else
# This will be ignored
echo "Got operation \"OPERATIONNAME\", ignoring"
fi
else
# This should never happen, but there may be new operations
# in new version of Duplicati
# We write this to stderr, and it will show up as a warning in the logfile
echo "Got unknown event \"$EVENTNAME\", ignoring" >&2
fi
# We want the exit code to always report success.
# For scripts that can abort execution, use the option
# --run-script-before-required = <filename> when running Duplicati
exit 0