profile picture

Michael Stapelberg

Kurz-Howto: Baculas Konfiguration stark vereinfachen (2007)

published 2007-12-16, last modified 2018-03-18
Edit Icon

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 windows

FileSet { 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! ❤️