weidner/archives/2013/02/

CFEngine 3 Konfiguration aus Monotone Repository

Diego Zamboni beschreibt in Kapitel 6 seines Buches Learning CFEngine 3, wie man die Konfiguration für CFEngine in einem Git-Repository verwalten kann.

Da ich mehr dem Versionsverwaltungssystem monotone zugeneigt bin, habe ich die Anregung aus dem Buch dahingehend modifiziert.

Arbeitsablauf

Arbeitsablauf

Bei dem Arbeitsablauf mit monotone Repository ändert der Administrator die Konfiguration in seinem Arbeitsverzeichnis und überprüft die Syntax (zum Beispiel, wie in diesem Artikel beschrieben). Wenn er mit seinen Änderungen zufrieden ist, schiebt er seine Änderungen mit

$ mtn commit
$ mtn sync

auf den monotone Server. Von dort holt sich der CFEngine Policy Hub die Änderungen automatisch mit der unten beschriebenen Konfiguration.

Der monotone Server läuft auf dem selben Rechner wie der Policy Hub, so dass es keinen zusätzlichen Netzverkehr gibt, wenn CFengine aller fünf Minuten die Repositories abgleicht.

Einrichten von monotone

Machen wir uns nun an die Umgebung für die Versionsverwaltung.

Das Aufsetzen des Servers lasse ich hier aus, das würde das Thema sprengen. Auf Debian oder Ubuntu Systemen reicht es, das Paket monotone-server zu installieren. Die Konfiguration für den Server ist dort unter /etc/monotone zu finden.

Als erstes lege ich eine Datenbank und einen Schlüssel für den CFEngine Policy Hub an und nehme die bereits vorhandene Konfiguration auf:

# cd /var/cfengine/masterfiles
# mkdir .monotone
# mtn --db .monotone/cfengine3.mtn db init
# mtn --db .monotone/cfengine3.mtn \
      --branch net.example.cfengine3 \
      setup .
# echo .monotone > .mtn-ignore
# mtn --keydir .monotone/keys genkey cfengine3@example.net
# mtn pubkey cfengine3@example.net

Den öffentlichen Schlüssel mache ich dem monotone Server bekannt und gestatte diesem Schlüssel Lesezugriff auf den Zweig net.example.cfengine3. Um die initiale Version der Dateien auf den monotone Server zu bekommen, gebe ich dem Schlüssel zunächst auch Schreibzugriff auf das Repository des monotone Servers. Nun kann ich die vorhandene CFEngine Konfiguration übernehmen.

# mtn add *.cf
# mtn commit -m Initial
# mtn push localhost net.example.cfengine3

Nun kann ich am monotone Server die Schreibrechte für den Schlüssel cfengine3@example.net entfernen. Das kontrolliere ich mit

# mtn pull
# mtn sync

Der erste Befehl sollte fehlerfrei durchlaufen, der zweite sollte einen Fehler denied ... write permission bringen.

Da der Befehl mtn pull später automatisch laufen soll, muss ich das Kennwort des Schlüssels ablegen. Dazu editiere ich die Datei _MTN/monotonerc und füge die folgenden Zeilen ein:

function get_passphrase(keypair_id)
    return "kennwort"
end

Statt kennwort natürlich das beim Erzeugen verwendete. Ab jetzt sollte der Befehl mtn pull ohne Kennwortabfrage funktionieren. Da dieser Schlüssel keine Schreibrechte auf dem monotone Server besitzt, und mit ihm auch keine weiteren Revisionen unterschrieben werden, sehe ich hierin auch kein Sicherheitsproblem.

Auf dem monotone Server erteile ich dem Schlüssel des Administrators, noch Lese- und Schreibrechte für den Zweig net.example.cfengine3 und kann nun den im Bild beschriebenen Ablauf bereits umsetzen. Allerdings muss ich nach jeder Änderung noch auf dem Server des Policy Hub im Verzeichnis /var/cfengine/masterfiles den Befehl mtn pull --update von Hand aufrufen. Hier kommt nun die aus dem Buch von Diego Zamboni adaptierte Konfiguration von CFEngine zum Einsatz.

Automatisches Aktualisieren der Masterfiles

Prinzipiell ist es möglich, durch cron in regelmäßigen Abständen im Verzeichnis /var/cfengine/masterfiles den Befehl mtn pull --update aufzurufen.

Wenn der Befehl aber CFEngine 3 selbst aufgerufen werden soll, kann man ihn zum Beispiel in der Datei failsafe.cf in der Sektion commands: des Bundles update() unterbringen. Dort füge ich das folgende hinzu:

  am_policy_hub::

   "/usr/bin/mtn pull --update --quiet"
      contain => u_in_dir("$(master_location)"),
      comment => "Update $(master_location) from monotone repository",
       handle => "update_commands_get_masterfiles_from_monotone";

Und ausserdem noch am Ende der Datei:

body contain u_in_dir(s)
{
 chdir => "$(s)";
}

Die Klasse am_policy_hub ist nur auf dem Policy Hub aktiv, folglich wird monotone nur auf diesem Server aufgerufen. Mit dem body u_in_dir() wird dafür gesorgt, dass monotone im Verzeichnis mit den Masterfiles aufgerufen wird.

Abweichend zu Diego Zambonis Vorschlag habe ich keine Zeitscheiben für die Aktualisierung gewählt, weil ich die Änderungen so schnell wie möglich haben wollte. Normalerweise arbeitet CFEngine die Konfiguration aus failsafe.cf aller fünf Minuten ab.

Posted 2013-02-25
Tags: