Das OS-Plugin-Konzept von OpenSLX¶
Viele der von uns geplanten Erweiterungen sollen als Plugins implementiert werden, so dass man sie unabhängig vom Kernsystem (und von anderen Erweiterungen) entwickeln und testen kann. Dies hat u.a. auch den Vorteil, dass zwei Entwickler, die gerade an einer Erweiterung werkeln, sich nicht gegenseitig bei der Integration ihrer Arbeit in das Stage3-Initskript auf den Füßen stehen.
Liste verfügbarer Plugins:¶
- auth
- bootsplash
- desktop
- dropbear
- eduroam
- example
- infoscreen
- kiosk
- plymouth
- profile
- syslog
- vmchooser
- vmware
- x11vnc
- xserver
Liste geplanter/in Entwicklung befindlicher Plugins:¶
- printer
- scanner
- virtualbox (unvollständig, in Entwicklung)
- qemukvm (unvollständig, in Entwicklung)
- xen
- auth (Konfiguration von Benutzern und ihren Homeverzeichnissen inkl. root und PW setzen)
Plugins & Attribute¶
Damit die Plugin-spezifischen Attribute zuverlässig dem richtigen Plugin zugeordnet werden können, muss bei der Benamung der Attribute darauf geachtet werden, dass jedes der Attribute mit den Präfix '<plugin-name>::' beginnt (denn darüber erfolgt die Zuordnung von Attributen zu Plugins beim Demuxen).
Doch, beim Deinstallieren eines Plugins mittels slxos-plugin werden alle Attribute (Stage1 & Stage3) aus der DB gelöscht. Man kann derzeit zwar Defaultwerte für alle Vendor-OS vorgeben, indem man ein Plugin in das Vendor-OS "<<<default>>>" installiert, allerdings wird dieses Plugin dann auch gleich immer beim Anlegen eines neuen Vendor-OS in dieses hineininstalliert.
Stage1-Attribute¶
Stage1-Attribute sind dazu da, die Installation des Plugins in das Vendor-OS vom Anwender steuerbar zu machen, d.h. die Werte dieser Attribute bestimmen, welche Varianten des vom Plugin verwalteten Dienstes in dem jeweiligen Vendor-OS (und damit in den darauf basierenden Systemen und Clients) zur Verfügung stehen sollen.
Stage1-Attribute werden zusammen mit dem Vendor-OS in der Datenbank gespeichert und repräsentieren die Installation des Plugins. Anzeigen lassen kann man sich diese Attribute (neben den Stage3-Attributen) mit:
slxconfig --verbose list-vendor <system>
Stage3-Attribute¶
Stage3-Attribute eines Plugins haben die Aufgabe, die Konfiguration des Plugins für bestimmte Systeme/Clients vorzunehmen, d.h. die Werte dieser Attribute bestimmen, welche der möglichen Varianten des vom Plugin verwalteten
Dienstes beim Booten eines bestimmten Systems/Clients benutzt wird. Merke: Die möglichen Varianten werden durch Stage1-Attribute festgelegt, die konkrete Auswahl einer bestimmten Variante aus diesen möglichen erfolgt über Stage3-Attribute.
- Attribute des konkreten Clients
- Attribute des konkreten Systems
- Attribute des Vendor-OS
D.h. ein beim Client gesetztes Attribut überstimmt alle an anderen Stellen gesetzten Werte dieses Attributs.
Nutzung von Plugins¶
Jedes OS-Plugin stellt eine bestimmte Erweiterung für alle von OpenSLX unterstützten Vendor-OS bereit. Dies kann z.B. einerseits die Möglichkeit zur Benutzerauthentizierung per LDAP sein, als auch anderseits die automatische Integration und Konfiguration von kommerziellen Xorg-Treibern. Damit die OS-Plugins ihre spezifische Aufgabe umsetzen können, bietet der OpenSLX-Kern grundsätzlichen Support für Plugins an:
Installation (allgemein anpassen)¶
Der Aufruf zur Installation:
slxos-plugin install <vendor-os> xserver ati=1 nvidia=1 slxos-export export <vendor-os> <exportType> slxconfig-demuxer slxconfig change-system <vendor-os> xserver::prefnongpl=1
Achtung: Für die binären Treiber von ATI und/oder NVIDIA (werden im Beispiel aktiviert/installiert) braucht man die Treiber-Archive, die von den jeweiligen Seiten heruntergeladen werden können. Bei Installation des Plugins sollte der genaue Pfad der Dateien mittels slxos-plugin festgelegt werden, da die Treiber sonst nicht geeignet installiert werden können.
Grundvorraussetzung sind auch die Kernel-Headers, damit die Module in die benötigte Kernel-Version eingebaut werden kann.
UPDATE: Zur Zeit werden die Kernel-Module direkt kompiliert und die benötigten Treiber-Bibliotheken von dem jeweiligen Paketsystem der Distribution übernommen. Implementiert ist diese Methode auf Ubuntu-8.10 (sauber) und auf Suse-11.0 (alles wird 2 Mal runtergeladen). Wenn jemand herausfindet, wie man mit zypper (dem Suse-rpm-tool) die rpm's direkt herunterladen kann, sollte bitte eine Mail an eine Liste schicken.
Die Option "xserver::prefnongpl=1" dient dazu, die Treiber in Stage3 zu aktivieren.
Generischer NVidia-Installer¶
Für eine Reihe von Distributionen steht der vorher beschriebene Weg so nicht zur Verfügung. Dann kann man den NVidia-Treiber direkt von der NVidia-Seite (der Link wird sich im Laufe der Zeit sicherlich ändern) herunterladen und ins Verzeichnis /root/xserver-pkgs legen. Von dort wird er bei der Plugin-Installation kopiert und der Installer aufgerufen. Der Aufruf ist für die Einrichtung der Bibliotheken unproblematisch. Diese finden sich dann im Plugin-Verzeichnis unterhalb von nvidia/usr, Schwieriger wird die Erstellung des Kernel-Moduls nvidia.ko.
Hierzu müssen Kernel-Quellen und Compile-Umgebung im gewünschten Vendor-OS installiert sein. Ebenso sollte man eine Konfiguration passend zum laufenden Kernel haben (zcat /proc/config.gz bei SuSE oder /boot/config-2.6.* bei Ubuntu). Dann:
slxos-setup shell <vendor-os> cd /usr/src/linux(-version) # je nach Distro cp pfad-zur-config/kernel-config .config make scripts cd /opt/openslx/plugin-repo/xserver NVidia-.../nvidia-installer (mit angepassten Optionen aus *nvidia-install.sh*)
Wenn alles glatt ging, gibts neben dem usr/ im Unterverzeichnis nvidia/ ein weiteres Verzeichnis modules/ in dem dann eine Datei nvidia.ko auftaucht.
Beispielablauf¶
Derzeit existiert einerseits ein ausführlich kommentiertes, aber funktional nur beispielhaften OS-Plugin namens 'example', welches mit einem Teil der genannten Mechanismen das "Feature" implementiert, beim Booten des Clients in Stage3 einen Smiley auszugeben, wobei die Richtung des Smileys [ ;-) oder (-; ] über eine Konfigurationsdatei angegeben werden kann. Andererseits gibt es das Plugin desktop, welches eine ganze Reihe von Dateien anlegt in Abhängigkeit verschiedener Variablen anlegt und konfiguriert. Dabei passieren Teile im Stage1 (Perl-Code) und Teile im Stage3 (Shell).
Im Folgenden soll der konkrete Ablauf von 'example' nachvollzogen werden:- Das Plugin 'example' wird im Vendor-OS 'suse-11.1' "installiert" (und aktiviert - das ist der Default, so dass es nicht wirklich notwendig ist. Damit es auch wirklich zur Verfügung steht, ist anschliessend noch ein Export erforderlich. Hier passiert nichts Plugin-spezifisches, alle notwendigen statischen Dateien werden erst jetzt in den Export übertragen.):
slxos-plugin install suse-11.1 example active=1 slxos-export export suse-11.1 <export-type>
- Beim Generieren der Conf-TGZs mittels
slxconfig-demuxer
wird das Stage1-Perlmodul example.pm erneut geladen und nach der (Default-)Konfiguration für die Clients gefragt. Diese Konfiguration wird zusammen mit dem Stage3-Shellskript des Plugins in das Config-TGZ des Clients übertragen:fry:/tmp/xxx # tar tzvf /srv/openslx/tftpboot/client-config/suse-11.1\:nfs/default.tgz drwxr-xr-x root/root 0 2007-10-14 18:41:10 initramfs/ -rw-r--r-- root/root 482 2007-10-14 18:41:10 initramfs/machine-setup -rwxr--r-- root/root 317 2007-06-17 11:51:38 initramfs/postinit.local drwxr-xr-x root/root 0 2007-10-14 18:41:10 initramfs/plugin-init.d/ -rwxr-xr-x root/root 1518 2007-10-14 18:41:10 initramfs/plugin-init.d/50_example.sh drwxr-xr-x root/root 0 2007-10-14 18:41:10 initramfs/plugin-conf/ -rw-r--r-- root/root 49 2007-10-14 18:41:10 initramfs/plugin-conf/example.conf -rwxr--r-- root/root 230 2007-06-17 11:44:58 initramfs/preinit.local drwxr-xr-x root/root 0 2006-09-22 21:08:33 rootfs/ drwxr-xr-x root/root 0 2006-09-23 17:42:43 rootfs/etc/ -rw-r----- root/root 597 2006-09-23 17:46:16 rootfs/etc/shadow -rw-r--r-- root/root 1264 2006-09-23 17:46:09 rootfs/etc/passwd
Man sieht, dass das Stage3-Runlevelskript des example-Plugins die Priorität 50 erhalten hat, was der Default-Priorität entspricht:fry:/tmp/xxx # cat initramfs/plugin-conf/example.conf example_active="1" example_preferred_side="left"
Außerdem kann man der Konfiguration noch entnehmen, dass das Plugin grundsätzlich aktiv ist (d.h. in Stage3 ausgeführt werden soll) und dass man es vorzieht, den Kopf nach links zu neigen, um das Smiley zu lesen ...
Aktivierung/Deaktivierung von Plugins¶
Merke: Ein Plugin kann einerseits installiert und aktiviert werden:- Installieren heißt, es wird ins Vendor-OS kopiert (und installiert dort evtl. weitere Pakete).
- Aktivieren erfolgt pro System (per Vorgabe ist jedes Plugin nach Installation in ein Vendor-OS in allen Systemen dieses Vendor-OS aktiviert).
Informationen zur Pluginentwicklung¶
Init-Hooks¶
Um es einzelnen Plugins zu ermöglichen, direkten Einfluss auf die Abläufe im Stage3-Initskript zu nehmen, gibt es noch das Konzept von Init-Hooks, d.h. das Stage3-Initskript sieht es vor, beim Erreichen von bestimmten Zuständen (Kernelvars ausgewertet, Root-FS gemountet, usw.) sämtliche in einem bestimmten Verzechnis befindliche Shellskripte auszuführen (ein simpler Eventmechanismus). Ein Plugin, welches in den Ablauf des Init-Skriptes eingreifen muss, kann nun eigene Hook-Skripte an die "richtigen" Stellen plazieren, um so die Gelegenheit zu erhalten, auf das jeweilige "Ereignis" zu reagieren.
So benutzt das bootsplash-Plugin diverse solcher Hook-Skripte, um den Bootsplash zu updaten.
- 00-started
- 05-have-kernelvars
- 10-nw-if-config
- 20-nw-bridge-config
- 25-have-ip-config
- 35-have-network-root
- 40-started-hw-config
- 50-have-layered-fs
- 60-have-servconfig
- 70-before-plugins
- 80-after-plugins
- 85-have-initial-boot
- 90-postinit-done
- 95-cleanup
- 99-handing-over
Distrospezifische Funktionen¶
Da bei der Installation eines Plugins in Stage1 klar ist, um welche Distribution es sich handelt, ist dieses der richtige Ort, das Stage3-Runlevel-Skript zu erzeugen, so denn eines benötigt wird. Dieses erfolgte ursprünglich via:
my $runlevelScript = $self->{distro}->function(attributes);
spitFile($file, $runlevelScript);
was sich aber als nicht so praktisch erwies. Deshalb gibt es nun einen abstrakteren Ansatz (Doku bisher nur in r2405):
* use OpenSLX::DistroUtils;
1. get initfile object
my $initfile = newInitFile();
1. modify the object
$initfile->addToBlock('head', 'set some variables');
1. 3rd parameter is setting the priority of the entry
2. default is 5
$initfile->addToBlock('head', 'set sth at the very beginning', 1);
$initfile->addToBlock('start', '/bin/startsomething');
$initfile->addToBlock('stop', '/bin/stopsomething');
$initfile->setName('foo');
..
1. get generated content of initfile
$source = getInitFileForDistro($initfile, 'Ubuntu');
Stage 3¶
Für Stage3 distrospezifische Skripte (beispielsweise angepasste Runlevelskripten) - diese werden bei der Installation des Plugins an eine einheitliche Stelle kopiert - kann man einen Blick auf das desktop Plugin werfen. Hierzu lässt sich folgender Ansatz verwenden:- Entsprechendes Skript in Stage1 (Distro ist hier bekannt) kopieren und
_XX_plugin.sh_nur mit..??
füllen. Ein Beispiel ist in Changeset r2012 zu sehen.
Stage 4¶
Stage4-Skripte (init-Skripte) kann man in Stage3 ablegen (sofern vendorOS je nach Stage3 Konfiguration verschiedene init-Skripte verwendet). Hier gibt es die Variable ${D_INITDIR}. Beispiel:
cp /mnt/opt/openslx/plugin-repo/vmware/${vmware_kind}/vmware.init \
/mnt/etc/${D_INITDIR}/vmware-env
Für die Aktivierung gibt es in Stage3 einen eigenen Befehl rrlinker.
Die zu kopierende Datei (hier vmware.init) ist distributionsspezifisch, da in Stage1 bekannt ist um welche Distribution es sich handelt und diese dementsprechend dort angepasst abgelegt wird.
Testen und Fehlersuche¶
Zum Ausprobieren, ob ein bestimmtes Perl-Modul (z.B. Plugin) funktioniert (dazu muss man sich im Pfad mit allen Plugins befinden ~/os-plugins/plugins):
perl -I /opt/openslx/lib/ -cw desktop/OpenSLX/Distro/Suse.pm
Pakete im Vendor-OS nachinstallieren¶
Im Stage1 kann man Pakete nachinstallieren - sofern diese Standardbestandteil der Distribution sind. Dies geschieht z.B. im Desktop-Plugin. Dieser Abschnitt dient lediglich als Hinweis, dass dies möglich ist und an welcher Stelle man den Ablauf nachschlagen kann.
Innerhalb des Desktop Plugins - dekstop.pm:
sub installationPhase
{
my $self = shift;
my $info = shift;
...
$self->_installRequiredPackages();
}
sub _installRequiredPackages
{
my $self = shift;
my $engine = $self->{'os-plugin-engine'};
# Test ob Gnome installiert ist. Falls nicht, so wird
# installGNOME aus der spezifischen Distributionsdatei ausgefuehrt
if ($self->{'gnome'} && !$self->{distro}->isGNOMEInstalled()) {
$self->{distro}->installGNOME();
}
....
return 1;
}
Ablauf eines Installationsaufrufes (z.B. installGNOME()) anhand der aufgerufenen Funktionen nach zu verfolgen. Interessant ist in diesem Beispiel auch die vorherige Überprüfung isGNOMEInstalled(). Neben der Gnome Umgebung können von diesem Plugin auch andere Pakete installiert werden. Je nach Bedarf kann aufgrund von distributionsspezifischen Funktionen die Betrachtung eines zu installierenden Paketes nahegelegt werden.
Die Frage die noch offen bleibt ist, in welchen Fällen man dies anwenden sollte.
Abbruchwerte der Pluginstallation innerhalb von plugin.pm¶
Manchmal kann es vorkommen, das man die Installation eines Plugins abbrechen will. Z.B. wenn bestimmte Dateien oder Pakete fehlen und auch nicht installierbar sind.
Ein "exit 1" in preInstallationPhase() fuehrt dazu, das das Plugin als nicht installiert gelistet wird (dies ist auch in der entsprechenden perldoc, die preInstallationPhase() beschreibt dokumentiert.
Zu installationPhase() wurde auf openslx-devel@ folgendes geschrieben:
> If I do a "exit 1" in installationPhase(), the plugin won't get
> installed. But in "slxos-plugin list-installed <vendorOS>" the plugin is
> still listed as installed.
The underlying problem here is that installationPhase() is being invoked
inside the chroot. In order to do so and be able to leave the chroot later,
the main process forks a child, which enters the chroot and invokes
installationPhase(). The parent process waits for the child to exit and then
continues (still outside of the chroot).
> Which exit value do I need in installationPhase() so the plugin won't
> show up as installed in slxos-plugin?
I think you should use die("message") instead of printing an error and then
invoke exit(). The death message should then be propagated back to the parent
process correctly, causing the parent to stop, too.