Impressum     Datenschutzerklärung      RSS-Feed
   

Python-Skript für Cloud-Backup mit rclone

Cloud Backup mit rclone

Als Programmierer habe ich seit Jahrzehnten ein großzügiges Backup-Konzept für meine Daten. Auch wenn mir schon so manche Maschine abgeraucht ist, hatte ich dennoch nie einen nennenswerten Datenverlust. Redundanz lautet das Zauberwort; je mehr Backups existieren, desto sicherer sind die digitalen Dinge, die ich mir erarbeitet habe. Ab sofort gehört auch die Cloud als Backup-Speicher zu meinem Konzept.

Inhalt

Vorüberlegungen und meine bisherigen Ansätze

Clouds

Software-Pakete für verschlüsselte Cloud-Backups

Grundlagen von rclone

Cloud Backup-Projekt mit Python-Skript

Download

Vorüberlegungen und meine bisherigen Ansätze

Über die Jahre habe ich folgende Ansätze verfolgt:

  • tägliches Backup der wichtigsten Daten auf dieselbe interne Festplatte am PC
  • tägliches Backup der wichtigsten Daten auf eine andere interne Festplatte
  • zweimal pro Woche vollständiges Backup auf eine weitere interne Festplatte
  • zweimal pro Woche vollständiges Backup auf einen weiteren PC im Netzwerk (in einem anderen Raum)
  • wöchentliches vollständiges Backup auf eine externe Festplatte (sonst immer ausgeschaltet)
  • unregelmäßiges, verschlüsseltes Backup der wichtigsten Daten auf CD (für die Jackeninnentasche; für die Wohnung meiner Eltern) oder auf USB-Stick (am Schlüsselbund)
  • fast vollständiges Synchronisieren mit einem mobilen, verschlüsselten Rechner, den ich bei mir habe, wann immer es möglich ist

Diese Methoden funktionieren gut, um auf alte Zustände zurückgreifen zu können und um einen Festplattencrash zu verkraften. Doch einige Gefahren werden damit nur unzureichend abgedeckt:

  • Wohnungsbrand und/oder Wasserschaden, bei dem PC(s) und externe Festplatte(n) dran glauben müssen
  • Einbruch mit Vandalismus oder komplettem Diebstahl meiner Technik
  • Datenverlust durch Virenbefall

Zwar habe ich Backup-CD und USB-Stick stets mit mir herumgetragen oder in fremde Wohnungen ausgelagert, doch waren dies nie vollständige Backups. Auch die synchronisierten Daten auf meinem mobilen Linux-Laptop sind zwar umfassend, aber nicht vollständig. Ein Freund hat seine kompletten Daten regelmäßig auf eine Festplatte kopiert und in einem Bankschließfach gelagert; ein perfektes Backup, dessen Kosten und Logistik ich aber stets gescheut habe.

Clouds

Eine Festplatte im Bankschließfach ist natürlich völlig retro. Heute hat jeder und jede eine Cloud. Doch wir alle wissen:

Clouds gibt es nicht. Eine Cloud ist nichts anderes als jemand anderes Computer.

Meine Daten ungeschützt in einer Cloud zu lagern, kommt für mich nicht in Frage. Kaum ein Cloudanbieter speichert die User-Daten zur Zeit verschlüsselt. Auch benötige ich die Daten weder auf mobilen Tablets oder Smartphones; die Synchronisierung meiner Rechner erledige ich lieber kontrolliert mittels Sync-Software, Unison in meinem Fall. Auf der anderen Seite ist eine Cloud eben genau „jemand anderes Computer“, auf den ich meine Daten auslagern sollte, um sie gegen die o.g. Gefahren zu schützen. Nur verschlüsselt müssen sie sein!

Selbst verschlüsseln ist also angesagt. Verschüsselte Daten kann ich auslagern, wo ich will, und sei es auch auf einem Google-Server in den USA. Also muss eine Software her, die das für mich übernimmt und einen zumutbaren Workflow bietet.

Software-Pakete für verschlüsselte Cloud-Backups

Folgende Programme zum Speichern verschlüsselter Cloud-Backups habe ich mir angesehen:

duplicity

Das Linux-Programm duplicity ist ein schlankes Kommandozeilen-Tool. Mit dem einfachen Befehl

duplicity /home/peter/test webdavs://'<cloud-username>':<cloud-password>@webdav.magentacloud.de/test
duplicity /home/peter/test webdavs://'<

