Plug & Backup sur Debian


On va décrire ici la mise en place d’un backup automatique avec Borg backup sur une debian sur disque amovible déclenché automatiquement et sans action utilisateur lorsque ce disque est branché sur un port USB de la machine.

Logo de Borg Backup

Toute la procédure est vient de la documentation de Borg Backup

Ajout d’une règle udev

On commence par créer le dossier de travail :

mkdir /etc/backups

On crée ensuite un fichier qui contient la règle udev :

touch /etc/backups/40-backup.rules

Avec le contenu suivant :

ACTION=="add", SUBSYSTEM=="bdi", DEVPATH=="/devices/virtual/bdi/*",
TAG+="systemd", ENV{SYSTEMD_WANTS}="automatic-backup.service"

Ajout d’un service systemd

On ajoute ensuite un service systemd qui sera lancé par la règle ci-dessus :

touch /etc/backups/automatic-backup.service

qui contient:

[Service]
Type=oneshot
ExecStart=/etc/backups/run.sh

Le script de backup

Dernier élément à mettre en place, le script de backup, ici celui qui est proposé dans la documentation de Borg Backup, à adapter à ses besoins :

#!/bin/bash -ue

# The udev rule is not terribly accurate and may trigger our service before
# the kernel has finished probing partitions. Sleep for a bit to ensure
# the kernel is done.
#
# This can be avoided by using a more precise udev rule, e.g. matching
# a specific hardware path and partition.
sleep 5

#
# Script configuration
#

# The backup partition is mounted there
MOUNTPOINT=/mnt/backup

# This is the location of the Borg repository
TARGET=$MOUNTPOINT/borg-backups/backup.borg

# Archive name schema
DATE=$(date --iso-8601)-$(hostname)

# This is the file that will later contain UUIDs of registered backup drives
DISKS=/etc/backups/backup.disks

# Find whether the connected block device is a backup drive
for uuid in $(lsblk --noheadings --list --output uuid)
do
        if grep --quiet --fixed-strings $uuid $DISKS; then
                break
        fi
        uuid=
done

if [ ! $uuid ]; then
        echo "No backup disk found, exiting"
        exit 0
fi

echo "Disk $uuid is a backup disk"
partition_path=/dev/disk/by-uuid/$uuid
# Mount file system if not already done. This assumes that if something is already
# mounted at $MOUNTPOINT, it is the backup drive. It won't find the drive if
# it was mounted somewhere else.
(mount | grep $MOUNTPOINT) || mount $partition_path $MOUNTPOINT
drive=$(lsblk --inverse --noheadings --list --paths --output name $partition_path | head --lines 1)
echo "Drive path: $drive"

#
# Create backups
#

# Options for borg create
BORG_OPTS="--stats --one-file-system --compression lz4 --checkpoint-interval 86400"

# Set BORG_PASSPHRASE or BORG_PASSCOMMAND somewhere around here, using export,
# if encryption is used.

# No one can answer if Borg asks these questions, it is better to just fail quickly
# instead of hanging.
export BORG_RELOCATED_REPO_ACCESS_IS_OK=no
export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=no

# Log Borg version
borg --version

echo "Starting backup for $DATE"

# This is just an example, change it however you see fit
borg create $BORG_OPTS \
  --exclude root/.cache \
  --exclude var/lib/docker/devicemapper \
  $TARGET::$DATE-$$-system \
  / /boot

# /home is often a separate partition / file system.
# Even if it isn't (add --exclude /home above), it probably makes sense
# to have /home in a separate archive.
borg create $BORG_OPTS \
  --exclude 'sh:home/*/.cache' \
  $TARGET::$DATE-$$-home \
  /home/

echo "Completed backup for $DATE"

# Just to be completely paranoid
sync

if [ -f /etc/backups/autoeject ]; then
        umount $MOUNTPOINT
        hdparm -Y $drive
fi

if [ -f /etc/backups/backup-suspend ]; then
        systemctl suspend
fi

Comme on le voit à la fin de ce script, la présence d’un fichier autoeject éjectera le disque dès que le backup est terminé, tandis que la présence d’un ficher backup-suspend passera la machine en veille lorsque le backup s’achève.

Activation de l’ensemble

On active la règle udev et le nouveau service :

ln -s /etc/backups/40-backup.rules /etc/udev/rules.d/40-backup.rules
ln -s /etc/backups/automatic-backup.service /etc/systemd/system/automatic-backup.service
systemctl daemon-reload
udevadm control --reload

Ajout d’un disque de backup

Pour ajouter un disque à tout ce dispositif il est nécéssaire de renseigner son UUID dans /etc/backup/backup.disks grâce à :

lsblk -o+uuid,label

Initialiser le backup Borg (utiliser le contenu des variables MOUNTPOINT et TARGET du script):

borg init --encryption ... /mnt/backup/borg-backups/backup.borg

Il ne reste plus qu’à tester en vérifiant les logs :

journalctl -fu automatic-backup [-n number-of-lines]