Command Hook Examples

Introduction

Command hooks are a powerful way to extend Backrest's capabilities. They allow you to run arbitrary shell commands in response to lifecycle events. This doc shows examples of command hooks.

Command Hook Options

When run on CONDITION_SNAPSHOT_START command hooks have the ability to send control signals to Backrest based on the exit status of the script. The handling of the exit status is configured by the Error Behavior field. The following options are available:

  • ON_ERROR_CANCEL - If the script exits with a non-zero status, the backup operation will be canceled.
  • ON_ERROR_FATAL - If the script exits with a non-zero status, it is treated as a backup failure and error notifications are triggered.
  • ON_ERROR_IGNORE - If the script exits with a non-zero status, the backup operation will continue and the error will be ignored.

Examples

Notify a healthcheck service

Ping a healthcheck service (e.g. https://healthchecks.io/ in the example) to notify it of backup status (or failure) using a command hook.

Note that this hook example takes advantage of the fact that the hook is a golang template to render different commands based on whether an error occurred.

Condition CONDITION_SNAPSHOT_END

Script

#!/bin/bash
{{ if .Error -}}
curl -fsS --retry 3 https://hc-ping.com/your-uuid/fail
{{ else -}}
curl -fsS --retry 3 https://hc-ping.com/your-uuid
{{ end -}}

Error Behavior: ON_ERROR_IGNORE

(MacOS) Show system notification

Show a system notification using the osascript command on MacOS.

Condition CONDITION_SNAPSHOT_END, CONDITION_PRUNE_ERROR, CONDITION_CHECK_ERROR

Script

#!/bin/bash
{{ if .Error -}}
osascript -e 'display notification "{{ .ShellEscape .Task }} failed" with title "Backrest"'
{{ else -}}
osascript -e 'display notification "{{ .ShellEscape .Task }} succeeded" with title "Backrest"'
{{ end -}}

Check for internet connectivity

Add a hook to check for internet connectivity before running a backup.

Condition CONDITION_SNAPSHOT_START

Script

#!/bin/bash
if ping -q -c 1 -W 1 google.com >/dev/null; then
  echo "Internet connection is up"
  exit 0
else
  echo "Internet connection is down"
  exit 1
fi

Error Behavior: ON_ERROR_CANCEL

Check that a target directory exists

Add a hook to check that a target directory exists before running a backup.

Condition CONDITION_SNAPSHOT_START

Script

#!/bin/bash
if [ -d /path/to/backup ]; then
  echo "Backup directory exists"
  exit 0
else
  echo "Backup directory does not exist"
  exit 1
fi

Error Behavior: ON_ERROR_CANCEL

Create a BTRFS filesystem snapshot before running a backup

Add a hook that creates a btrfs snapshot prior to each backup (overwriting any prior snapshot). This is useful for creating a point in time consistent copy of the filesystem for restic to read from. It eliminates the possibility of inconsistency due to the time it takes restic to scan your files during a backup.

Condition CONDITION_SNAPSHOT_START

Script

#!/bin/bash
btrfs subvolume snapshot -r /your-btrfs-filesystem /your-btrfs-filesystem/.backrest-snapshot

Error Behavior: ON_ERROR_FATAL (if the snapshot fails, the backup should fail)

Note: you may also add a hook to delete the snapshot after the backup is complete e.g.

Condition CONDITION_SNAPSHOT_END

Script

#!/bin/bash
btrfs subvolume delete /your-btrfs-filesystem/.backrest-snapshot

Error Behavior: ON_ERROR_IGNORE (even if the snapshot deletion fails, the backup was already successful)

Check that the battery is above a certain level

Add a hook to check that the battery is above a certain level before running a backup.

Condition CONDITION_SNAPSHOT_START

Script

#!/bin/bash
if [ $(cat /sys/class/power_supply/BAT0/capacity) -gt 80 ]; then
  echo "Battery level is above 20%"
  exit 0
else
  echo "Battery level is below 20%"
  exit 1
fi

Error Behavior: ON_ERROR_CANCEL

Windows PowerShell examples

GUI message box on error condition

The message box stays on screen until acknowledged by the user. Use the same script for both backup plan and repo settings to catch errors.

Condition CONDITION_ANY_ERROR

Script

Add-Type -AssemblyName System.Windows.Forms
# This option puts message box on top of all windows.
$options = [System.Windows.Forms.MessageBoxOptions]::ServiceNotification
$defbutton = [System.Windows.Forms.MessageBoxDefaultButton]::Button1
$buttons = [System.Windows.Forms.MessageBoxButtons]::OK
$icon = [System.Windows.Forms.MessageBoxIcon]::Error
$title = "Backrest"
$message = '{{ .Summary }}'
[System.Windows.Forms.MessageBox]::Show($message, $title, $buttons, $icon, $defbutton, $options)

# Include this comment and the line above it. See https://github.com/garethgeorge/backrest/issues/400

GUI toast warning notification

Toast or app notifications appear for a short time before disappearing without user acknowledgement.

Condition CONDITION_SNAPSHOT_WARNING

Script

Add-Type -AssemblyName System.Windows.Forms
$balloon = New-Object System.Windows.Forms.NotifyIcon
$balloon.Icon = [System.Drawing.SystemIcons]::Warning
$balloon.BalloonTipIcon = [System.Windows.Forms.ToolTipIcon]::Warning
$balloon.BalloonTipText = '{{ .Summary }}'
$balloon.BalloonTipTitle = "Backrest"
$balloon.Visible = $true
$balloon.ShowBalloonTip(5000)
Start-Sleep -Seconds(5)
$balloon.Visible = $false
$balloon.Icon.Dispose()
$balloon.Dispose()

# Include this comment and the line above it. See https://github.com/garethgeorge/backrest/issues/400

GUI toast information notification

Condition CONDITION_SNAPSHOT_SUCCESS

Script

Add-Type -AssemblyName System.Windows.Forms
$balloon = New-Object System.Windows.Forms.NotifyIcon
$balloon.Icon = [System.Drawing.SystemIcons]::Information
$balloon.BalloonTipIcon = [System.Windows.Forms.ToolTipIcon]::Information
$balloon.BalloonTipText = '{{ .Summary }}'
$balloon.BalloonTipTitle = "Backrest"
$balloon.Visible = $true
$balloon.ShowBalloonTip(5000)
Start-Sleep -Seconds(5)
$balloon.Visible = $false
$balloon.Icon.Dispose()
$balloon.Dispose()

# Include this comment and the line above it. See https://github.com/garethgeorge/backrest/issues/400