lässt sich ein verschlüsseltes Backup des Ordners /home/peter/test in der (Magenta-)Cloud erstellen. Verwendet wird das webdav-Protokoll, das so ziemlich jede Cloud anbieten wird.
Die in diesem Befehl enthaltenen Zugangsdaten dienen nicht der Verschlüsselung, sondern für den Zugriff auf die Cloud. Das Verschlüsselungs-Password wird nach Eingabe des Befehls abgefragt und muss eingetippt werden. Es kann aber auch über eine Environment-Vaiable ein für alle mal hinterlegt werden.
Das Backup besteht aus einigen Dateien im angegebenen Zielorder (text im obigen Fall), die mit weiteren Backup-Läufen ergänzt werden. Duplicity erstellt inkrementelle Backups, überträgt also immer nur die frisch geänderten Daten.

Warum benutze ich duplicity nicht? Es ist ein reines Linux-Programm. Das ist grundsätzlich kein Problem, doch mein Haupt-Rechner mit den umfassendsten Daten läuft zur Zeit noch mit Windows 7 (ich weiß, auch ziemlich retro).

Boxcryptor

Das mächtige Programm Boxcryptor gibt es für alle drei großen Betriebssysteme. Es ist mehr als nur ein Backup-Programm. Boxcryptor fügt sich nahtlos in eine Cloudumgebung ein. Die Cloud kann wie gewohnt verwendet werden mit dem einzigen Unterschied: Nichts geht mehr unverschlüsselt Richtung „jemand anderes Computer“. Dies ist die größte und umfassendste Lösung, die ich gefunden (aber nicht ausprobiert) habe, die sehr viel Lob in Softwaretests gefunden hat.

Abschreckend ist lediglich der Preis für die kommerzielle Nutzung: 72€ pro Jahr (April 2021) – nur für die Software wohlgemerkt, die Cloud selbst kommt davon unabhängig hinzu. Für private, nicht-kommerzielle Nutzer gibt es ein günstigeres und ein kostenloses Angebot; für manche/n Cloud-User/in ist dies somit vielleicht ein interessantes Produkt.

Cryptomator

Ebenfalls auf allen gängigen Betriebssystemen läuft Cryptomator. Das OpenSource-Programm kommt mit einer aufgeräumten Benutzeroberfläche, die eine einfache Einrichtung erlaubt. Ähnlich wie Boxcryptor integriert sich der Cryptomator in die Oberfläche des Betriebssystems, indem es ein Netzlaufwerk (oder mehrere) bereitstellt, über das einfach Dateien hineinkopiert und herausgeholt werden können. Unter Windows erscheint zu diesem Zweck ein neuer Laufwerksbuchstabe.

Cryptomator kann ich nach meinen kurzen Tests allen empfehlen, die ihre Cloud wie gewohnt (nur über ein neues Laufwerk) verwenden wollen. Allerdings speichert das Programm die Backups in sog. Tresoren, also einer Art Container, in die alle Dateien hineingeworfen werden. Das mag seine Vorteile haben, ich bevorzuge aber, die ursprüngliche Ordnerstruktur und die Dateien einzeln im Backup vorzufinden.

Duplicati

Ein weiteres OpenSource-Programm ist Duplicati. Es läuft unter Windows, Linux und MacOS und ist kostenlos nutzbar, auch für kommerzielle Zwecke. Die Einrichtung erfolgt über eine gut ausgestattete Oberfläche.

Warum ich dieses Programm nicht ausprobiert habe, weiß ich nicht mehr :-|

rclone

OpenSource, plattformübergreifend (Linux, Windows, MacOS, ...), kostenlos – Diese Eigenschaften bringt das reine Kommandozeilen-Tool rclone mit sich. Mit diesem Programm habe ich einige Tests gemacht und mich entschieden, ein Python-Skript zu schreiben, das ich mittels Cronjob oder Aufgabenplanung automatisch starten kann, um meine Backups in eine Cloud zu erledigen. Mehr dazu in den folgenden Abschnitten.

Grundlagen von rclone

Bei einem Kommandozeilen-Tool bleibt einem meist nichts anderes übrig, als die Dokumentation durchzuarbeiten. Ein guter Startpunkt findet sich auf der rclone-Website. Ich versuche hier in aller Kürze, einen (unvollständigen) Überblick zu geben.

Remotes

Grundlage aller Arbeit mit rclone sind die sog. Remotes, von denen sich unbegrenzt viele anlegen lassen. Jedes Remote definiert die Zugangsdaten zu einem einzelnen (entfernten) Datenspeicher. Rclone bietet den Zugang zu unzähligen gängigen Clouds. Wird z.B. ein Remote mit dem Namen „MagentaCloud“ angelegt, das – logisch – den Zugriff auf eine MagentaCloud definiert, kann anschließend mittels rclone ls MagentaCloud: der Inhalt dieser Cloud gelistet werden. Andere Kommandos (erster Parameter von rclone) erlauben andere Zugriffe wie etwa das Synchronisieren:

rclone ls MagentaCloud: ➞ listet den Inhalt der gesamten Cloud

rclone space MagentaCloud: ➞ berechnet den belegten Speicherplatz in der gesamten Cloud

rclone space MagentaCloud:<Folder> ➞ berechnet den belegten Speicherplatz im angegebenen Cloud-Unterordner

rclone sync <FolderSource> MagentaCloud: ➞ synchronisiert den angegebeben lokalen Quell-Ordner mit der Cloud (Backup erstellen / aktualisieren)

rclone sync <FolderSource> MagentaCloud:<FolderBackup> ➞ synchronisiert den angegebeben lokalen Ordner mit einem Ziel-Ordner in der Cloud (Backup erstellen / aktualisieren)

rclone sync MagentaCloud:<FolderBackup> <FolderRestore> ➞ synchronisiert den angegebeben Ordner in der Cloud mit dem angegebenen lokalen Ordner (Backup zurückspielen an einen bestimmten Ort)

Hinweis:

Der sync-Befehl arbeitet immer von links nach rechts. Die Daten im Quell-Ordner, auf die der zweite rclone-Aufrufparameter verweist, bleiben immer unangetastet! Verändert (synchronisiert) werden nur die Ziel-Daten, auf die der dritte rclone-Parameter verweist.

Verschlüsselung

Ein solches Remote arbeitet zunächst einmal unverschlüsselt. Um Daten verschlüsselt in der Cloud speichern zu können, muss ein weiteres Remote angelegt werden, das sich nicht direkt mit der Cloud, sondern dem zuvor erstellten Remote verbindet. Klingt kompliziert? Ist es aber nur auf den ersten Blick. Das erste Remote dient dazu, Daten an die Cloud weiterzureichen. Das zweite dagegen ist für das Verschlüsseln zuständig und reicht die dann verschlüsselten Daten an das erste Remote weiter, welches sie dann an die Cloud weiterreicht. Arbeitsteilung eben; jeder macht, was er am besten kann :-)

lokale Daten V Remote2 (verschlüsselt die Daten) V Remote1 (schickt die Daten an die Cloud) V Cloud

Um Daten also verschlüsselt mit der Cloud auszutauschen (und verschlüsselt dort abzulegen), muss mit einem verschlüsselnden Remote kommuniziert werden. Daher ist es wichtig, diesem einen guten, sprechenden Namen zu geben. Ist meine Cloud z.b. die o.g. MagentaCloud, bieten sich folgende Namen an:

MagentaCloud ➞ Remote-Name für den unverschlüsselten Cloud-Zugriff

CryptMagentaCloud ➞ Remote-Name für das verschlüsselnde Remote, das auf MagentaCloud zugreift

Filtern

