Das wohl wichtigste Merkmal von eisfair ist die für alle Pakete einheitliche Konfiguration. Deshalb ist die Nutzung der eisfair-Konfigurationsschicht eine absolute Voraussetzung für ein eisfair-Paket.
Im Folgenden wird der Aufbau einer solchen eisfair-Konfigurationsdatei sowie die damit zusammenhängenden Mechanismen beschrieben.
Die aktuelle Konfiguration eines Pakets wird immer in der Datei /etc/config.d/$package gespeichert. Der Aufbau der Konfigurationsdateien ist weiter unten detailiert beschrieben.
Diese Datei wird bei einem eisfair-Paket nicht mitgeliefert, da diese bei der Installation eine eventuell bereits vorhandene Konfiguration, einer vorher installierten Version des Pakets überschreiben würde. Bei einer Erstinstallation muss diese aber erstellt werden. Das kann z.B. durch Kopieren der Standardkonfigurationsdatei erfolgen. (Siehe auch Kapitel Paketinstallation)
Die Standardkonfigurationsdatei liegt unter /etc/default.d/$package. Diese Datei muss in einem eisfair-Paket mitgeliefert werden. In ihr muss das Paket deaktiviert sein, d.h. die Startvariable START_$PACKAGE muss auf ,,no`` gesetzt sein.
Bei jedem Editieren einer Konfiguration wird mittels ACFH (Advanced Configuration File Handling) eine Sicherheitskopie der letzten Konfiguration unter /etc/backup.d/$package erstellt. Die Verwaltung dieser Sicherheitskopien erfolgt mittels der ACFH-Funktionalität und muss nicht in jedem Paket einzeln implementiert werden.
Beispiel für eine eisfair-Konfigurationsdatei (Paket foo):
#-----------------------------------------------------------------------------
# /etc/config.d/foo - foo configuration parameters
#
# Creation: 2005-02-01 max
# Last Update: 2005-03-06 max
#
# Copyright (c) 2001-2007 the eisfair team, team(at)eisfair(dot)org
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# General settings
#-----------------------------------------------------------------------------
START_FOO='no' # start foo: yes or no
FOO_GENERAL_SETTING='60' # time for foo
FOO_ANOTHER_SETTING='Test' # text for foo
FOO_LONG_COMMNET='yes' # you can write long comments by
# using more than one line...
#-----------------------------------------------------------------------------
# Second Group
#
# You can give a detailed description of this group inside
# the comment
#-----------------------------------------------------------------------------
FOO_ARRAY_N='3' # number of elements in array
FOO_ARRAY_1_ACTIVE='yes' # is element active: yes or no
FOO_ARRAY_1_TEXT='Sample' # some text for an array element
FOO_ARRAY_1_VALUE='12345' # a number for this element
FOO_ARRAY_2_ACTIVE='no' # is element active: yes or no
FOO_ARRAY_2_TEXT='Inactive' # some text for an array element
FOO_ARRAY_2_VALUE='' # a number for this element
FOO_ARRAY_3_ACTIVE='yes' # is element active: yes or no
FOO_ARRAY_3_TEXT='Something' # some text for an array element
FOO_ARRAY_3_VALUE='999' # a number for this element
#------------------------------------------------------------------------------
# End
#------------------------------------------------------------------------------
Damit die Konfiguration mittels eines eisfair-Konfigurationseditors oder mittels Webconf bearbeitet werden kann, ist die Struktur der Konfigurationsdatei zwingend einzuhalten. Im Folgenden werden die einzelnen Blöcke näher beschrieben.
Generell werden spezielle Blöcke mittels der Trennzeilen ,,#-----`` gekennzeichnet.
Vor der eigentlichen Konfiguration steht der Kopfbereich, der im Allgemeinen der GPL-Header ist und einen Verweis auf die GPL enthält, da wohl die meisten Pakete unter der GPL stehen werden.
Am einfachsten sollte der hier angegebene Kopfbereich einfach übernommen werden und nur die relevanten Inhalte angepasst werden.
Als Fußbereich wird das Ende der Datei mit ,,# End`` gekennzeichnet.
Die gesamte Konfiguration wird in einzelne Gruppen unterteilt. Jede Gruppe wird über den Gruppenkopf näher beschrieben. Dieser wird mittels einer Trennzeile ,,#-----`` eingeleitet und abgeschlossen.
Dazwischen steht in der ersten Zeile der Gruppenname und in den Folgezeilen ein optionaler Kommentar zur gesamten Gruppe. Dort können nähere Angaben zu den in der Gruppe zu konfigurierenden Funktionen gemacht werden (aber hier noch ohne Bezug zur einzelnen Konfigurationsvariable).
Innerhalb der einzelnen Gruppen stehen die Konfigurationsvariablen. Unter diesen nimmt die Startvariable START_$PACKAGE eine Sonderstellung ein. Durch diese Variable wird das gesamte Paket aktiviert bzw. deaktiviert.
Alle anderen Variablen haben die Form $PACKAGE_OPTION, d.h. jede der Variablen bekommt als Präfix den Paketnamen. Die anderen Namensbestandteile werden mittels des Unterstrichs ,,_`` abgetrennt.
Konfigurationsvariablen werden prinzipiell durchgehend groß geschrieben.
Jede Konfigurationsvariable kann mit einem eigenen Kommentar näher beschrieben werden. Dieser Kommentar kann dabei entweder hinter der Variable stehen (mittels mindestens eines Leerzeichens plus einem Kommentarzeichen ,,#`` abgetrennt) oder in der Folgezeile. In diesem Fall muss der Kommentar mittels eines oder mehrerer Leerzeichen eingerückt sein, das Kommentarzeichen darf also nicht in der ersten Spalte stehen.
Mehrzeilige Kommentare sind möglich, dabei dürfen die Kommentarzeichen in keiner Zeile in der ersten Spalte stehen.
Um Optionen anzugeben, die in einer variablen Anzahl auftreten können, müssen mehrere Felder verwendet werden. Diese bestehen aus einer Variable, die die Anzahl der Werte angibt (FOO_ARRAY_N) und den eigentlchen Optionen (FOO_ARRAY_1_TEXT, FOO_ARRAY_1_VALUE). Diese treten dann je nach angegebener Anzahl mehrfach auf.
Um einzelne Ausprägungen auch innerhalb der Liste ausblenden zu können, ohne jedesmal die gesamte Liste umnummerieren zu müssen, empfiehlt sich die Verwendung einer Aktivierungsvariable (FOO_ARRAY_1_ACTIVE). Diese muss dann im paketspezifischen Script geprüft werden.
Mehrdimensionale Felder können in der Form FOO_ARRAY_1_SUBARRAY_2_VALUE) angegeben werden. Dazu müssen dann je Ausprägung der ersten Dimension die Anzahl der Ausprägungen der zweiten Dimension angegeben werden (FOO_ARRAY_1_SUBARRAY_N).
Sobald ein Anwender eine Konfiguration über das eisfair-Menü (über das edit-Script) geändert hat, wird diese auf Gültigkeit überprüft. Dazu wird das Programm Eischk benutzt, das im weiteren Verlauf dieses Kapitels näher beschrieben wird.
/etc/check.d/$package
/etc/check.d/$package.exp
/etc/check.d/$package.ext
In der Datei /etc/check.d/$package wird dabei die eigentliche Prüfung mit Abhängigkeiten und Feldern definiert. Dazu stehen die in /etc/check.d/base.exp definierten Regulären Ausdrücke zur Verfügung.
Sofern für die Überprüfung einer eigenen Variable die vordefinierten Ausdrücke nicht ausreichend sind, so können in der Datei /etc/check.d/$package.exp eigene Reguläre Ausdrücke definiert werden. Die Namen dieser eigenen Ausdrücke müssen dabei den Paketnamen als Präfix enthalten (Beispiel: $PACKAGE_WERTEBEREICH).
In der Datei /etc/check.d/$package.ext können mit einer Scriptsprache zudem weitergehende Prüfungen implementiert werden.
In den neueren Konfigurationseditoren (Webconf bzw. ECE) können dem Anwender weitergehende Hilfetexte angezeigt werden. Diese müssen dazu in der Datei /var/install/help/$package hinterlegt werden.
Zeilenümbrüche werden in dieser Datei mit dem Tag <br/> gekennzeichnet,
Kommentare können XML-Konform mittels <!-- Kommentar -->
eingefügt werden.
Der Hilfetext jeder einzelnen Variable wird mittels des Tags <help> in dieser Datei hinterlegt.
Diese Datei hat das Format:
Beispiel für eine eisfair-Hilfedatei (Paket foo):
<!-- #----------------------------------------------------------------------------- # /var/install/help/foo - helptexts for package foo # # Creation: 2005-02-01 max # Last Update: 2005-03-06 max # # Copyright (c) 2001-2007 the eisfair team, team(at)eisfair(dot)org # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. #----------------------------------------------------------------------------- --> <help name="FOO_GENERAL_SETTING"> Hier können Sie eine Zeitspanne für das Paket foo definieren.<br/> <br/> Default: 60 </help> <!-- Dies ist ein Kommentar --> <help name="FOO_ARRAY_%_ACTIVE"> Die Konfigurationsvariable FOO_ARRAY_%_ACTIVE dient zur Aktivierung bzw. Deaktivierung der einzelnen Einträge.<br/> <br/> Default: yes </help>
Nach erfolgreicher Prüfung der Konfiguration muss diese aktiviert (,,apply``) werden. Dieser Vorgang wird ab eisfair Version 1.1.0 vollständig im allgemeinen Edit-Script gekapselt.
Für diesen Mechanismus müssen zwei paketspezifische Dateien bereitstehen:
/var/install/config.d/$package.sh
/etc/init.d/$package
Die Datei /var/install/config.d/$package.sh dient dabei zum Generieren der Konfiguration der im Paket verwendeten Software aus der eisfair Konfigurationsdatei. Es handelt sich hier also um das Apply im eigentlichen Sinne.
ACHTUNG
Da eischk die Konfiguration nicht überprüft, wenn START_$PACKAGE='no'
gesetzt ist, darf in diesem Fall kein Neuschreiben der Konfiguration
erfolgen!
Dieses Skript muss im Erfolgfall den Wert 0 zurückgeben (exit 0). Im Fehlerfall muss ein Wert ungleich 0 zurückgegeben werden. Dies bewirkt, dass der Neustart des Basisdienstes über /etc/init.d/$package nicht ausgeführt wird.
Im Script /etc/init.d/$package muss der Befehl restart unterstützt werden. Dieser Befehl wird beim Aufruf als einziger Parameter übergeben. Bei Aufruf mit restart muss der Dienst neu gestartet werden bzw. es muss die Konfiguration so eingelesen werden, dass diese wirksam wird.
Weitere Details dazu können in den Kapiteln Menü sowie Bootprozess nachgeschlagen werden.
Das Advanced Configuration File Handling (ACFH) bietet die Möglichkeit Generationen von Konfigurationsdateien in einem Verzeichnis (/etc/backup.d/) sichern zu lassen. Dies geschieht bei Nutzung des Skripts /var/install/bin/edit automatisch.
Die gesicherten Konfigurationsdateien tragen den Namen
$package.YYYY-MM-DD-HH-MI-SS,
also z.B. inet.2005-03-08-17-57-24.
Die Anzahl der vorzuhaltenden Generationen von Konfigurationsdateien wird bestimmt durch den Wert der Environmentvariablen MAX_BACKUP_CONFIG in der Datei /etc/config.d/environment. Übersteigt die Anzahl der Konfigurationsdateien für ein Paket die in MAX_BACKUP_CONFIG angegebene Anzahl, so wird jeweils die älteste Konfigurationsdatei gelöscht.
Über ein vorbereitetes Menü des ACFH und entsprechende Skriptes lassen sich die Funktionen des ACFH aufrufen. An der Stelle inet steht jeweils der entsprechende Paketname.
Beispiel:
Advanced inet-configuration file handling.
1: Restore configuration file from default directory
2: Restore configuration file from backup directory
3: Backup configuration file to backup directory
4: Show difference between current and default configuration
5: Show difference between current and a backup configuration
6: Show difference between default and a backup configuration
7: Show difference between two backup configurations
0: Exit
Command (1-7, ENTER=Return 0=Exit)
Die einzelnen Menüpunkte können allerdings nur dann erfolgreich augerufen werden, wenn die entsprechenden Konfigurationsdateien vorhanden sind.
Die Einbindung von ACFH in ein Paket ist mit dem neuen Menüformat (XML-Menü) sehr einfach geworden.
Um für ein Paket das ACFH-Untermenü aufrufen zu können sind nur zwei Zeilen im entsprechenden Paket-Menü notwendig.
<package>$package</package>
<menu file="setup.services.advancedconfig.menu">
Advanced configuration file handling</menu>
Der <menu>-Tag muss in einer Zeile stehen.
Über den <package>-Tag wird einerseits die Anzeige im Untermenü (siehe Beispiel oben paketname=inet) gesteuert, andererseits auch für die aufzurufenden Skripte eingestellt, um welches Paket und damit um welche Konfigurationsdateien es sich handelt.
Der über den <package>-Tag eingestellt Paketname wird in der Environmentvariablen $PACKAGE gespeichert. Diese Variable darf nicht anderweitig benutzt oder gar gelöscht werden. Daher steht im ACFH-Untermenü selbst (Datei setup.services.advancedconfig.menu) kein <package>-Tag.
Eine spezielle Situation entsteht, wenn von einem Menü aus mehr als ein ACFH Untermenü für verschiedene Konfigurationsdateien in /etc/config.d/ aufgerufen werden sollen.
Dies ist derzeit z.B. im Menü ,,Base configuration`` der Fall. Hier ein Ausschnitt aus dem Menü:
3: Advanced base configuration file handling
4: Advanced environment configuration file handling
Hier wird das ACFH Untermenü sowohl für die Datei /etc/config.d/base, als auch für /etc/config.d/environment aufgerufen.
Über den <package>-Tag ist base als Paketname eingestellt. D.h. der Aufruf für base kann wie oben beschrieben erfolgen.
Für die Behandlung der Datei /etc/config.d/environment muss die Option package="" des <menu>-Tag genutzt werden.
<menu package="environment" file="setup.services.advancedconfig.menu">
Advanced environment configuration file handling</menu>
Der <menu>-Tag muss in einer Zeile stehen.
Um die Quelldatei des Menüs einheitlich zu gestalten wurde auch der Aufruf des Menüs für die Datei /etc/config.d/base mit der optionalen Option package="" versehen.
<menu package="base" file="setup.services.advancedconfig.menu">
Advanced base configuration file handling</menu>
<menu package="environment" file="setup.services.advancedconfig.menu">
Advanced environment configuration file handling</menu>
Der <menu>-Tag muss in einer Zeile stehen.
Da das alte Menüformat keine Parameter übergeben konnte und auch das Setzen einer Environmentvariablen nicht vorgesehen war, war die Einbindung von ACFH ein wenig komplexer.
Die Einbindung wird hier noch einmal beschrieben, um deutlich zu machen, was beim Umsetzen eines Menüs vom alten Format in das neue Format an ,,Aufräumarbeiten`` notwendig ist.
Um beim alten Menüformat das entsprechende ACFH-Untermenü einbinden zu können und die Skripte erfolgreich aufrufen zu können existiert das Skript /var/install/bin/add_advancedconfigmenu.
Aufruf: add_advancedconfigmenu [-quiet] <package>
Bei <package> wird der Paketname angegeben. Der Parameter -quiet steuert, ob Ausgaben erfolgen sollte. Das Skript erstellt ein paketeigenes ACFH-Untermenü /var/install/menu/setup.services.$package.advancedconfig.menu sowie eine Reihe von Links mit Prefix $package, die auf die entsprechenden ACFH-Skripts zeigen. Zusätzlich muß die Zeile
/var/install/bin/$package-advancedconfig Advanced configuration file handlingin die entsprechende Menüdatei des Paketes eingetragen werden. Die Angabe muß in einer Zeile stehen.
ACHTUNG
Das Skript add_advancedconfigmenu ist für ein Paket, welches
das neue Menüformat (XML-Menü) nutzt, nicht mehr notwendig.
Zum Löschen des erzeugten paketeigenen ACFH-Untermenüs und der Links existiert das Skript del_advancedconfigmenu
Aufruf: del_advancedconfigmenu [-quiet] $package
Bei $package wird der Paketname angegeben. Der Parameter -quiet steuerte, ob Ausgaben erfolgen sollte.
Genau dieses Skript ist beim Umsetzen eines Paketes vom alten Format in das neue Format z.B. in /tmp/install.sh aufzurufen, um die entsprechenden ,,Aufräumarbeiten`` durchzuführen.
Beispiel:
/var/install/bin/del_advancedconfigmenu -quiet inet
führt die ,,Aufräumarbeiten`` z.B. für das inet-Paket durch.
Um die Konfigurationsfehler in Paketen möglichst auszuschließen wird für jedes Paket, welches eine Config-Datei besitzt, auch eine EISCHK-Datei angelegt: /etc/check.d/$package. In ihr sind alle Variablen der Konfigurationsdatei einzutragen. Der Aufbau gliedert sich dabei in 4 Spalten, die wie folgt belegt sind:
Diese Spalte gibt den Namen der zu überprüfenden Variable aus der Config-Datei an. Wenn es sich dabei um eine Variable handelt, die mehrmals mit verschiedenen Nummern auftauchen kann, wird an Stelle der Nummer ein Prozentzeichen (%) als Platzhalter in den Variablennamen eingefügt. Mehrere Prozentzeichen zur Überprüfung mehrdimensionaler Arrays sind zulässig. Sollten Variablen nur unter bestimmten Konfigurationsbedingungen benötigt werden, so sind sie als Optional zu kennzeichnen. Dazu wird vor die Variable ein ,,+`` Zeichen vorangestellt. Soll ein gesamtes Array optional sein, dann ist der Zählvariable (z.B. FOO_N) ebenfalls ein ,,+`` voranzustellen. In diesem Fall müssen aber auch die Array-Elemente als optional gekennzeichnet werden.
Beispiele:
optionale Variable:
# Variable: OPT_VARIABLE: VARIABLE_N: VALUE:
+FOO_NAME - - NONE
optionales Element in einem Array:
FOO_N - - NUMERIC
++FOO_%_VALUE1 - FOO_N NONE
FOO_%_VALUE2 - FOO_N NONE
optionales Array:
+FOO_N - - NUMERIC
++FOO_%_VALUE1 - FOO_N NONE
++FOO_%_VALUE2 - FOO_N NONE
optionales mehrdimensionales Array:
+FOO_N - - NUMERIC
++FOO_%_VALUE_N - FOO_N NUMERIC
++FOO_%_VALUE_%_VAL1 - FOO_%_VALUE_N NONE
Bei Bedarf kann in dieser Spalte eine Abhängigkeit zu einer anderen Variable
(OPT_VARIABLE) definiert werden. Dadurch findet eine Überprüfung nur dann statt,
wenn die OPT_VARAIABLE auf ,,yes`` steht. Der Name der OPT_VARIABLE
darf keine Platzhalter für Arrays (%) enthalten. Gibt es keine OPT_VARIABLE, ist hier
ein ,,-`` anzugeben.
Ab dem base-Paket v1.3.0 duerfen Platzhalter für Arrays (%) enthalten sein.
Beispiel:
# Variable: OPT_VARIABLE: VARIABLE_N: VALUE:
--------------------------------------------------------------------------------------
EISFAX_ANALOG_USE START_EISFAX - YESNO
EISFAX_ANALOG_N EISFAX_ANALOG_USE - NUMERIC
EISFAX_ANALOG_%_NAME EISFAX_ANALOG_USE EISFAX_ANALOG_N NONE
EISFAX_ANALOG_%_ACTIVE EISFAX_ANALOG_USE EISFAX_ANALOG_N YESNO
EISFAX_ANALOG_%_DEVICE EISFAX_ANALOG_%_ACTIVE EISFAX_ANALOG_N NOTEMPTY
EISFAX_ANALOG_%_SND EISFAX_ANALOG_%_ACTIVE EISFAX_ANALOG_N YESNO
EISFAX_ANALOG_%_SND_TO EISFAX_ANALOG_%_SND EISFAX_ANALOG_N NONE
EISFAX_ANALOG_%_SND_TYPE EISFAX_ANALOG_%_SND EISFAX_ANALOG_N EISFAX_FTYPE
EISFAX_ANALOG_%_PRN EISFAX_ANALOG_%_ACTIVE EISFAX_ANALOG_N YESNO
EISFAX_ANALOG_%_PRN_QUE EISFAX_ANALOG_%_PRN EISFAX_ANALOG_N EISFAX_PQUEUE
EISFAX_ANALOG_%_PRN_TYPE_GS EISFAX_ANALOG_%_PRN EISFAX_ANALOG_N YESNO
EISFAX_ANALOG_%_PRN_DRV EISFAX_ANALOG_%_PRN_TYPE_GS EISFAX_ANALOG_N NONE
Steht in der ersten Spalte eine Variable mit einem Platzhalter % im Namen, so wird hier die Variable angegeben, die die Häufigkeit des Auftretens der Variable definiert. Für mehrdimensionale Array sind auch hier % Zeichen im Namen zulässig. Gibt es keine VARIABLE_N, ist hier ein ,,-`` anzugeben.
Beispiel 1:
# Variable: OPT_VARIABLE: VARIABLE_N: VALUE:
BIND9_N - - NUMERIC
BIND9_%_NAME - BIND9_N DOMAIN
BIND9_%_MASTER - BIND9_N YESNO
BIND9_%_NETWORK - BIND9_N IPADDR
Beispiel 2 - mehrdimensionale Arrays mit optionalen Parametern:
# Variable: OPT_VARIABLE: VARIABLE_N: VALUE:
++BIND9_%_NS_N - BIND9_N NUMERIC
++BIND9_%_NS_%_NAME - BIND9_%_NS_N FQDN
Diese Spalte enthält die Überprüfungrichtlinie des Inhaltes der Variable. Sie sollte im Interesse einer geringen Fehlerquote möglichst exakt die Eingabemöglichkeiten eingrenzen. Dabei kann auf eine große Anzahl von fertigen Definitionen zurückgegriffen, aber auch mittels sogenannter ,,Regular Expressions`` eigene erstellt werden.
Folgende Definitionen sind bereits vorhanden:
| Name | Bedeutung | Beispiele
|
|---|---|---|
| NONE | Kein Überprüfung durchführen | |
| NOTEMPTY | Inhalt darf nicht leer sein | 'foo- 12' |
| NOBLANK | Es dürfen keine Leerzeichen enthalten sein | 'foo' |
| ENOBLANK | Kein Eintrag - oder Eintrag wie unter NOBLANK | '' / 'foo' |
| NUMERIC | Nur Zahlen sind zulässig | '1234' |
| ENUMERIC | Kein Eintrag - oder Eintrag wie unter NUMERIC | '' / '1234' |
| DOT_NUMERIC | Zwei Zahlen durch einen Punkt getrennt | '12.5' |
| EDOT_NUMERIC | Kein Eintrag - oder Eintrag wie unter DOT_NUMERIC | '' / '12.5' |
| NUM_HEX | Hexadezimale Zahl - startend mit 0x | '0xff12' |
| NUM_ANY | Zahlen in numerischer oder hexadezimaler Schreibweise | '123' / ''0xff12' |
| YESNO | Nur yes oder no sind erlaubt | 'yes' / 'no' |
| MACADDR | Mac Adresse einer Netzwerkkarte | '00:00:E8:83:72:92' |
| HOSTNAME | Hostname bestehend aus Buchstaben, Zahlen und Bindestrich | 'foo-1' |
| DOMAIN | Domainname inclusive Endung | 'bar.local' |
| EDOMAIN | Kein Eintrag - oder Eintrag wie unter DOMAIN | '' / 'bar.local' |
| FQDN | Vollständiger Internetname - host.domain.location | 'foo-1.bar.local' |
| EFQDN | Kein Eintrag - oder Eintrag wie unter FQDN | '' / 'foo-1.bar.local' |
| OCTET | Zahl im Bereich von 0 bis 255 | '128' |
| IPADDR | Gültige IP-Adresse, bestehend aus 4x OCTET | '192.168.0.128' |
| EIPADDR | Kein Eintrag - oder Eintrag wie unter IPADDR | '' / '192.168.0.128' |
| IPADDRESSES | Eine oder mehrere IP-Adressen durch Leerzeichen getrennt | '192.168.0.1 192.168.0.2 192.168.0.3' |
| EIPADDRESSES | Kein Eintrag - oder Eintrag wie unter IPADDRESSES | '' / '192.168.0.1 192.168.0.2 192.168.0.3' |
| IP_ROUTE | Netzwerk, Netzmaske und Gateway durch Leerzeichen getrennt | '192.168.0.0 255.255.255.0 192.168.0.254' |
| DNS_SPEC | DOMAIN und IP-Adresse durch Leerzeichen getrennt | 'bar.local 192.168.0.1' |
| MASK | Zahl zwischen 0 und 32 | '32' |
| NETWORK | Kombination aus IP-Adresse, Trennstrich und Maske | '192.168.0.0/24' |
| NETWORKS | Ein oder mehrer Netzwerke durch Leerzeichen getrennt | '192.168.0.0/24 192.168.1.0/24' |
| ENETWORKS | Kein Eintrag - oder Eintrag wie unter NETWORKS | '' / '192.168.0.0/24 192.168.1.0/24' |
| MULTIPLE_NETWORKS | Ein oder mehrer Netzwerke durch Leerzeichen getrennt | '192.168.0.0/24 192.168.1.0/24' |
| EMULTIPLE_NETWORKS | Kein Eintrag - oder Eintrag wie unter MULTIPLE_NETWORKS | '' / '192.168.0.0/24 192.168.1.0/24' |
| IPADDR_NETWORK | IP-Adresse und Netzwerk durch Leerzeichen getrennt | '192.168.0.1 192.168.1.0/24' |
| EIPADDR_NETWORK | Kein Eintrag - oder Eintrag wie unter IPADDR_NETWORK | '' / '192.168.0.1 192.168.1.0/24' |
| MAILADDR | Vollständige E-Mail Adresse | 'foo@bar.local' |
| EMAILADDR | Kein Eintrag - oder Eintrag wie unter MAILADDR | '' / 'foo@bar.local' |
| CRONTAB | Crontab Eintrag: Minute Stunde Tag Monat Wochentag | '15 3 * * fri' |
| REL_PATH | Relatives Verzeichnis | 'install/menu' |
| E_REL_PATH | Kein Eintrag - oder Eintrag wie unter REL_PATH | '' / 'install/menu' |
| ABS_PATH | Absolutes Verzeichnis | '/var/install/menu' |
| E_ABS_PATH | Kein Eintrag - oder Eintrag wie unter ABS_PATH | '' / '/var/install/menu' |
| LOG_INTERVAL | Als Werte sind daily, weekly oder monthly möglich | 'daily' / 'weekly' / 'monthly' |
| PORT | Kommunikationsport im Bereich von 1 - 65535 | '3050' |
| ETH_BASE_DEV_NAME | Name der Ethernet Schnittstelle | 'eth0' |
| ETH_DEV_NAME | Erweiterter Name der Ethernet Schnittstelle | 'eth0:3 |
| TR_BASE_DEV_NAME | Name der Tokenring Schnittstelle | 'tr2' |
| TR_DEV_NAME | Erweiterter Name der Tokenring Schnittstelle | 'tr2:1' |
| BR_DEV_NAME | Netzwerk Bridge Schnitstelle | 'br1:2' |
| BOND_BASE_DEV_NAME | Netzwerk Bonding Schnitstelle | 'bond0' |
| BOND_DEV_NAME | Erweiterter Name der Netzwerk Bonding Schnitstelle | 'bond0:1' |
| XEN_BASE_DEV_NAME | XEN Bridge Netzwerk Schnitstelle | 'xen-br0' |
| XEN_BASE_NAME | Erweiterter Name der XEN Bridge Netzwerk Schnitstelle | 'xen-br0:1' |
| DUMMY_DEV_NAME | Platzhalter Schnittstelle (Dummy) | 'dummy0' |
| IP_NET_NAME | Ethernet, Tokenring, Bridge oder Dummy Schnittstelle | 'eth0:2' / 'br1' / 'tr0' / 'dummy0' |
| IP_ROUTE | Netzwerkroute (network netmask gateway) | '192.168.1.0 255.255.255.0 192.168.1.254' |
| IP_ROUTE_CIDR | Netzwerkroute (network/cidr gateway) | '192.168.1.0/24 192.168.1.254' |
Damit wird man nicht jeden Anwendungsfall abdecken können. Deshalb gibt es die Möglichkeit, eigene Überprüfungen zu definieren. Das wird durch die Buchstaben ,,RE:`` für Regular Expressions eingeleitet.
Beispiel:
# Variable: OPT_VARIABLE: VARIABLE_N: VALUE:
COLOR - - RE:red|green|blue
So kann eine einfache Parameterauswahl realisiert werden. Alle anderen Eingaben als ,,red``, ,,green`` oder ,,blue`` werden abgelehnt. Ein komfortablerer Weg stellt der Einsatz einer /etc/check.d/$package.exp Datei dar. In ihr können neben den Regular Expressions eigene Fehlermeldungen definiert werden.
ACHTUNG
Eigene Regular Expressions in der Datei /etc/check.d/$package.exp müssen
den Paketnamen als Präfix enthalten.
Beispiel:
FOO_COLOR = 'red|green|blue' : 'only red, green or blue are allowed'
In den regulären Ausdrücken können auch Referenzen auf bereits existierende Definitionen enthalten sein. Dadurch ist es einfacher, reguläre Ausdrücke zu konstruieren. Eingefügt werden die Referenzen einfach durch '(RE:Referenz)'.
Beispiel:
FOO_IP_ROUTE = '(RE:IPADDR)[[:space:]]+(RE:IPADDR)[[:space:]]+(RE:IPADDR)'
: 'no valid route specification (network netmask gateway)'
FOO_DOT_NUMERIC = '(RE:NUMERIC).(RE:NUMERIC)'
: 'should be numeric (decimal) with dot e.g. 5.0'
Findet die Prüfung einen Fehler, erfolgt die Ausgabe der Fehlermeldung auf folgende Art:
Error: wrong value of variable HOSTNAME: '' (may not be empty)
Error: wrong value of variable MOUNT_OPT: 'rx' (user supplied regular expression)
Beim ersten Fehler wurde der Ausdruck in einem exp file definiert und ein Hinweis auf den Fehler wird mit ausgegeben. Im zweiten Falle wurde der Ausdruck direkt im *.txt File spezifiziert, deshalb gibt es keinen zusätzlichen Hinweis auf die Fehlerursache.
Reguläre Ausdrücke sind wie folgt definiert:
Regulärer Ausdruck: Eine oder mehrere Alternativen, getrennt durch '|', z.B. 'ro|rw|no'. Trifft eine der Alternativen zu, trifft der ganze Ausdruck zu (hier wären 'ro', 'rw' und 'no' gültige Ausdrücke).
Eine Alternative ist eine Verkettung mehrerer Teilstücke, die einfach aneinandergereiht werden.
Ein Teilstück ist ein ,,Atom``, gefolgt von einem einzelnen '*', '+', '?' oder '{min, max}'. Die Bedeutung ist wie folgt:
Ein ,,Atom`` ist ein
Ein Ausdruck mit rechteckigen Klammern bedeutet folgendes
Sehen wir uns das mal an einigen Beispielen an:
Numerisch: Ein numerischer Wert besteht aus mindestens einer, aber beliebig vielen Zahlen. Mindestens ein, aber beliebig viele drückt man mit '+' aus, eine Zahl hatten wir schon als Beispiel. Zusammengesetzt ergibt das:
NUMERIC = '[0-9]+' oder alternativ
NUMERIC = '[[:digit:]]+'
NOBLANK: Ein Wert, der keine Leerzeichen enthält ist ein beliebiges Zeichen (außer dem Leerzeichen) und davon beliebig viele:
NOBLANK = '[^ ]*'
bzw. wenn der Wert zusätzlich auch nicht leer sein soll:
NOBLANK = '[^ ]+'
Disk und Partition: Gültige Bezeichner für eine Disk beginnen mit hd bei IDE-Disks bzw sd bei SCSI-Disks. Dann folgen Buchstaben von a-z (a für die erste Disk, b für die 2., ...) und bei Partitionen die Zahlen 1-8 (1-4 für die ersten 4 Partitionen, die Primär bzw. Extended (nur eine) sein können und 5-8 für die logischen Partitionen innerhalb einer extended Partition). Die Ausdrücke sehen dann wie folgt aus:
DISK = '(hd|sd)[a-z]'
PARTITION = '(hd|sd)[a-z][1-8]'
Sehen wir uns das ganze nochmal am Beispiel der IP-Addresse an. Eine IP-Adresse besteht aus 4 Octets, die mit einem '.' getrennt sind. Ein Octet kann eine Zahl zwischen 0 und 255 sein. Definieren wir als erstes ein Octet. Es kann
| eine Zahl zwischen 0 und 9 sein: | [0-9] |
| eine Zahl zwischen 00 und 99: | [0-9][0-9] |
| eine Zahl zwischen 100 und 199: | 1[0-9][0-9] |
| eine Zahl zwischen 200 und 249: | 2[0-4][0-9] |
| eine Zahl zwischen 250 und 255 sein: | 25[0-5] |
Da sich die ersten drei Teile stark ähneln, kann man sie zusammenfassen:
Das ganze sind Alternativen, also fassen wir sie einfach mittels '|' zu einem Ausdruck zusammen: '1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5]' und haben damit ein Octet. Daraus können wir nun eine IP-Adresse machen, 4 Octets mit Punkten voneinander getrennt (der Punkt muß mittels backslash gequotet werden, da er sonst für ein beliebiges Zeichen steht). Basierend auf der Syntax der Exp-Files sieht das ganze dann wie folgt aus:
OCTET = '1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5]'
IPADDR = '((RE:OCTET)\.){3}(RE:OCTET)'
Manchmal ist es notwendig, komplexere Überprüfungen durchzuführen. Beispiele für solche komplexeren Dinge wären z.B. Abhängigkeiten zwischen Paketen oder Bedingungen, die nur erfüllt sein müssen, wenn Variablen bestimmte Werte annehmen.
Um diese Überprüfungen durchführen zu können, kann man in /etc/check.d/$package.ext kleinere Tests schreiben. Die Sprache besteht aus folgenden Elementen:
Mit Hilfe dieser drei Funktionen kann man Nutzer warnen, einen Fehler signalisieren oder die Prüfung sofort abbrechen. Das Format sieht wie folgt aus:
Im Text kann man auf Variablen Bezug nehmen, indem man einfach den Namen mit einem vorangestellten '$' oder '%' Zeichen in den Text schreibt (evtl. in eingeschlossen, um den Variablenamen vomm umgebenden Text abzugrenzen). eischk versucht den darauffolgenden Text (Ziffern, Zahlen, '_') als Variablennamen zu interpretieren und setzt bei einem vorangestellten '$' den Inhalt der Variablen an dieser Stelle ein, wenn Sie definiert ist, bzw bei einem vorangestellten '%' den vollständigen Namen der aktuellen %-Variable. Sonst steht der originale Text da. Will man wirklich ein '$' oder ein '%' im Text haben, schreibt man '$$' bzw. '%%'.
Benötigt man aus irgend einem Grund eine temporäre Variable, kann man diese einfach mit ,,set var [= value]`` anlegen. Die Variable darf kein Config-Variable sein. Läßt man den ,,= value`` Teil weg, wird die Variable einfach auf ,,yes`` gesetzt, so daß man sie hinterher einfach in einer if-Anweisung testen kann. Wird ein Zuweisungsteil angegeben, kann hinter dem Gleichheitszeichen alles stehen, normale Variablen, Indizierte Variablen, Zahlen, Zeichenketten, Versionen.
Will man auf einzelne Elemente einer %-Variablen (eines Arrays) zugreifen, kann man das wie gewohnt mit %_var[index] tun, wobei für jedes % Zeichen ein [ Index ] auftauchen muß.
stat() ermöglicht es, Eigenschaften einer Datei abzufragen. Zur Verfügung gestellt wird im Augenblick lediglich die Größe einer Datei, andere Attribute sind aber leicht hinzuzufügen. Abfragen sehen wie folgt aus (wobei die verwendeten Parameter nur Beispiele sind):
stat ("unix/Makefile", test)
Danach sind zwei Variablen definiert:
Das könnte dann z-B. so aussehen:
stat ("unix/Makefile", test)
if ("$test_res" == "OK")
then
warning "test_size = $test_size"
else
error "Error '$test_res' while trying to get size of ..."
fi
Oftmals werden Variablen mir mehreren Parametern belegt, die dann in Startup-Scripten erst wieder auseinandergenommen werden. Will man diese bereits vorher auseinandernehmen und Tests mit ihnen durchführen, nimmt man split().
split (string, %_var, character)
Der String kann durch eine Variable, %-Variable oder direkt als String angegeben werden. eischk zerlegt ihn an den Stellen, an denen das Trennzeichen auftaucht und erzeugt je eine Instanz der %-Variablen. Über diese kann man dann hinterher Tests laufen lassen. Steht zwischen zwei Trennzeichen nichts, wird eine Instanz mit einer leeren Zeichenkette als Wert erzeugt. Ausnahme ist ' ', hier werden alle whitespaces konsumiert und keine leeren Variablen erzeugt.
Sollen die bei der Zerlegung entstandenen Elemente in einem numerischen Kontext verwendet werden (z.B. als Index), muß das beim Aufruf von Split spezifiert werden. Das geschieht durch das zusätzliche Attribut 'numeric'. Der Aufruf sieht dann wie folgt aus:
split (string, %_var, character, numeric)
if (expr)
then
statement
else
statement
fi
Eine klassische if-Konstruktion, wie man sie kennt. Ist die Bedingung wahr, wird der then-Teil ausgeführt, ist die Bedingung falsch, wird der else-Teil ausgeführt.
Will man Tests über %-Variablen durchführen, muß man jede einzelne Variable testen. Dazu gibt es das foreach-Statement in zwei Varianten:
foreach loop_var in set_var
do
statement
done
Diese Schleife iteriert über alle %-Variablen, angefangen bei eins bis zum in der dazugehörigen (in /etc/check.d/$package stehenden) Variable_N stehenden Index n. Die Laufvariable loop_var nimmt dabei die jeweiligen Werte der %-Variablen an.
Das Statement kann dabei eine der oben beschriebenen Funktionen if, foreach, warning, error oder fatal_error sein.
Will man genau eine %-Variable testen, kann man diese mittels var_%$index auswählen. Der index kann dabei eine normale Variable, ein String, oder wiederum ein indiziertes Array sein.
foreach loop_var in var_n
do
statement
done
Diese Schleife läuft von 1 bis var_n. Man kann die Schleifenvariable loop_var dazu benutzen, um _% Variablen zu indizieren. Will man also nicht nur über eine _% Variable iterieren, sondern über mehrere gleichzeitig, nimmt man diese Variante der Schleife und verwendet die loop_var zum Indizieren mehrerer _% Variablen.
Die Expressions erlauben so gut wie alles, was man von einer Programmiersprache gewöhnt ist. Ein in einem Ausdruck auftauchender Wert 'val' kann eine Variable, ein String oder ein indiziertes Array sein. Variablen in Strings werden dabei wie oben beschrieben ersetzt. Ein Test auf die Gleichheit zweier Variablen könnte also so aussehen:
var1 == var2
"$var1" == "$var"
Zu beachten ist dabei, daß der Vergleich in Abhängigkeit vom Typ der Variable erfolgt, der in /etc/check.d/$package festgelegt wurde. Variablen, die als Typnamen einen mit NUM beginnenden Namen haben erhalten einen numerischen Typ. Ist einer der beiden Variablen numerisch, erfolgt der Vergleich auf numerischer Basis, d.h. die Zeichenketten werden in Zahlen umgewandelt und dann vergleichen. Sonst erfolgt der Vergleich auf String-Basis; ein Vergleich von '05' und '5' geht ergibt ungleich, ein Vergleich von '18' und '9' ergibt '18' < '9'.
Für den Vergleich von Versionen wird das Hilfskonstrukt numeric(version) eingeführt, welches den numerischen Wert für einen Versionsstring für Vergleichszwecke bestimmt . numeric(version) == sub_version + 1000 * minor_version + 10000 * major_version:
Eine vollständige Auflistung aller Ausdrücke ist in der folgenden Tabelle zu finden.
| expr | true if |
| id | id == 'yes' |
| val == val | strings/numerische Werte sind identisch |
| val != val | strings/numerische Werte sind verschieden |
| val == number | numerischer Wert von val == number |
| val != number | numerischer Wert von val != number |
| val < number | numerischer Wert von val < number |
| val > number | numerischer Wert von val > number |
| val == version | numeric(val) == numeric(version) |
| val < version | numeric(val) < numeric(version) |
| val > version | numeric(val) > numeric(version) |
| ( expr ) | Ausdruck in Klammern ist wahr |
| expr && expr | beide Ausdrücke sind wahr |
| expr || expr | mind. einer der beiden Audrücke ist wahr |