weidner/archives/2012/12/

CFEngine 3 Multiple Environments Syntax Check

Ich verwende schon seit vielen Jahren CFEngine 2 um Server einheitlich zu konfigurieren. Seit 2008 gibt es nun die neue Version CFEngine 3, mit der sich etliche Aufgaben leichter erledigen lassen, die eine umfangreiche Standardbibliothek mitbringt und vor allem inkompatibel zu Version 2 ist.

Dieses Jahr habe ich mir das Buch Learning CFEngine 3 von Diego Zamboni besorgt und begonnen mich mit der neuen Version vertraut zu machen.

Natürlich ist das Arbeiten mit CFEngine erheblich leichter geworden, Fehler sind aber immer noch möglich. Darum geht nichts über einen guten Workflow, der Fehler begrenzt und sie möglichst zeitig beheben läßt.

Multiple Environments

In Kapitel 6 seines Buches schlägt Diego Zamboni eine Konfiguration mit verschiedenen CFEngine-Umgebungen für die Entwicklung von Regeln, das Testen und den Produktiveinsatz vor. Das funktioniert so, dass je nachdem, welcher Umgebung ein Rechner zugeordnet wurde, CFEngine seine Regeln aus dem dieser Umgebung entsprechenden Verzeichnis einliest.

Die genaue Funktionsweise ist detailliert im Buch beschrieben, hier dazu nur soviel, dass in der Datei promises.cf eine Datei aus dem Umgebungsverzeichnis eingelesen wird und dann die Kontrolle übernimmt:

body common control
{
 inputs => { 
   "cfengine_stdlib.cf", 
   "environment_$(environments.active)/env_promises.cf",
 };
 bundlesequence => {
   "environments",
   "main",
   "env_main",
 };
 ...
}

Wesentlich ist das Bundle environments, in dem die Variable active gesetz wird.

Das funktioniert über Klassen, die normal von CFEngine anhand beliebiger Kriterien gesetzt werden. Die Variable active wird dann von der spezifischsten Klasse überschrieben:

bundle common environments
{
 classes:
  "environment_development" or => {
    "devoppc",
  };
  "environment_testing"     or => {
    "testserver",
  };
  "environment_production"  or => {
    "ipv4_192_168_1",
  };
 vars:
  any::
   "active" string => "none", policy => "overridable";
  environment_production::
   "active" string => "production", policy => "overridable";
  environment_testing::
   "active" string => "testing", policy => "overridable";
  environment_development::
   "active" string => "development", policy => "overridable";
}

Hier ist die Reihenfolge bei vars wichtig, und dass die Auswahlkriterien immer spezifischer werden.

Syntaxcheck

In einem Thread in den CFEngine Forums ist beschrieben, wie man die gesamte CFEngine-Konfiguration syntaktisch testen kann, nämlich:

$ cf-promises -f ./promises.cf

Das funktioniert unabhängig davon, wo sich die zu überprüfende Konfiguration befindet. Insbesondere auch, wenn die Konfiguration via Versionskontrollsystem ausgecheckt wurde. Wichtig ist, dass die Option -f verwendet wird und promises.cf ein ./ vorangestellt wird.

Nun ergibt sich bei der Konfiguration mit multiplen Umgebungen aber das Problem, das cf-promise genau eine Umgebung auswählt und auch nur diese prüft, nämlich die für den Rechner, auf dem cf-promises gerade läuft, gültige.

Um auch die Syntax der anderen Umgebungen zu testen, kann ich Klassen über die Kommandozeile definieren oder unterdrücken. Das hat den Vorteil, dass ich damit ich der Lage bin, unabhängig vom Rechner die gewünschte Umgebung zu testen. Da die Kommandozeile für cf-promise nun sehr lang wird, schreibe ich ein Makefile für die Tests.

# CHECKVERBOSE  = -v
CHECKVERBOSE  =
# 'make check' checks the config for the local system
check:
        cf-promises $(CHECKVERBOSE) -f ./promises.cf

check_development:
        cf-promises $(CHECKVERBOSE) -D environment_development -f ./promises.cf

check_testing:
        cf-promises $(CHECKVERBOSE) -N environment_development \
                    -D environment_testing -f ./promises.cf

check_production:
        cf-promises $(CHECKVERBOSE) \
                    -N environment_development,environment_testing \
                    -D environment_production -f ./promises.cf

check_none:
        cf-promises $(CHECKVERBOSE) \
        -N environment_development,environment_testing,environment_production \
        -f ./promises.cf

Nun kann ich mit make check die Syntax der für diesen Rechner gültigen Konfiguration überprüfen. Mit make check_development überprüfe ich die Konfiguration unter environment_development und analog für die anderen Umgebungen.

Weiterhin habe ich die Möglichkeit, durch Aufruf von

$ make CHECKVERBOSE=-v check

cf-promises ausführliche Informationen zu entlocken.

Posted 2012-12-19
Tags: