Puppet im Detail
Dieser Abschnitt beschreibt die wichtigsten Details, die im Umgang mit Puppet zu beachten sind. Weitere Informationen zu Puppet findet man in der offziellen Puppet-Dokumentation. Hier sind für einen Überblick besonders die Einleitung und der Language Guide, und zum Nachschlagen die Type Reference empfehlenswert.
Am einfachsten ist es für Department-Admins, sich beim Befüllen der eigenen Module an den bereits existierenden Modulen der Arbeitsgruppe Angewandte Bioinformatik (ABI) zu orientieren. Idealer Weise beachtet man dabei auch den Styleguide der Uni Stanford.
Datei-Übersicht
Die folgende Übersicht gibt an, welche Dateien von den Department-Admins editiert werden müssen, wenn das Git-Repository puppet nach $pp ausgecheckt wurde und $wg für das Arbeitsgruppen-Kürzel steht. Die Dateinamen können auch der Grafik unter Setup-Übersicht entnommen werden.
| Basispfad | Dateiname | Inhalt/Zweck |
|---|---|---|
$pp/etc/modules/ | $wg_baseconfig/manifests/$wg_baseconfig_ubuntu.pp | Puppet-Modul $wg_baseconfig (Modulteil für Ubuntu); enthält Konfigurationsdirektiven, die für alle Nodes des Arbeitsbereichs gelten |
$pp/etc/modules/ | $wg_desktopconfig/manifests/$wg_desktopconfig_ubuntu.pp | Puppet-Modul $wg_desktopconfig (Modulteil für Ubuntu); enthält Konfigurationsdirektiven, die für alle Desktopnodes (X11/Gnome) des Arbeitsbereichs gelten |
$pp/etc/modules/ | $wg_serverconfig/manifests/$wg_serverconfig_ubuntu.pp | Puppet-Modul $wg_serverconfig (Modulteil für Ubuntu); enthält Konfigurationsdirektiven, die für alle Servernodes des Arbeitsbereichs gelten |
$pp/etc/manifests/ | nodes/$wg_nodes.pp | Puppet-Manifest für alle physikalischen Nodes des Arbeitsbereichs. Hier muss jede Node eingetragen sein. Konfigurationsdirektiven sollten hier nicht eingetragen werden. |
$pp/etc/manifests/ | nodes/$wg_templatenodes.pp | Puppet-Manifest, das die Templatenodes $wg_basenode, $wg_desktopnode und $wg_servernode enthält. Hier müssen die Department-Admins nichts ergänzen. |
Konfigurationsbeispiele
Im Folgenden werden einige Beispiele aus den zentralen Puppet-Modulen des WSI erläutert, um den Einstieg in das Befüllen eigener Module zu vereinfachen.
File und Service
Die folgende Klasse aus dem Modul baseconfig konfiguriert den AFS-Client. Dabei wird zunächst der Puppet Type file bemüht, um drei Konfigurationsdateien aus dem AFS zu kopieren. Der Dateiname links des Zuweisungsoperators ist als Ziel auf dem Client zu verstehen, und der Dateiname rechts davon (der Parameter source des Puppet Types file) gibt an, von woher die Datei kopiert wird. Es fällt auf, dass weder der Besitzer der Datei noch die Dateirechte angegeben sind. In solchen Fällen erhalten die Dateien auf den Client Defaultwerte, die global in $pp/etc/manifests/site.pp definiert sind.
class afs {
file {
"/etc/openafs/CellServDB": source => "/afs/wsi/common/etc/CellServDB";
"/etc/openafs/ThisCell": source => "/afs/wsi/common/etc/ThisCell";
"/etc/openafs/CellAlias": source => "/afs/wsi/common/etc/CellAlias";
}
service {
"openafs-client": subscribe => [ File["/etc/openafs/CellServDB"],
File["/etc/openafs/ThisCell"],
File["/etc/openafs/CellAlias"] ],
}
}
Der Puppet Type service wird verwendet, um den eigentlichen AFS-Dienst auf dem Client zu verwalten. Der Name in Anführungszeichen ist als Name des Dienstes zu verstehen. Hierbei wird deutlich, dass das Puppet-Modul distributionsspezifisch sein muss, denn die Bezeichnung der Dienste variiert unter den einzelnen Distributionen. Auch für den Puppet Type service existieren Defaultwerte. Gibt man nichts anderes an, soll der Dienst immer aktiviert sein. Der Parameter subscribe gibt an, dass der AFS-Client bei Änderungen der angegebenen File-Ressourcen neu gestartet werden soll. Man sieht an diesem kleinen Beispiel, dass sich hinter wenigen Konfigurationsdirektiven schon viel verbergen kann.
File mit $basepath/$modulename
Der source-Parameter aus dem oben aufgeführten Beispiel ist eher eine Ausnahme. Viel häufiger verweist der source-Parameter in den Puppet-Modulen auf $basepath/$modulename. Dabei handelt es sich um das Git-Repository für Konfigurationsfiles, und $basepath steht für den Pfad /afs/wsi/wsi/git-environment/puppet/files/<distribution>. Die Konfigurationsfiles sind also zunächst nach Distribution sortiert. Darunter liegen Unterverzeichnisse mit dem Modulnamen $modulename, wie bspw. baseconfig, ab_baseconfig oder dm_desktopconfig. In den meisten Fällen sind die Konfigurationsfiles im Git-Repository zu finden, nur in wenigen Ausnahmen sind sie an anderen Stellen im AFS untergebracht. Die folgende Klasse aus dem Modul baseconfig zeigt $basepath/$modulename anhand der Sendmail-Konfiguration im Beispiel:
class sendmail {
service { "sendmail": subscribe => File["/etc/mail/sendmail.mc"] }
package {
"sendmail": ;
"sendmail-cf": ;
}
file { "/etc/mail/sendmail.mc":
source => "${basepath}/${modulename}/sendmail/sendmail.mc",
require => [ Package["sendmail"],
Package["sendmail-cf"] ];
}
}
Man sieht hier wieder den bereits bekannten Puppet Type service, der Sendmail neu startet, wenn sich die Datei /etc/mail/sendmail.mc ändert. Neu ist der Puppet Type package, über den mit Hilfe eines Paketmanagers Pakete installiert werden. Der package-Type besitzt wie service und file Defaultwerte, weshalb außer dem Paketnamen nichts weiter angegeben ist. In diesem Fall ist bei Ubuntu das Frontend aptitude anstelle von apt-get als Default für die Paketverwaltung APT gesetzt. Der Puppet Type file verwendet hier den Parameter require. Damit wird erreicht, dass die Pakete sendmail und sendmail-cf installiert sind, bevor die Datei /etc/mail/sendmail.mc auf den Client kopiert wird. Durch require (bei file) und subscribe (bei service) ergibt sich folgende unveränderliche Abfolge: Installation der Sendmail-Pakete, Kopieren der Sendmail-Konfigurationsdatei, Neustart von Sendmail.
Exec
Neben den bereits oben verwendeten Puppet Types file, service und package existieren noch zahlreiche weitere für viele unterschiedliche Zwecke. Trotzdem ist es manchmal unumgänglich, auf den Clients einen Befehl auszuführen, der nicht durch einen Puppet Type bereitgestellt wird. Für solche beliebigen Befehle wird der Puppet Type exec verwendet. Dabei muss beachtet werden, dass ein mit exec definierter Befehl ohne Unterlass wiederholt wird, sofern dies nicht durch geeignete Parameter verhindert wird. Im folgenden Beispiel wird mit exec ein symbolischer Link angelegt, sofern dieser noch nicht existiert, wofür der Parameter unless verwendet wird:
exec { "/bin/ln -sf /etc/ldap.conf /etc/ldap/ldap.conf":
unless => "/usr/bin/test -L /etc/ldap/ldap.conf";
}
Neben dem Parameter unless existieren u.a. auch der Parameter onlyif und creates. Der Parameter creates gibt an, dass ein Befehl eine Datei erzeugt. Der Befehl wird in diesem Fall nur ausgeführt, wenn die Datei noch nicht existiert. Der Parameter onlyif wird in folgendem Beispiel verwendet, in dem ein symbolischer Link nur dann angelegt wird, wenn er noch nicht existiert. Unless und onlyif sind natürlich in gewisser Weise redundant. Man kann daher immer denjenigen der beiden Parameter wählen, mit dem sich die einfacher zu lesende Puppet-Direktive ergibt.
exec { "/bin/rm /etc/legal":
onlyif => "/usr/bin/test -e /etc/legal";
}
Stages
Puppet-Module und -Manifeste enthalten Konfigurationdirektiven, die eine Menge von Konfigurationszuständen eines Clients beschreiben. Dieses Stateful Configuration Management steht im Gegensatz zu skriptbasierten Werkzeugen, bei denen das Abarbeiten sequenzieller Befehle zur gewünschten Konfiguration führen soll. Um trotz des zustandsbehafteten Paradigmas Einfluss auf die Reihenfolge des Erreichens einzelner Konfigurationszustände nehmen zu können, existieren sog. Stages bzw. Run Stages. Dabei handelt es sich um frei benennbare Zustands-Sammlungen, für die eine Reihenfolge definiert wird. Puppet stellt dann sicher, dass alle Konfigurationszustände einer Stage erreicht sind, bevor zur nachfolgenden Stage übergegangen wird.
Für die Zuweisung von Puppet-Klassen zu Stages existiert am Anfang jeder Moduldatei eine besondere Klasse, die ausschließlich diese Zuweisungen beinhaltet. Folgende Klasse weist bswp. die Konfiguration der Sendmail-Aliase und die CUPS-Konfiguration jeweils der Stage main zu:
class {
"aliases": stage => main;
"cups": stage => main;
}
Für die Module der Arbeitsbereiche ist vorgesehen, dass sie lediglich eine einzige Stage verwenden, und zwar die Stage main. Diese sollte für die arbeitsbereichspezifischen Konfigurationen ausreichen. Falls Arbeitsbereiche ihre Konfigurationsdirektiven doch in mehrere Stages aufteilen möchten, so ist dies grundsätzlich möglich, sollte aber vorher mit puppet-admin abgesprochen werden.