j’ai acheté un PC...
Sauvegarde intelligente sur HubiC

Sauvegarde intelligente sur HubiC

⏱ 3 mn

Introduction

Il y a pas loin d’une année je publiais un script bash permettant de faire des backups distants sur HubiC (complets & incrémentaux) de toutes vos données. Un an et un changement de connexion ADSL plus tard, ce script n’est pas vraiment viable. En effet, je suis passé d’une fibre optique à une connexion ADSL avec une forte atténuation. Pour transférer mes données complète ça prend pas loin d’une journée …

J’ai donc changé le script pour pallier ce problème. L’idée est toujours de sauvegarder mes données mais au lieu d’un ubert tar découpé que je transfère une fois par semaine, je suis parti sur une sauvegarde par sous-répertoire et un transfert des modifications uniquement.

Explications

On a un script qui prend en entrée la passphrase et le répertoire à sauvegarder.

  • Pour le répertoire, on liste les sous-répertoires et pour chacun on génère un sha1 qui va permettre de savoir si le répertoire a été modifié ou non depuis la dernière analyse.
  • Pour chaque répertoire, on crée un tar.gz que l’on crypte en GPG et que l’on envoie sur hubic. Cette partie la ne diffère pas de la version précédente du script.
  • Enfin, on stocke le nom du répertoire et le sha1 dans un fichier .bkp_sha1sum.lst dans le répertoire principal.

De cette façon le script est capable de détecter les répertoires qui ont changé et ne transfère que les répertoires modifiés. Alors certes si le répertoire à sauvegardé est un gros répertoire fourre tout ce script aide pas. La version précédent est plus adaptée. Mais dans le cas par exemple d’un répertoire Photos trié par année ou par évènement, où l’année passée ne bougera plus jamais, ce script est nettement plus efficace.

Le script

#!/usr/local/bin/bash

BACKUP_DIR=$2
hubicpy=./hubic.py
sha1sumFile="${BACKUP_DIR}/.bkp_sha1sum.lst"
passphrase=$1

touch "${sha1sumFile}"
ls "$BACKUP_DIR" | while read line; do

  if [[ ! -d "$BACKUP_DIR/$line" ]]; then
    continue
  fi

  filename=$(echo $line | cut -d'/' -f 1,2 | sed "s/[ \/,.'!?()]//g")
  safeLine=$(echo $line | sed -e 's/[][()\.^$?*+]/\\&/g')
  sha1=$(find "$BACKUP_DIR/$line" -type f -print0 | sort -z | xargs -0 shasum | shasum | cut -d' ' -f 1)
  bkpsha1=$(grep -x -E "[0-9a-f]{40} ${safeLine}" "${sha1sumFile}"  | head -n 1 | cut -d' ' -f 1)
  
  if [[ -n "$bkpsha1" && ("$sha1" == "$bkpsha1") ]]; then
    echo "${sha1} ${line}"
    continue
  fi
  # Remove the line with old sha1
  if [[ -n "$bkpsha1" ]]; then
    echo "/${bkpsha1}/d -> ${sha1sumFile}"
    sed -i '' "/${bkpsha1}/d" "${sha1sumFile}"
  fi
  tar -P -czf - "${BACKUP_DIR}/${line}" | gpg --batch --yes --passphrase ${passphrase} -ac -o "/tmp/${filename}.tar.gz.gpg"
  $hubicpy --swift -- upload --use-slo --segment-size 15000000 --object-name "backup/$(basename $BACKUP_DIR)/${filename}.tar.gz.gpg" default /tmp/${filename}.tar.gz.gpg
  if [ $? -eq 0 ]; then
    echo "${sha1} ${line}"
    echo "${sha1} ${line}" >> "${sha1sumFile}"
  else
    $hubicpy --swift -- list default_segments | grep "backup/$(basename $BACKUP_DIR)/${filename}.tar.gz.gpg" | xargs -I {} sh -c "${hubicpy} --swift delete {}"
    exit 1
  fi
  rm -f /tmp/${filename}.tar.gz.gpg
done
# Clean the sha1 file
while IFS='' read -r line || [[ -n "$line" ]]; do
  filename=$(echo $line | cut -d' ' -f 2-)
  if [[ ! -d "$BACKUP_DIR/$filename" ]]; then
    sha1=$(echo $line | cut -d' ' -f 1)
    sed -i '/'$sha1'/d' "${sha1sumFile}"
  fi
done < "${sha1sumFile}"

Sauvegarde intelligente sur HubiC est paru le