Nicht immer sollen alle lokalen Daten gesichert werden. Um Cloud-Speicher zu sparen, können viele Dateitypen ausgeschlossen werden. Lokale Backup-Dateien z.B. (*.bak), Sicherungs-Kopien (Kopie von *.*, Kopie (*.*) oder vielleicht auch zip-Dateien (*.zip). Diese Angaben können in einer Textdatei hinterlegt und an rclone übergeben werden:

# Textdatei /home/peter/BackupExclude.txt # Wildcards: ? -> genau ein Zeichen # * -> beliebig viele Zeichen außer '/' # ** -> beliebig viele Zeichen, auch '/' # ausgeschlossene Dateien: *.bak Kopie von *.* Kopie (*.* *.zip # ausgeschlossene Ordner (gekennzeichnet durch den Slash am Ende): muell/ Sicherung von */ WichtigeDateien/RiesigeDateien/ WichtigeDateien/**/RiesigeDateien/

Für die Berücksichtigung einer solchen Datei ist der rclone-Aufrufparameter --exclude-from vorgesehen:

rclone <command> [SomeParameters] --exclude-from=<PathToExcludeFile>

Windows-Beispiel:

rclone sync d:\peter\Wichtig MagentaCloud:Wichtig --exclude-from=d:\peter\BackupExclude.txt

Linux-Beispiel:

rclone sync /home/peter/Wichtig MagentaCloud:Wichtig --exclude-from=/home/peter/BackupExclude.txt

Von diesen Dateien können beliebig viele übergeben werden, die der Reihe nach berücksichtigt werden.

Hinweis: Neben dem Ausschließen von Dateien gibt es das etwas flexiblere Filtern (--filter-from=). In den entsprechenden Dateien können Ausschlüsse und Einschlüsse definiert werden. So ist es z.B. möglich, in der ersten Filterdatei alle (speicherplatzintensiven) mp4-Videos auszuschließen, in einer folgenden dann aber ein spezielles, wichtiges Video wieder einzuschließen. Näheres bitte der rclone-Dokumentation entnehmen.

rclone-Konfigurationsdatei

Die Einstellungen für die Remotes liest rclone aus einer Konfigurationsdatei (wie Remotes interaktiv anlegt werden, beschreibe ich im nächsten Abschnitt). Diese liegt unter Linux standardmäßig unter ~/.config/rclone/ und hat den Namen rclone.conf (im Zweifelsfall kann der Pfad mit dem Befehl rclone config file angezeigt werden). Soll eine andere Konfiguration verwendet werden, so kann der Parameter --config verwendet werden:

rclone <command> [SomeParameters] --config=<PathToConfigFile>

Die Konfigurationsdatei ist eine einfache Textdatei im INI-Format:

# rclone.conf # remote for cloud access # with cloud server and cloud user and cloud password [MagentaCloud] type = webdav url = https://webdav.magentacloud.de/backup/rclone vendor = MagentaCloud user = meine.mailadresse@t-online.de pass = nEYvNQFiJh9FJJSDSAqnWzsp3Nr2yGIx9jJi-TQ # crypt remote using the MagentaCloud-remote # only for folder 'Privates' [MagentaCloudCryptPrivates] type = crypt remote = MagentaCloud:Privates filename_encryption = off directory_name_encryption = false password = -sdBVzuYG7jjdudzjY-pvporbjibDdBvDpAngA # crypt remote using the MagentaCloud-remote # only for folder 'Softwareentwicklung' [MagentaCloudCryptSoftwareentwicklung] type = crypt remote = MagentaCloud:Softwareentwicklung filename_encryption = off directory_name_encryption = false password = -sdBVzuYG7jjdudzjY-pvporbjibDdBvDpAngA

In diesem Beispiel finden wir drei Remotes mit einigen Besonderheiten:

MagentaCloud ➞ Remote für den unverschlüsselten Cloud-Zugriff; die angegebene url enthält einen tiefergehenden Pfad in der Cloud (/backup/rclone); unterhalb dieses Cloud-Pfads werden alle Aktivitäten dieses Remotes stattfinden.

MagentaCloudCryptPrivates ➞ Remote-Name für das verschlüsselnde Remote, das auf die oben definierte MagentaCloud zugreift und nur die privaten Daten behandeln soll. Alle Backups landen im Cloud-Speicherort /backup/rclone/Privates. Ordner und Dateinamen werden in diesem Beispiel nicht verschlüsselt.

MagentaCloudCryptSoftwareentwicklung ➞ dito, außer: Dieses Remote behandelt nur den Arbeitsbereich 'Softwareentwicklung'. Alle Backups landen im Cloud-Speicherort /backup/rclone/Softwareentwicklung

Hinweis:

An dieser Stelle wird noch einmal deutlich, dass wir es mit mindestens zwei Passwörtern zu tun haben. Das erste Remote enthält das Password für die Cloud, wie es beim Cloud-Anbieter hinterlegt ist. Die beiden anderen Remotes definieren die Passwörter (in diesem Fall beide gleich), die für die Verschlüsselung der Daten durch rclone verwendet werden.

rclone konfigurieren / Remotes anlegen

Mit dem Befehl

rclone config

oder auch

rclone config --config=<PathToConfigFile>

kann die interaktive Einrichtung der Remotes gestartet werden. Es erscheint eine Darstellung der bisher angelegten Remotes und eine Eingabeaufforderung:

Name Type ==== ==== MagentaCloud webdav MagentaCloudCryptSoftwareentwicklung crypt MagentaCloudCryptPrivates crypt e) Edit existing remote n) New remote d) Delete remote r) Rename remote c) Copy remote s) Set configuration password q) Quit config e/n/d/r/c/s/q> _

Gibt man hier n<enter> für 'new' ein, muss zuerst ein Name vergeben werden. Anschließend erscheint eine erschlagende Auswahl an Möglichkeiten, die ich hier nur auszugsweise widergebe:

... name> GanzNeuesRemote Type of storage to configure. Enter a string value. Press Enter for the default (""). Choose a number from below, or type in your own value 1 / 1Fichier \ "fichier" 2 / Alias for an existing remote \ "alias" 3 / Amazon Drive \ "amazon cloud drive" ... 5 / Backblaze B2 \ "b2" ... 9 / Dropbox \ "dropbox" 10 / Encrypt/Decrypt a remote \ "crypt" ... 13 / Google Drive \ "drive" ... 18 / Local Disk \ "local" ... 21 / Microsoft OneDrive \ "onedrive" ... 29 / Webdav \ "webdav" ... Storage> _

Die MagentaCloud findet sich nicht in diesen Optionen, aber 'webdav'. Wie oben schon angesprochen ist dieses Protokoll sehr universell, und so kann darüber auch die MagentaCloud angebunden werden. Weiterhin interessant ist 'local', um rein lokale Backups zu erzeugen, und natürlich 'crypt', worüber ein verschlüsselndes Remote angelegt werden kann, das seinerseits auf ein anderes Remote zugreift (s.o.).

An dieser Stelle steige ich aus der Beschreibung aus. Der weitere Vorgang ist interaktiv und einigermaßen selbsterklärend. Mehr Details müssen in der rclone-Dokumentation erforscht werden. Eine gute Step-by-Step-Beschreibung findet sich auch in einem ausführlichen Blogartikel von Andy Ibanez: rclone: From Basics to Encryption.

Als Ergebnis all dieser Bemühungen erscheint ein neuer Eintrag in der Konfigurationsdatei. Da diese aber eine reine Textdatei ist, kann nach Belieben darin herumergänzt werden; man muss also nicht für jedes Remote einen interaktiven Konfig-Durchlauf starten. Lediglich für die Eingabe eines neuen Passwords (Passwörter werden verschlüsselt gespeichert) ist ein neuer Durchlauf nötig.

Mein eigenes Cloud Backup-Projekt mit Python-Skript

Als Telekom-Kunde habe ich eine kostenfreie 25GB-MagentaCloud. Diese wollte ich endlich als außer-Haus-Backup nutzen, aber natürlich nur verschlüsselt. Dabei hilft mir jetzt rclone in Zusammenarbeit mit einem eigenen Python-Skript.

Vorgaben

Als Besonderheit spielt zunächst die langjährige Struktur meiner Daten eine Rolle. Im jeweiligen Homeverzeichnis auf jedem meiner Rechner (D:\peter\ bzw. /home/peter/) finden sich wenige Hauptordner, die meine Arbeitsbereiche darstellen. Wie oben schon angegeben sind dies u.a. die Bereiche 'Privates' und 'Softwareentwicklung', die auch gleichzeitig die Ordner-Namen darstellen.

HomeFolder | |--- SourceFolderName1 (e.g. Privates) |--- SourceFolderName2 (e.g. Softwareentwicklung) |--- SourceFolderName3 |--- ...

Tja, und dies waren meine Ideen und Wünsche:

  • Jeden dieser Ordner möchte ich separat sichern können, und jeder Ordner soll mit demselben Namen im Backup auftauchen.
  • Das Python-Skript soll den rclone-Aufruf managen und je nach Aufrufparameter alle Arbeitsbereiche (Hauptordner) behandeln oder nur den angegebenen (und evtl. auch nur einen angegebenen Unterordner).
  • Ich möchte die Backups aktualisieren können, die Dateien darin auflisten, die Gesamtgrößen ermitteln und Backups wieder zurückspielen können, ohne dass die ursprünglichen Daten dabei gefährdet werden (restore in ein anderes Verzeichnis!).
  • Außerdem möchte ich pro Arbeitsbereich andere Dateien ausschließen können; gleichzeitig gibt es aber Dateitypen, die ich in allen Bereichen vom Backup ausschließen möchte.
  • Je nach Betriebssystem soll das Skript aufgerufen werden mittels .bat-Datei oder .sh-Datei.

Skript-Datei und weitere Dateien

Neben der eigentlichen Python-Skript-Datei rclone.py werden noch ein paar weitere Dateien im selben Verzeichnis erwartet:

ScriptFolder | |--- <rcloneExeFolder> | |--- rclone.exe (rclone executable) | |--- rclone.py (the python script) |--- rclone.conf (rclone config file) |--- rclone-exclude-all.txt (common excludes) |--- rclone-exclude-<SourceFolderName1>.txt (special excludes) |--- rclone-exclude-<SourceFolderName2>.txt (special excludes) |--- rclone-exclude-<SourceFolderName3>.txt (special excludes)

rclone.exe ➞ Unter Windows kann hier die Datei rclone.exe liegen; sie kann aber auch irgendwo anders liegen, der genaue Ort wird im Python-Skript fest hinterlegt (hardcoded).

rclone.py ➞ mein Python-Skript

rclone.conf ➞ die rclone-Konfigurationsdatei; sie kann hier erstellt oder hierher kopiert worden sein oder per Symlink hier bereitgestellt werden.

rclone-exclude-all.txt ➞ Textdatei, in der Datei- und Ordner-Ausschlüsse definiert werden, die für alle Arbeitsbereiche (Haupt-Quell-Ordner) gelten

rclone-exclude-<SourceFolderName...>.txt ➞ Textdatei(en), in der/denen Datei- und Ordner-Ausschlüsse definiert werden, die für den jeweiligen Arbeitsbereich gelten

Das Python-Skript

Dieses Skript (rclone.py) läuft unter Windows und Linux. Es erwartet zwei Aufrufparameter, zwei weitere sind optional:

python <PathToScriptFolder>/rclone.py <operation> <PathToHomeFolder> [<SourceFolderName>] [<SourceSubFolderName>]

<PathToScriptFolder> ➞ Pfad zum Skript-Verzeichnis

<operation> ➞ Befehl, der ausgeführt werden soll; mögliche Werte: list-source, size-source, backup, restore, list-remote, size-remote

<PathToHomeFolder> ➞ Pfad zum Home-Verzeichnis

<SourceFolderName> ➞ wenn übergeben, wird nur dieser Arbeitsbereich bearbeitet

<SourceSubFolderName> ➞ wenn übergeben, wird nur dieses Unterverzeichnis des angegebenen Arbeitsbereiches bearbeitet (<SourceFolderName> muss ebenfalls übergeben werden)

Die genannten möglichen Operationen haben folgende Aufgaben:

  • list-source, size-source: Listet die Dateien oder berechnet die Gesamtgröße der Quell-Dateien (im Home-Verzeichnis) unter Berücksichtigung der ausgeschlossenen Dateien (aufgelistet in den Exclude-Dateien)
  • backup: Führt ein Backup durch; die lokalen Dateien in den Quell-Ordnern bleiben unangetastet, verändert werden nur die Daten in der Cloud.
  • restore: Spielt die Backups zurück; auch hier bleiben alle lokalen Daten in den Quell-Ordnern unangetastet; die aus der Cloud zurückgespielten Daten werden im Skript-Ordner in einem neuen Unterordner gespeichert, dessen Name die genaue Zeitinformation des Zurückspielens enthält.
  • list-remote, size-remote: Listet die Dateien oder berechnet die Gesamtgröße der Backup-Dateien (in der Cloud)

Hier nun der Code des kompletten Skripts:

# ----------------------
# rclone.py
# by Peter Teuchert (www.coonlight.de)
# April 2021
# see www.coonlight.de/artikel/2021/2022-04-05-python-skript-fuer-cloud-backup-mit-rclone/
# 
# use freely as you like, but without any guarantee!
# 
# python script for backup and restore with rclone
#
# call: rclone.py <operation> <HomeFolder> [<SourceFolderName>] [<SourceSubFolder>]
#
# this script backups and restores whole folders to an encrypted rclone remote
# these folders has to lie under a single home folder:
#
# HomeFolder
#     |
#     |--- SourceFolderName1
#     |--- SourceFolderName2
#     |--- SourceFolderName3
#     |---        ...
#
# the HomeFolder is parameter #2 for this script
# the SourceFolderNames are specified at the bottom of this file 
# in the calls of DoRClone(<SourceFolderName>), 
# or a single one is passed via parameter #3
#
# configuration of rclone via rclone config
# - unencrypted remote 
#   named <RCloneRemoteName> (here hardcoded as "MagentaCloud")
# - an encrypted remote for each SourceFolderName 
#   named <RCloneRemoteName>Crypt-<SourceFolderName> e.g. "MagentaCloudCrypt-Important"
#
# configuration file rclone.conf must exist in the folder of this script
# also the exclude file rclone-exclude-all.txt 
# and for each SourceFolderName a file rclone-exclude-<SourceFolderName>.txt
#
# don't forget to change things under "prepare" according to your needs
#
# ----------------------

import sys, os, time
import subprocess
import colorama
from colorama import Fore, Back, Style
from argparse import ArgumentParser
from datetime import datetime

colorama.init()

print(Style.BRIGHT)


# ----------------------
# prepare
# ----------------------
print(Style.BRIGHT + Fore.CYAN)

# date time string for the path for restoring the backup in
now = datetime.now()
DateTime = now.strftime("%Y-%m-%d_%H-%M-%S")
print("DateTime              = " + DateTime)

# path to the folder of this python script
ThisScriptFolder = os.path.normpath(os.path.dirname(os.path.abspath( __file__ )))
print("ThisScriptFolder      = " + ThisScriptFolder)

# path to the rclone folder with all the config files
# this path is also the root for restoring backups
RCloneFolder = os.path.normpath(ThisScriptFolder)
print("RCloneFolder          = " + RCloneFolder)

# path to the rclone executable
if(sys.platform.startswith("win")):
# in this case (Windows) in a subfolder of RCloneFolder
  RCloneExeFile = os.path.normpath(RCloneFolder + "/rclone-v1.55.0-windows-amd64/rclone.exe")
