#!/bin/bash -e # Parse CLI and set options repoFile="$(dirname "$0")/repos" dryRun='' preventSleep='' suspend='' varDir=/var/lib/bup-backup-trigger triggerFile="$varDir/trigger" lockFile="$varDir/lock" log="/var/log/bup-sync" mkdir -p "$varDir" while [ $# -gt 0 ] do case "$1" in --repos|-r) repoFile="$2" shift ;; --dry|--dry-run|-d) dryRun=y ;; --lock) touch "$lockFile" exit 0 ;; --unlock) rm -f "$lockFile" exit 0 ;; --no-sleep) preventSleep=y ;; --suspend) suspend=y ;; --log) log="$2" shift ;; *) echo "Cannot understand parameter \"$1\". Aborting." >&2 exit 1 ;; esac shift done if [ "$log" != '-' ] then exec >> "$log" fi # Do some safety checks if [ ! -r "$repoFile" ] then echo "Cannot read the file $repoFile. Exiting" >&2 exit 1 fi # if [ -f "$lockFile" ] # then # echo "The lock file exists. Skipping for now ($(date))" # exit 0 # fi # Define the needed functions getNextDate() { python << EOF import datetime now = datetime.date.today() weekday = now.weekday() oneDay = datetime.timedelta(days=1) mondayThisWeek = now - oneDay * weekday mondayNextWeek = mondayThisWeek + oneDay * 7 dt = datetime.datetime.fromisoformat(mondayNextWeek.isoformat()) dt = dt.replace(hour=4, minute=45) print(int(dt.astimezone(datetime.timezone.utc).timestamp())) EOF } updateTriggerFile() { getNextDate > "$triggerFile" } triggerLiesInPast() { if [ ! -f "$triggerFile" ] then return 0 fi local now=$(date +%s) local triggered=$(cat "$triggerFile") if [ $now -gt "$triggered" ] then return 0 else return 1 fi } getNextStart() { date -d "@$(cat "$triggerFile")" "+%Y-%m-%d %H:%M" } goToSleep() { nextStart=$(getNextStart) echo "Going to sleep until $nextStart" rtcwake --mode disk --date "$nextStart" } if [ -n "$suspend" ] then if [ -f "$lockFile" -o -n "$preventSleep" ] then echo "Failed to go to sleep while lock file is present or sleep prevention given." exit 1 else goToSleep exit 0 fi fi if ! triggerLiesInPast then echo "The timestamp in the trigger event lies in the future. Waiting further." exit 0 fi echo "The backup script is triggered." date errored= while read line do echo "Processing line $line" if [ -n "$dryRun" ] then echo "Shipping to call script $line as in dry mode." else tmp=$(mktemp) $line 2> "$tmp" && echo "Done" || { echo "Command failed: $line" echo "Logs:" cat "$tmp" errored=y } rm -f "$tmp" fi done <<< $(cat "$repoFile" | grep -v '^#' | sed '/^\W*$/d') echo "All sync scripts have been run." date if [ -n "$errored" ] then echo "An error had happened. Aborting" exit 1 fi if [ -n "$dryRun" ] then echo "Not updating the trigger timestamp. The value would be $(getNextDate)." echo "Sleep mode entry is skipped as well." else updateTriggerFile if [ -n "$preventSleep" ] then echo "Not going to sleep as prevented by CLI argument" else if [ -f "$lockFile" ] then echo "Skipping sleeping due to lock file existence." else goToSleep fi fi fi