Bup est un système de sauvegarde construit au dessus de git. Il permet donc très simplement de parcourir l'historique des sauvegardes.

Il découpe les fichiers sauvegardés en de multiples fragments, pour profiter du fonctionnement de git : Chaque fragment n'est stocké qu'une seule fois.

Mise à jour 09/01/2018 : Ajout des paragraphes Sauvegarde d'un répertoire, Parcours des données sauvegardées et Restauration d'un répertoire.

Installation

Sous Debian, il suffit d'installer le paquet bup.

$ sudo apt-get install --no-install-recommends bup

Utilisation

La possibilité de sauvegarder un répertoire ne stocke pas encore les méta-donnée. Je n'utilise donc que la sauvegarde de fichier simple pour le moment.

Il est possible de sauvegarder un fichier unique, ou un répertoire. Les méta-données sont maintenant correctement sauvegardées et restaurées lors de l'utilisation sur un répertoire, il est donc possible d'utiliser cette fonctionnalité sans problème.

Emplacement des sauvegardes

Par défaut, bup utilise le répertoire ~/.bup pour effectuer les sauvegardes. Il est possible d'utiliser un autre répertoire en le précisant dans le paramètre --bup-dir.

$ bup --bup-dir=<Path> <command>

Pour éviter d'avoir à répéter ce paramètre à chaque commande, il est possible de définir la variable d'environnement BUP_DIR.

$ export BUP_DIR=<Path>
$ bup <command>

Initialisation

L'initialisation d'un dépôt de sauvegarde bup se fait simplement par l'appel à la commande init. Pour un dépôt local, cette commande ne prend aucun paramètre.

$ bup init

Pour initialiser un dépôt distant, il faut donner le nom d'hôte et le chemin au paramètre -r.

$ bup init -r <hostname>:[<path>]

Note : Pour que ceci fonctionne, il est nécessaire que bup soit installé sur la machine distante.

Note : Un dépôt local est initialisé automatiquement lors de l'initialisation d'un dépôt distant.

Note : Si le chemin distant n'est pas spécifié, bup utilisera le chemin par défaut, ~/.bup, sur la machine distante.

Sauvegarde d'un fichier

La sauvegarde d'un fichier d'archive se fait avec la commande split. Cette commande prend le nom de la sauvegarde dans le paramètre -n. Le nom de la sauvegarde correspond à un nom de branche qui sera utilisé dans le dépôt git.

Il est possible de donner un nom de fichier à sauvegarder, ou de sauvegarder la sortie d'une commande d'archivage directement.

Quelques exemples :

$ bup split -n <SaveName> <Filename>
$ tar Pcf - <PathToSave> | bup split -n <SaveName>
$ pg_dump -Ft <DbName> | bup split -n <SaveName>

Note : Pour une base de données PostgreSQL, je conseille d'utiliser le format tar (paramètre -Ft dans l'exemple), qui permet de filtrer les éléments avec l'utilitaire pg_restore lors de la restauration. Ce format est plus adapté que le format custom (paramètre -Fc) pour une sauvegarde bup, puisqu'il permet une déduplication plus efficace.

Sauvegarde d'un répertoire

La sauvegarde d'un répertoire d'archive se fait avec les commandes index et save.

Indexation du contenu

La commande index a plusieurs rôles :

  • Indexer le contenu d'un répertoire, afin de détecter lister les modifications à sauvegarder.
  • Afficher le contenu de cet index.

Lors de l'indexation du contenu d'un répertoire, il est possible d'exclure certains chemins :

  • --one-file-system, abrégé en --xdev ou -x : Ne parcourir que le point de montage du répertoire demandé.
  • --exclude : Exclure un chemin précis.
  • --exclude-from : Exclure tous les chemins contenus dans un fichier, un chemin par ligne.
  • --exclude-rx : Exclure des chemins, selon une expression régulière.
  • --exclude-rx-from : Exclure tous les chemins contenus dans un fichier, une expression régulière par ligne.

L'affichage peut être restreint aux seuls fichiers modifiés, au moyen du paramètre --modified (abrégé en -m). Il est aussi possible de préfixer l'affichage par un caractère montrant l'état de chaque fichier (A = Ajouté, M = Modifié, D = Supprimé, = Aucun changement).

Sauvegarde du contenu

La commande save prend le nom de la sauvegarde dans le paramètre -n. Le nom de la sauvegarde correspond à un nom de branche qui sera utilisé dans le dépôt git.

Les répertoires sauvegardés ne doivent pas forcément correspondre aux répertoires indexés. Ainsi, il est possible de n'indexer que certains répertoires, mais de lancer la sauvegarde à partir de la racine du système de fichiers, pour inclure tous ces répertoires dans une même sauvegarde. Au contraire, il est parfois utile d'indexer la totalité des fichiers d'un répertoire, mais de n'en sauvegarder que certains sous-répertoires.

Par défaut, le chemin asbolu complet des fichiers est sauvegardé, même lors de la sauvegarde d'un répertoire spécifique. Il est possible d'éviter cela en ajoutant le paramètre --strip.

Attention : Bien que le caractère / soit accepté dans les noms de sauvegarde, il empêche la lecture des sauvegardes de répertoires. En effet, Bup utilise ce caractère comme séparateur entre les différents éléments (nom de sauveagrde, timestamp, chemin). Si certains noms de sauvegardes contiennent ce caractères, il est possible de les corriger en utilisant la commande git --git-dir=<BupDirName> branch -m <WrongName> <NewName>.

Quelques exemples

Sauvegarde du système complet :