elif(sys.platform.startswith("linux")):
# for Linux just "rclone"
  RCloneExeFile = "rclone"
print("RCloneExeFile         = " + RCloneExeFile)

# name of the unencrypted rclone remote which is used by the encrypted remotes
# the encrypted remotes has to be named <RCloneRemoteName>Crypt-<SourceFolderName>
RCloneRemoteName = "MagentaCloud"
print("RCloneRemoteName      = " + RCloneRemoteName)

# path to the rclone.conf file
# in this case in the RCloneFolder itself
RCloneConfigFile = os.path.normpath(RCloneFolder + "/rclone.conf")
print("RCloneConfigFile      = " + RCloneConfigFile)

# list of the main source folders
# these folders must lie directly under the home folder (e.g. /home/peter or d:\peter)
# (the home folder is passed to this script with the second parameter)
AllSourceFolderNames = ["Privates", "Softwareentwicklung"]



# ----------------------
# parameters
# ----------------------
print(Style.BRIGHT + Fore.CYAN)

# parameters for this script:
# this script expects four parameters, the last two are optional
parser = ArgumentParser()
parser.add_argument("operation")
parser.add_argument("homefolder")
parser.add_argument("sourcefoldername", nargs="?", default="") # optional
parser.add_argument("sourcesubfolder", nargs="?", default="") # optional
args = parser.parse_args()

# no. 1: the operation to be done:
# values: list-source, size-source, backup, restore, list-remote, size-remote
Command = args.operation
print("Command               = " + Command)

# no. 2: path to the home directory, where all the source folders lie in
HomeFolder = os.path.normpath(args.homefolder)
print("HomeFolder            = " + HomeFolder)

# no. 3: just handle this one source folder
SourceFolderName = args.sourcefoldername
print("SourceFolderName      = " + SourceFolderName)

# no. 4: just handle this one source subfolder
SourceSubFolder = os.path.normpath(args.sourcesubfolder)
if(SourceSubFolder == "."):
  SourceSubFolder = ""
print("SourceSubFolder       = " + SourceSubFolder)



# ----------------------
# call function
# ----------------------
# this function is called for every single source folder
# with or without a sub folder
def DoRClone(source_folder_name, source_sub_folder = ""):
  print(Style.BRIGHT + Fore.GREEN)
  print("---------------------")
  if(source_sub_folder == ""):
    print(source_folder_name)
  else:
    print(source_folder_name + "/" + source_sub_folder)
  print("---------------------")
  
  # the path of the source folder to be backuped or restored
  SourcePath = os.path.normpath(HomeFolder + "/" + source_folder_name + "/" + source_sub_folder)
  print("SourcePath            = " + SourcePath)
  
  # the used rclone remote with subfolder
  RCloneRemote = RCloneRemoteName + "Crypt-" + source_folder_name + ":" + source_sub_folder
  print("RCloneRemote          = " + RCloneRemote)
  
  if(Command == "list-source" or Command == "size-source" or Command == "backup"):
    # the rclone exclude file for all source folders: rclone-exclude-all.txt
    RCloneExcludeFileAll = os.path.normpath(RCloneFolder + "/rclone-exclude-all.txt")
    print("RCloneExcludeFileAll  = " + RCloneExcludeFileAll)
    # the rclone exclude file for this special source folder: rclone-exclude-<source_folder_name>.txt
    RCloneExcludeFileThis = os.path.normpath(RCloneFolder + "/rclone-exclude-" + source_folder_name + ".txt")
    print("RCloneExcludeFileThis = " + RCloneExcludeFileThis)
  if(Command == "restore"):
    # restore path inside the rclone config folder 
    # namend by date and time and source folder name
    RestorePath = os.path.normpath(RCloneFolder + "/" + DateTime + "_" + source_folder_name + "/" + source_sub_folder)
    print("RestorePath           = " + RestorePath)
  print(Style.BRIGHT + Fore.WHITE)
  
  if(Command == "list-source"):
    subprocess.run([RCloneExeFile, 
                    "ls", 
                    SourcePath, 
                    "--config=" + RCloneConfigFile, 
                    "--exclude-from=" + RCloneExcludeFileAll, 
                    "--exclude-from=" + RCloneExcludeFileThis])
  elif(Command == "size-source"):
    subprocess.run([RCloneExeFile, 
                   "size", 
                   RCloneRemote, 
                    "--config=" + RCloneConfigFile, 
                    "--exclude-from=" + RCloneExcludeFileAll, 
                    "--exclude-from=" + RCloneExcludeFileThis])
  elif(Command == "backup"):
    subprocess.run([RCloneExeFile, 
                   "sync", 
                   SourcePath, 
                   RCloneRemote, 
                   "--delete-excluded", 
                   "--progress", 
                   "--stats=1000ms", 
                   "--stats-file-name-length=38", 
                   "--config=" + RCloneConfigFile, 
                   "--exclude-from=" + RCloneExcludeFileAll, 
                   "--exclude-from=" + RCloneExcludeFileThis])
  elif(Command == "restore"):
    subprocess.run([RCloneExeFile, 
                   "sync", 
                   RCloneRemote, 
                   RestorePath, 
                   "--progress", 
                   "--stats=1000ms", 
                   "--stats-file-name-length=38", 
                   "--config=" + RCloneConfigFile])
  elif(Command == "list-remote"):
    subprocess.run([RCloneExeFile, 
                    "ls", 
                    RCloneRemote, 
                    "--config=" + RCloneConfigFile])
  elif(Command == "size-remote"):
    subprocess.run([RCloneExeFile, 
                   "size", 
                   RCloneRemote, 
                   "--config=" + RCloneConfigFile])

  time.sleep(0.3)
  
  return


  
