nerdism

Duplicity-Backups wiederherstellen

Heute fiel mir auf, dass ich noch ein „paar“ Dateien (einige Git-Repositories) von unserem bereits gekündigten Server sichern und auf einen neuen Server verschieben will. Und dann fiel mir auf, dass der Server bereits vor 5 Tagen gelöscht wurde. Und so begann das Suchen in den Backups.

Auf dem Server setzte ich Debian Linux als Betriebssystem und duplicity als Backup-Software ein. Dieses Backuptool verschlüsselt die Backups mit GPG-Schlüssel, somit braucht man eine intakte (vorzugsweise unixartige) Systemumgebung und den GPG-Schlüssel, mit dem das Backuparchiv erstellt wurde. Meine Herausforderung war nun, die auf einem Linux-Server erstellten Backup-Archive auf dem Mac wieder auszupacken, um die wiederhergestellten Git-Repositories auf einen anderen Server zu verschieben.

Duplicity bekommt man mit Homebrew in Sekundenstelle installiert, ebenso das Skript duply, ein Wrapper für duplicity, der die Konfiguration und Bedienung extrem vereinfacht.

sudo brew install duplicity
sudo brew install duply

nun braucht man die duply-Konfiguration, lag auf dem Server unter /etc/duplyund kann auf dem Mac in ~/.duplyabgelegt werden. Ich nenne das Backup-Set mal „gitrepo“, das Backup-Set liegt in ~/backups.
Es muss noch in der Datei ~/.duply/gitrepo/conf der Pfad zu den Backup-Ordnern geändert werden, z.B.

TARGET='file:///var/backups/duply/gitrepo/'

in

TARGET='file:///Users/drue/backups/gitrepo/'

Nun kann man die Wiederherstellung starten, der GPG-Schlüssel-ID und das Passwort steht in der Duply-Konfiguration. In diesem Beispiel soll das Backup ins Verszeichnis ~/gitrepo wiederhergestellt werden.

$ duply gitrepo restore ~/gitrepo
Start duply v1.5.4, time is 2012-02-03 16:11:46.
Using profile '/Users/drue/.duply/gitrepo'.
Using installed duplicity version 0.6.17, gpg 1.4.11 (Home: ~/.gnupg).
Autoset first GPG_KEY entry '09ABCDEF' as signing key.
Test - Encrypt to 09ABCDEF & Sign with 09ABCDEF (OK)
Test - Decrypt (OK)
Test - Compare (OK)
Cleanup - Delete '/tmp/duply.17084.1328281906_*'(OK)
--- Start running command RESTORE at 16:11:47.000 ---
Max open files of 120 is too low, should be >= 1024.
Use 'ulimit -n 1024' or higher to correct.
16:11:47.000 Task 'RESTORE' failed with exit code '37'.

OK, es ist eben kein Server. Duplicity beklagt, dass die Höchstgrenze gleichzeitig geöffneter Dateien mit 120 zu gering ist. Das lässt sich mit

ulimit -n 1024

auf jedem unixartigen System hochsetzen. Ein alternatives mac-spezifisches Kommando ist

launchctl limit 1024 10240

Nun ein weiterer Versuch:

drue@ain:~$ duply gitrepo restore ~/gitrepo
Start duply v1.5.4, time is 2012-02-03 16:10:32.
Using profile '/Users/drue/.duply/gitrepo'.
Using installed duplicity version 0.6.17, gpg 1.4.11 (Home: ~/.gnupg).
Autoset first GPG_KEY entry '09ABCDEF' as signing key.
Test - Encrypt to 09ABCDEF & Sign with 09ABCDEF (OK)
Test - Decrypt (OK)
Test - Compare (OK)
Cleanup - Delete '/tmp/duply.16860.1328281836_*'(OK)
--- Start running command RESTORE at 16:10:36.000 ---
Synchronizing remote metadata to local cache...
Copying duplicity-full-signatures.20110910T232302Z.sigtar.gpg to local cache.
Traceback (most recent call last):
  File "/usr/local/bin/duplicity", line 1377, in <module>
    with_tempdir(main)
  File "/usr/local/bin/duplicity", line 1370, in with_tempdir
    fn()
  File "/usr/local/bin/duplicity", line 1246, in main
    sync_archive(decrypt)
  File "/usr/local/bin/duplicity", line 1059, in sync_archive
    copy_to_local(fn)
  File "/usr/local/bin/duplicity", line 1008, in copy_to_local
    tdp.move(globals.archive_dir.append(loc_name))
  File "/usr/local/Cellar/duplicity/0.6.17/libexec/duplicity/path.py", line 617, in move
    self.copy(new_path)
  File "/usr/local/Cellar/duplicity/0.6.17/libexec/duplicity/path.py", line 443, in copy
    self.copy_attribs(other)
  File "/usr/local/Cellar/duplicity/0.6.17/libexec/duplicity/path.py", line 448, in copy_attribs
    util.maybe_ignore_errors(lambda: os.chown(other.name, self.stat.st_uid, self.stat.st_gid))
  File "/usr/local/Cellar/duplicity/0.6.17/libexec/duplicity/util.py", line 65, in maybe_ignore_errors
    return fn()
  File "/usr/local/Cellar/duplicity/0.6.17/libexec/duplicity/path.py", line 448, in <lambda>
    util.maybe_ignore_errors(lambda: os.chown(other.name, self.stat.st_uid, self.stat.st_gid))
OSError: [Errno 1] Operation not permitted: '/Users/drue/.cache/duplicity/duply_gitrepo/duplicity-full-signatures.20110910T232302Z.sigtar.gz'

An dieser Stelle habe ich aufgehört, mein Glück mit Duply zu veruchen, da es abbricht, weil es ein paar erweiterte Dateiattribute nicht setzen kann. Beim nächsten Versuch habe ich mir das eigentliche Duplicity-Kommando gesucht und im Ubuntu-Hilfe-Wiki gefunden. Wenn man das GPG-Passwort nicht in der Umgebungsvariable PASSPHRASE hinterlegt, wird man bei der Ausführung des Kommandos duplicity restore ... erfragt.

export PASSPHRASE=SomeLongGeneratedHardToCrackKey
duplicity restore file:///Users/drue/duply/gitrepo/ gitrepo
unset PASSPHRASE

Nun kommt noch immer diese Fehlermeldungen:

...
Error '[Errno 1] Operation not permitted: 'gitrepo/repositories/image_server.git/objects/45'' processing .
...

Das Kommando aber läuft durch. Ich hatte meine Git-Repositories zurück und habe sie mittlerweile funktionierend und an neuer Location wieder am Start.

Epilog

Den Beitrag habe ich geschrieben, um alle im Netz verstreut liegenden Infos zusammenzutragen und den Suchmaschinen zu den Fehlermeldungen die passenden Beschreibungen zu liefern. 😉
Ein wichtige Lehre ist wiedermal: Hast Du alle Daten zur Hand, die Du zur Wiederherstellung brauchst. In diesem Fall waren das der GPG-Schlüssel, das zugehörige Kennwort und natürlich ein möglichst aktuelles und konsistentes Backup.

Hätte die Wiederherstellung auf dem Mac nicht funktioniert, wäre der nächste Programmpunkt, eine Jiffybox mit Debian Linux einzurichten, die Backups auf diesen vServer zu transferieren und mit nahezu identischer Systemumgebung ausgepackt. Hätte aber ein paar Stunden länger gedauert.

Autor

Ich bin Softwareentwickler und derzeit vor allem mit PHP und Webanwendungen beschäftigt. Nach 10 Jahren mit Drupal habe ich mich gerade frisch in Laravel verliebt. Jenseits dessen verteilen sich meine digitalen Interessen zwischen Python, diversen Linuxen und macOS.