Yabu ist parallelisierbar, d.h. bei entsprechender Konfiguration kann Yabu versuchen, verschiedene Ziele gleichzeitig zu erreichen. Das geht natürlich nur für Ziele, die nicht voneinander abhängen, letzteres kommt aber häufig vor. Wird zum Beispiel ein Programm aus 5 Objektdateien erzeugt, dann sind die 5 Objekte in der Regel unabhängig voneinander und können parallel kompiliert werden. Auf einem Mehrprozessorsystem oder einem Verbund aus mehreren Rechnern kann man so die Kompilierzeiten eines Projektes verkürzen.
Ein zweiter Aspekt der Parallelisierung sind Multi-Platform-Projekte, die gleichzeitig auf verschiedenen Plattformen oder für unterschiedliche Laufzeitumgebungen kompiliert werden müssen. Mit Hilfe von Prototyp-Regeln, Konfigurationen und konfigurationsabhängigen Variablen lassen sich solche Projekte effizient in einem einzigen Buildfile beschreiben und Redundanzen auf ein Minimum beschränken. Das ist jedoch nur der erste Schritt. Ein kompletter Build erfordert in der Regel die Kompilierung auf verschiedenen Plattformen – ein Prozeß, der nach Automatisierung verlangt.
Die Parallelisierung des Buildprozesses ist mit Yabu in mehreren Abstufungen realisierbar. Allen gemeinsam ist die Annahme, daß ein Verbund von Rechnern als Build-Platformen zur Verfügung steht, die alle eine gemeinsame Sicht auf das Dateisystem haben und Benutzer auf allen Rechner einheitlich eingerichtet sind. Insbesondere gibt es ein globales Konfigurationsverzeichnis, auf das alle Rechner unter dem gleichen Namen Zugriff haben. Damit sind folgende Szenarien denkbar:
Lokale Parallelisierung, zum Beispiel zur Ausnutzung von Mehrprozessorsystemen. Hierbei arbeitet Yabu wie gewohnt, führt aber Skripte bis zu einer gewissen Anzahl gleichzeitig aus. Der Parallelisierungsgrad wird in der globalen Konfigurationsdatei für jeden Rechner festgelegt.
Verteilte Ausführung von Skripten. Hierbei verteilt Yabu die Skriptausführung auf alle passenden Rechner im Verbund. "Passend" heißt zum Beispiel, daß eine Linux-Übersetzung nur auf Linux-Rechner erfolgt, und nicht etwa unter FreeBSD. Die Auswahl der passenden Rechner erfolgt über eine Konfiguration, die jedem Rechner zugeordnet ist.
Multi-Platform-Build. Dies ist lediglich ein kleine Erweiterung der verteilten Ausführung. In einem einzigen Yabu-Lauf wird dabei die Anwendung für mehere Plattformen und Umgebungen kompiliert. Dabei spielt es keine Rolle, auf welchem Rechner der Benutzer Yabu startet. Für jedes Skript wählt Yabu automatisch einen passenden Rechner zur Ausführung aus. So läßt sich beispielsweise die BSD-Variante problemlos – und für den Benutzer transparent – von einem Linux-Rechner aus kompilieren.
Wie oben bereits erwähnt, benötigt Yabu für die parallelisierte Skriptausführung ein globales Konfigurationsverzeichnis, dessen Name beim Aufruf mit der Option -a übergeben wird. Beispiel:
yabu -g /usr/local/yabu all
Den Verzeichnisnamen bei jedem Aufruf von Yabu einzugeben, wäre natürlich mühsam. In der Regel wird es hierfür ein Skript oder ein Shell-Alias geben.
Das Konfigurationsverzeichnis enthält unter anderem die Datei yabu.cfg
,
die Yabu beim Start auswertet. Außer allgemeinen Einstellungen
(siehe Globale Konfigurationsdatei (yabu.cfg)) enthält die Datei den Abschnitt !servers
mit Beschreibungen aller Rechner im Verbund.
Im folgenden Beispiel besteht der Verbund aus drei Rechnern:
!servers host frodo max=2 host gandalf max=5 host gimli max=2
Der Parameter max
gibt an, wieviele Skripte parallel ausgeführt werden sollen.
Er richtet sich nach der Leistungsfähigkeit der Rechner, insbesondere nach der
Anzahl von Prozessoren bzw. Prozessorkernen.
Mit der obigen Beispielkonfiguration ist noch nicht viel erreicht. Immerhin kann Yabu nun die vorhandenen CPU-Resourcen ohne Hilfestellung durch den Benutzer sinnvoll ausnutzen. Der nächste Schritt ist, jedem Rechner eine Konfiguration zuzuordnen. Wir nehmen an, daß zwei der Rechner unter Linux und einer unter FreeBSD läuft:
!options platform(linux freebsd) !servers host frodo max=2 cfg=linux host gandalf max=5 cfg=linux host gimli max=2 cfg=freebsd
Der !options-Abschnitt entspricht der !options-Anweisung im Buildfile
(siehe Optionen) – mit dem kleinen Unterschied, daß hier die
Einrückung nicht zwingend erforderlich ist.
Durch den cfg
-Parameter legt man fest, für welche Konfiguration(en) die
einzelnen Rechner Skripte ausführen können.
Zum Beispiel kann der Rechner gandalf Skripte in der Konfiguration +linux oder
+linux+debug ausführen. Dagegen würde Yabu mit einer Fehlermeldung reagieren,
wenn man versucht ein Skript für die Konfiguration +freebsd auszuführen.
Die Konfigurationsangabe bewirkt also einen gewissen Schutz vor Fehlern
im Buildfile oder beim Aufruf von Yabu.
Der wahre Nutzen erschließt sich aber erst, wenn wir die verteilte Skriptausführung zulassen. Voraussetzung hierfür ist, daß auf jedem der Rechner ein Yabu-Server läuft (Details siehe unten). In der Konfiguration wird dies durch einen Doppelpunkt hinter dem Hostnamen kenntlich gemacht:
!options platform(linux freebsd) !servers host frodo: max=2 cfg=linux host gandalf: max=5 cfg=linux host gimli: max=2 cfg=freebsd
Damit werden die Rechner zu einem echten Verbund: unabhängig davon auf welchem Rechner man Yabu startet, können Skripte auf allen drei Rechnern ausgeführt werden. Yabu verbindet sich dazu via TCP mit den jeweiligen Serverprozessen, übergibt die auszuführenden Skripte an den Server und empfängt als als Antwort die Ausgaben des Skriptes. Für den Benutzer ist das weitegehnd transparent; er hat den Eindruck als würden alle Skripte lokal ausgeführt. Da sich nun alle Konfigurationen auf allen Rechnern erzeugen lassen, verliert die statische Auswahl der Plattform ihren Sinn. Stattdessen kann man eine Regel definieren, die alle Konfigurationen in einem einzigen Yabu-Aufruf erzeugt:
all: all-linux all-freebsd all-%: build/%/prog1 build/%/prog2 ...
Wie im obigen Beispiel gezeigt, definiert man in der Konfigurationsdatei für jeden Rechner mit "cfg=..." eine Konfiguration. Sie beschreibt, für welche Konfigurationen der Rechner Skripte ausführen kann. Wird ein Skript ausführbereit, dann ermittelt Yabu alle Server, deren Konfiguration kompatibel – im Sinne von Konfigurationen – zur aktuellen Konfiguration ist. Einer dieser Server erhält das Skript zur Ausführung. Beispiel: die Konfiguration "linux" des Servers frodo (siehe oben) ist kompatibel zu "" (leere Konfiguration) und "+linux" und "+linux+debug", nicht aber zu "+freebsd".
Die lokale Konfiguration und "_local"
In der Regel ist der Rechner, auf dem Yabu läuft, in yabu.cfg als Server definiert und hat somit eine Serverkonfiguration. Man beachte daß diese "lokale Konfiguration" unabhängig von der Startkonfiguration ist, die Yabu bei jedem Programmlauf festlegt (siehe Auswahl der Konfiguration). Insbesondere kann es vorkommen, daß die lokale Konfiguration nicht kompatibel zur Startkonfiguration ist. Das ist kein Fehler, sondern führt lediglich dazu, daß Yabu alle Skripte auf anderen Servern ausführt. Ein Beispiel, wobei wieder die obige Konfigurationsdatei vorausgesetzt wird: ruft man auf dem Rechner frodo Yabu mit
>frodo# **yabu -c freebsd**
auf, dann ist die Startkonfiguration "+freebsd" (zuzüglich weiterer Startoptionen aus dem Buildfile), die lokale Konfiguration gemäß yabu.cfg ist aber "+linux". Yabu würde deshalb alle Skripte auf derm Server gimli ausführen.
Aus diesem Grunde hat die Startkonfiguration und damit die !configure
-Anweisung
in einem Rechnerverbund nur noch geringe Bedeutung.
Man kann sie nach wie vor verwenden, um nicht plattformspezifische Optionen
global ein- und auszuschalten.
Die lokale Konfiguration kann man im Buildfile über die Systemvariable
$(_LOCAL_CFG) ermitteln.
Wurde Yabu ohne -g gestartet oder enthält yabu.cfg keinen Eintrag für
den ausführenden Rechner, dann ist der Wert der Variable ein leerer String.
Die lokale Konfiguration enthält – zusätzlich zu den Optionen aus yabu.cfg – immer die Option "+_local". Alle Server erhalten dagegen die Option "-_local". Damit ist es möglich, die lokale Ausführung von Skripten zu erzwingen, und zwar unabhängig davon, auf welchem Rechner Yabu läuft.
Der Aufbau eines Rechnerverbundes wie im vorigen Abschnitt beschrieben stellt gewisse Anforderungen an die Infrastruktur.
Alle beteiligten Rechner müssen über ein IP-Netzwerk verbunden sein
Alle Rechner müssen eine einheitliche Sicht auf das Dateisystem haben. Genauer gesagt, das Verzeichnis, in dem Yabu gestartet wird und das globale Konfigurationsverzeichnis müssen überall unter dem gleichen Namen erreichbr sein. Typischerweise wird das über NFS realisiert.
Benutzer müssen auf allen Rechnern einheitlich eingerichtet sein, insbesondere mit gleichem Namen und Benutzer-Id. Das ist für die Authentisierung gegenüber dem Yabu-Server erforderlich.
Das globale Konfigurationsverzeichnis muß ein Unterverzeichnis
namens auth
enthalten, in dem alle Benutzer Dateien anlegen können.
Falls möglich, sollte das Verzeichnis so eingerichtet sein, daß ein
Benutzer keine Dateien anderer Benutzer umbenennen oder löschen kann
(wie normalerweise das Verzeichnis /tmp).
Sind diese Voraussetzungen erfüllt, dann ist der nächste Schritt die
Erstellung der Datei yabu.cfg
im Konfigurationsverzeichnis. Sie
sollte für normale Benutzer nur lesbar sein.
Abschnitt !settings
Der Abschnitt enthält globale Programmeinstellungen, siehe Programmeinstellungen. Beispiel:
!settings max_warnings=5
Abschnitt !options
Dieser Abbschnitt hat das gleiche Format wie die !options
-Anweisung im Buildfile.
In ihm werden globale Optionen definiert, insbesondere die Optionen, die in den
Konfigurationsangaben im !servers
-Abschnitt benutzt werden.
Beispiel:
!options os(linux freebsd win32) subtype(debug release)
Abschnitt !servers
Im Abschnitt !servers
legt man Parameter für die einzelnen Rechner fest.
Er besteht aus einer host
-Zeile pro Rechner, die eines der folgenden
Formate hat:
host gandalf Parameter host gandalf: Parameter host gandalf:gandalf-if1 Parameter host gandalf:gandalf-if1:12345 Parameter host gandalf::12345 Parameter
Die erste Form definiert lediglich Parameter für einen Rechner. Alle anderen Formen (mit Doppelpunkt hinter dem Hostnamen) bezeichnen einen Yabu-Server, also einen Rechner auf dem der Yabu-Serverprozeß läuft. Neben dem Hostnamen kann man eine IP-Adresse und/oder eine Portnummer angeben, auf der der Server TCP-Verbindungen annimmt. Ohne die entsprechenden Angaben benutzt der Server den Port 6789 und nimmt Verbindungen auf allen lokalen IP-Adressen an.
Parameter ist eine Liste von Elementen der Form Name=Wert. Die erlaubten Parameter sind:
max |
Maximale Anzahl parallel ausgeführter Kommandos. Ein sinnvoller Wert ist das Zweifache der CPU-Zahl. |
config |
String (Default: "").
Legt eine Konfiguration fest, für die der Server Skripte ausführen kann.
|
prio |
Zahl (Default: 1). Ermöglicht eine gewisse Kontrolle über die Verteilung von Skripten auf die einzelnen Rechner Rechner mit höherer Priorität werden bevorzugt ausgewählt |
Auf jedem Yabu-Server muß ein Serverprozeß laufen. Dabei handelt es sich um die gleiche ausführbare Datei wie yabu, nur wird sie unter dem Namen yabusrv gestartet. Die allgemeine Syntax ist
yabusrv -g CfgDir -S Shell -qvV?
wobei die Optionen die gleiche Bedeutung wie für Yabu haben (siehe Kommandozeile). Es ist wichtig, daß Server und Clients das gleiche Konfigurationsverzeichnis verwenden, denn darauf basiert der Verbindungsaufbau (TCP-Port in yabu.cfg) und die Authentisierung.
Der Server muß als Benutzer "root" gestartet werden, damit er Kommandos im Auftrag eines beliebigen Benutzers unter dessen Idenitität ausführen kann.
Fehlermeldungen gibt der Server über den syslog-Dienst aus,
er benutzt dabei die ``Facility'' LOG_USER
.
Wenn ein Skript auszuführen ist, wählt Yabu zunächst die Server aus, die dafür in Frage kommen. Die Auswahl basiert auf der aktuellen Konfiguration (AKT) und den Konfigurationen, welche in yabu.cfg den einzelnen Servern zugeordnet sind (SRV). Ein Server wird ausgewählt, wenn SRV in AKT enthalten ist. Das heißt, jede Option, die in SRV einen definierten Wert (+ oder -) hat, muß den gleichen Wert in AKT haben. Hierzu einige Beispiele:
AKT |
SRV |
Ergebnis |
---|---|---|
+linux |
ausführbar |
|
+linux |
+freebsd |
nicht ausführbar |
+linux+debug |
+linux |
ausführbar |
+linux-database |
+linux |
nicht ausführbar |
Außer auf den in yabu.cfg aufgeführten Servern kann Yabu Skripte auch selbst
("lokal") ausführen, also genauso wie im serverlosen Modus ohne -g.
Dabei kommt es darauf an, ob der Rechner, auf dem yabu läuft, in yabu.cfg
aufgeführt ist oder nicht.
Enthält yabu.cfg eine host
-Zeile für den Rechner, dann bestimmt der
dort angegebene Parameter config
, welche Skripte lokal ausführbar sind.
Andernfalls sind alle Skripte lokal ausführbar.
Server haben immer Vorrang vor der lokalen Ausführung. Ist zum Beispiel ein Skript auf 3 Servern und lokal ausführbar, dann versucht Yabu zuerst, es auf einem der Server auszuführen. Nur wenn keiner der Server verfügbar ist, wird das Skript lokal ausgeführt.
Manchmal stört es, daß sich nicht genau voraussagen läßt, auf welchem
Server Yabu ein bestimmtes Skript ausführt.
Insbesondere bei der Fehlersuche wünscht man sich manchmal,
daß Skripte nur lokal ausführt werden.
Yabu bietet hierfür eine spezielle Programmeinstellung:
use_server=no
(oder auf der Kommandozeile: -j
) bewirkt,
daß Yabu keinen Server anruft und Skripte nur noch lokal ausführt.
Dabei bleiben alle Konfigurationsregeln weiter gültig.
use_server=no
bedeutet also nicht, daß Yabu nun Skripte
ausführt, die nicht zur lokalen Konfiguration passen.
Vielmehr muß der Benutzer darauf achten, nur solche Ziele vorzugeben,
die in der lokalen Konfiguration erreichbar sind;
andernfalls tritt ein Fehler auf.
Man kann das auch so formulieren:
use_server=no
simuliert, daß alle Server ausgefallen sind.