# ----------------------
# main action: call backups
# ----------------------
print(Style.BRIGHT + Fore.WHITE)

if(SourceFolderName != ""):
  # call once for the specific source folder and sub folder
  DoRClone(SourceFolderName, SourceSubFolder)
else:
  # call for all my source folders
  for source_folder_name in AllSourceFolderNames:
    DoRClone(source_folder_name)



# ----------------------
# bye
# ----------------------
print(Style.BRIGHT + Fore.GREEN)

print("all ready")

print("closing soon ...")

time.sleep(3)

Die aufrufenden Dateien

Für jede der sechs möglichen Operationen habe ich mir eine Windows-Batch-Datei und ein Linux-Bash-Skript geschrieben. Diese verwende ich z.B., um per Aufgabenplanung oder Cron-Job automatisiert Backups erstellen zu lassen. Zwei Beispiel-Dateien folgen hier:

rem run-rclone-backup.bat
rem to start the rclone-python-script on a windows-machine

@echo off
COLOR 1F

set THISFOLDER=%~dp0
set RCFOLDER=%THISFOLDER%

python %RCFOLDER%rclone.py backup d:\peter %1 %2

echo.&pause&goto:eof
#!/bin/bash

# run-rclone-backup.sh
# to start the rclone-python-script on a linux-machine

THISFOLDER="`dirname \"$0\"`"

python3 $THISFOLDER/rclone.py backup /home/peter $1 $2

read -p "Press <enter> to continue"

Download

Last but not least hier ein Download-Link:

  ➞ Download ZIP-Datei: python-skript-fuer-cloud-backup-mit-rclone.zip

Darin enthalten sind das Python-Skript, Beispiel-Konfigurations- und -Exclude-Dateien, Aufruf-Dateien (Windows-Batch und Linux-Bash). Sowohl die rclone-Konfigurationsdatei als auch die Exclude-Dateien sind nur als Beispiele zu betrachten und müssen neu eingerichtet oder ersetzt werden. Auch im Skript selbst müssen die Vorgaben unter dem Punkt „prepare“ auf die eigenen Bedürfnisse angepasst werden. Die Aufruf-Dateien erwarten eine Anpassung des lokalen Wurzelverzeichnisses (HomeFolder).

Diese Software ist Freeware und darf beliebig verwendet werden (auch kommerziell). Selbstverständlich übernehme ich keinerlei Garantie und keinerlei Haftung im Schadensfalle.

 

rclone-Website rclone.org
rclone-Dokumentation rclone.org/docs/
Blogartikel von Andy Ibanez
rclone: From Basics to Encryption
www.andyibanez.com/posts/rclone-basics-encryption/
Ich freue mich, wenn Du
diesen Artikel weiterempfiehlst:
 
bisherige Kommentare:
neuer Kommentar:
(freiwillige Angabe)
(freiwillige Angabe; Spam-Links werden gelöscht!)
(freiwillige Angabe; wird nicht veröffentlicht)
Zitate bitte mit eckigen Klammern umschließen: [ ... ]

Die von Ihnen eingegebenen Daten (nur der Kommentartext ist Pflichtfeld) werden gespeichert, um den Kommentar auf dieser Seite anzeigen zu können. Ihre IP-Adresse wird nicht gespeichert.

Beachten Sie auch die Datenschutzerklärung.

Bitte die Lösung angeben (Spamschutz):
3 + 5 = 
  
 
- 33ms -     (c) www.coonlight.de     Impressum     Datenschutzerklärung      RSS-Feed