$ # Exclusion de certains répertoires spécifiques
$ bup index --exclude=/tmp --exclude=/run /
$ # Exclusion d'une liste de répertoires depuis un fichier contenant des expressions régulières
$ bup index --exclude-rx-from=/etc/bup/ignore /
$ # Sauvegarde des fichiers dans le dépôt bup
$ bup save -n $(hostname -f) /

Sauvegarde de certains répertoires précis :

$ # Indexation de tout le contenu du répertoire /home
$ bup index /home
$ # Sauvegarde du répertoire home de chaque utilisateur dans une sauvegarde séparée
$ for username in $(ls /home); do bup save --strip -n home-$username /home/$username; done

Parcours des données sauvegardées

Il est possible de parcourir le contenu du dépôt bup au moyen de la commande ls.

Sans paramètre, cette commande liste simplement les différentes sauvegardes disponibles. Passer le nom d'une sauvegarde en paramètre permet de lister les différentes versions de cette sauvegarde. On peut ensuite ajouter un chemin après le nom de la sauvegarde, pour lister le contenu d'un répertoire précis dans une version de la sauvegarde désignée.

Quelques exemples :

$ # Lister les sauvegardes
$ bup ls
$ # Lister les différentes versions d'une sauvegarde
$ bup ls <SaveName>
$ # Lister les fichiers d'un répertoire de cette sauvegarde
$ bup ls <SaveName>/<Timestamp>/<Path>

Le parcours du contenu des sauvegardes peut aussi se faire au moyen d'un montage fuse (Filesystem in USErspace) dans un répertoire. Cela permet de lister les fichiers sauvegardés dans votre explorateur de fichiers habituel, mais aussi de lire les fichiers directement. Cette méthode est particulièrement pratique pour récupérer un fichier, ou une information précise dans un fichier, sans avoir à restaurer la totalité de la sauvegarde.

Le paramètre -o permet d'ouvrir l'accès aux sauvegardes à tous les utilisateurs. Le paramètre --meta indique à Bup d'utiliser les méta-données dans ce montage, afin que les droits des fichiers affichés correspondent à ce qui a été sauvegardé.

Exemple :

$ # Monter le contenu d'un dépôt de sauvegarde dans le répertoire <MountPath>
$ bup fuse -o --meta <MountPath>

Synchronisation avec un serveur

Bien que bup permette de sauvegarder directement sur une machine distante, via le paramètre -r, cela utilise automatiquement le répertoire ~/.bup sur la machine distante, ce que je trouve ennuyeux. J'utilise donc simplement la commande push de git pour synchroniser les sauvegardes avec un serveur. De plus, couplé à une application serveur comme gitolite, cela permet de gérer les droits d'accès en écriture aux sauvegardes, afin, par exemple, d'empêcher la machine qui envoie sa sauvegarde d'altérer ou supprimer les précédentes.

Note : Tout comme bup, git permet de définir l'emplacement du dépôt par le paramètre --git-dir ou la variable d'environnement GIT_DIR.

Ajout du remote

$ git remote add backup ssh://<HostName>/<Path>

Note : Il est nécessaire que le dépôt existe avant d'y envoyer des sauvegardes. Si le dépôt n'existe pas, il est possible de l'initialiser avec la commande init de bup.

Envoi des nouvelles sauvegardes

$ git push --all -u

Restauration d'un fichier

La restauration des données est effectuée par la commande join. Cette commande ne prend que le nom de la sauvegarde en paramètre.

Note : Le nom de la sauvegarde est un nom d'objet git. Il est donc possible de donner un hash de commit, le nom d'une branche, etc.

Le contenu de la sauvegarde est restitué sur la sortie standard, il faut donc la rediriger vers une application ou un fichier.

Quelques exemples :

$ bup join <SaveName> > <FileName>
$ bup join <SaveName> | tar Pxf -
$ bup join <SaveName>~1 | pg_restore -d <DbName>

Note : Il est possible de restaurer des données directement depuis une machine distante, en utilisant le paramètre -r, de la même manière que pour la commande init.

Restauration d'un répertoire

La restauration de la sauvegarde d'un répertoire est effectuée par la commande restore. Cette commande prend le nom de la sauvegarde à restaurer en paramètre. Préciser dans quel répertoire restaurer les données se fait au moyen du paramètre --outdir=</path>.

Note : Le nom de la sauvegarde est un nom d'objet git. Il est donc possible de donner un hash de commit, le nom d'une branche, etc.

Il est possible de restaurer la totalité de la sauvegarde, ou juste une partie. Pour cela, il suffit d'ajouter le chemin des fichiers à restaurer à la suite du nom de la sauvegarde.

Quelques exemples :

$ # Restaurer la dernière version d'une sauvegarde
$ bup restore <SaveName>/latest
$ # Restaurer un répertoire précis d'une sauvegarde dans un chemin spécifique
$ bup restore --outputdir=<RestorePath> <SaveName>/<Timestamp>/<Path>

Note : Il n'est actuellement pas possible de restaurer des données directement depuis une machine distante.

Contrôle d'intégrité

La commande fsck permet à bup de vérifier l'intégrité des fichiers du dépôt git.

$ bup fsck

Si le paquet par2 est installé sur le système, bup est capable de générer des informations de redondance, afin de vérifier et corriger les fichiers de sauvegarde. Pour cela, il faut d'abord générer les informations par2.

$ bup fsck -g

Si des erreurs sont détectées par la commande fsck, bup peut tenter de réparer les fichiers, en donnant le paramètre -r.

$ bup fsck -r