Mit Baculas hoher Flexibilität einher geht auch eine hohe Komplexität bei den Konfigurationsdateien. Letztendlich landet man aber, nachdem man sich mal damit befasst hat, bei einer Konfiguration, die für jeden Rechner weitestgehend gleich ist. Bei einigen Resourcen muss man sogar nur den Namen austauschen.
In meinem Setup habe ich 10 Rechner, die gesichert werden sollen. Mit dem normalen Ansatz müsste ich nun 10 Mal die komplette Konfiguration durchführen, die weitestgehend gleich ist.
Als Alternative würde schon eine Direktive genügen, mit der ich in der Konfiguration, die ja das Einbinden von anderen Dateien erlaubt, Variablen angeben könnte, die ersetzt würden, dachte ich mir. Nachdem ich mir anschaute, wie man das am besten implementieren könnte, bemerkte ich, dass Bacula auch mit Pipes umgehen kann beim Laden von Konfigurationsdateien, sprich man kann andere Programme ausführen und deren Ausgabe verwenden.
In bester UNIX-Manier kann man also sed
und Shell-Scripts
verwenden, um sich die Konfiguration zu abstrahieren. Jedoch gab es zwei kleine
Probleme:
- Ein Bug verhinderte, dass Pipes richtig ausgeführt werden, denn das Pipe-Zeichen wurde nicht übersprungen und somit wurde das auszuführende Programm nicht gefunden.
- Der Parser behandelte Anführungszeichen bei Include-Direktiven als Trennzeichen und erlaubte keine Angabe eines Befehls, der Leerzeichen enthielt und daher in Anführungszeichen eingeschlossen werden muss. Somit könnte man zwar ein Shellscript ausführen, ihm jedoch keine Parameter mitgeben, wodurch man nichts gewonnen hätte.
Beide Fehler konnte ich für Version 2.2.7 von Bacula beheben.
Templates
Wie die Templates nun aussehen, die man sich selbst macht, ist weitestgehend
beliebig. Ich habe als Variable zum Beispiel %name
verwendet. Mit
sed
wird diese Variable dann ersetzt.
Template-Datei default-pool.inc
Pool { Name = %name Pool Type = Backup Maximum Volume Jobs = 1 Volume Retention = %ret Maximum Volume Bytes = 0 Volume Use Duration = 0 }
Einbindung in bacula-dir.conf
@"|sed 's/%name/codebox/g;s/%ret/2 weeks/g' /etc/bacula/default-pool.inc"
Hier wurde also %name
durch „codebox” ersetzt und die Volume Retention-Variable %ret
durch „2 weeks”. Nach diesem Schema kann man nun mehrere Rechner sehr einfach einbinden:
@"|sed 's/%name/codebox/g;s/%ret/2 weeks/g' /etc/bacula/default-pool.inc" @"|sed 's/%name/ibook/g;s/%ret/4 weeks/g' /etc/bacula/default-pool.inc" @"|sed 's/%name/macbook/g;s/%ret/4 weeks/g' /etc/bacula/default-pool.inc"
Das macht dann 3 Zeilen im Vergleich zu 24 Zeilen Konfigurationsaufwand…
Template-Datei default-client.inc
Client { Name = %name-fd Address = %address FDPort = 9102 Catalog = MyCatalog Password = "%pass" File Retention = %ret Job Retention = %ret AutoPrune = yes }
Hierbei ist darauf zu achten, dass man – da sed
manche Zeichen
anders interpretiert – manche Zeichen escapen muss. Da der Parser von Bacula
jedoch auch escaped, muss man sogar doppeltes Escaping vornehmen:
@"|sed 's/%name/codebox/g;s/%address/codebox/g;s/%ret/2 weeks/g;s/%pass/password mit \\/ slash/g' /etc/bacula/default-client.inc"
Dieser Aufruf entspricht dem Passwort „password mit / slash”.
Template-Datei default-device.inc
Device { Name = %name-files Media Type = File Archive Device = /raid/%name LabelMedia = yes Random Access = Yes AutomaticMount = no RemovableMedia = no AlwaysOpen = no }
Natürlich klappt diese Technik auch beim Storage Daemon, sodass man sich hier – je nach Setup – auch wieder enorm viele Zeilen sparen kann.
Include-Datei default-fs-exclude-linux.inc
Wenn wir gerade beim Einbinden von Dateien sind, ist es auch sinnvoll, die standardmäß auszulassenden Files auszulagern:
File = /proc File = /tmp File = /.journal File = /.fsck File = /media File = /mnt File = /sys File = /lost+found
Include-Datei default-fs-exclude-mac.inc
File = /Volumes File = /tmp File = /private/tmp File = /cdrom File = /automount File = /Network File = /.vol
Template-Datei default-job.inc
Job { Name = "%name" Type = Backup Client = %name-fd FileSet = "%name-set" Schedule = "%name-sched" Storage = %name-storage Messages = Standard Priority = 10 Write Bootstrap = "/raid/%name/bootstrap" Pool = %name }
Diese Datei fügt quasi die anderen Dateien zusammen und hat die größte Ausbeute, was Zeilen und Ersetzungen angeht.
Template-Datei default-storage.inc
Storage { Name = %name-storage # Use VPN address here to enable clients connecting via VPN to back up Address = fs.vpn SDPort = 9103 Password = "secret" Device = %name-files Media Type = File }
Template-Datei/Script default-fs.inc/default-fs.sh
# Variable FileSet-Definition # # Parameters: # %name - name of the machine to be backed up # %compression - leave blank or set to 'compression = gzip' # %mac - leave blank or set to 'hfsplussupport = yes' # %os - set mac or linux or windowsFileSet { Name = “%name-set” Include { Options { signature = MD5 %compression %mac } File = / %extrafiles } Exclude { @/etc/bacula/default-fs-excludes-%os.inc } }
Da die Konfiguration des Filesets etwas umfangreicher werden kann, habe ich sie in den meisten Fällen im gewohnten Format gelassen. Allerdings konnte ich die Hälfte der Konfigurationen abstrahieren, auch wenn das aufwändiger ist als bisher. Damit die Zeilen nicht so lang werden, habe ich folgendes Script dazu gebaut:
#!/bin/sh # Returns a default FileSet-resource # Syntax: default-fs.sh <name> <os> [compression] [extra-files][ "${2}" = "mac" ] && mac="hfsplussupport = yes" [ ! -z "${3}" -a "${3}" = "yes" ] && comp="compression = gzip" extra=${@:4} sed "s/%name/${1}/g;s/%compression/${comp}/g;s/%mac/${mac}/g;s/%os/${2}/g;s/%extrafiles/${extra}/g" /etc/bacula/default-fs.inc
Eingebunden wird das Script folgendermaßen:
@"|/etc/bacula/default-fs.sh ibook mac yes" @"|/etc/bacula/default-fs.sh tv linux yes" @"|/etc/bacula/default-fs.sh fs linux"I run a blog since 2005, spreading knowledge and experience for almost 20 years! :)
If you want to support my work, you can buy me a coffee.
Thank you for your support! ❤️