Lingon - die GUI für den Super-Dämonen launchd

stk

Grünapfel
Registriert
05.01.04
Beiträge
7.141
Eventgesteuerte Programmstarts sind für OS X nichts Neues. Startobjekte nach dem Login; iCal-Termine, die nicht klingeln sondern Dateien oder Scripte öffnen oder Ordneraktionen zur Überwachung von Ordnerinhalten - alles schon vorhanden.

Wer das alles lieber zentral an einem Ort verwalten möchte oder wer - z.B. bei einem Server - i.d.R. keine GUI zur Verfügung hat, aber dennoch eventgesteuert Programme triggern will, braucht launchd. Und wer sich (anfangs) nicht zutraut die passenden XML-Dateien für den Start von Programmen via launchd zu schreiben, sollte sich Lingon anschauen!

Lingon ist der schwedische Name für »Preiselbeere« und stammt von Peter Borg, der auch den Texteditor Smultron (Walderdbeere) und die Bookmarkverwaltung Hallon (Himbeere) geschrieben hat. Lingon ist Donationware und kann unter http://lingon.sourceforge.net/ heruntergeladen werden.

Gehen wir aber für einen kurzen Moment nochmal unter die OS X Oberfläche um uns launchd anzuschauen. Ein gewisses Grundverständnis dieses Prozesses schadet nicht um hinterher die anstehenden Aktionen richtig konfigurieren zu können.

Technisch gesprochen ersetzt der launchd-Daemon die Routinen init, rc, die init.d- und rc.d-Scripte, SystemStarter, inetd und xinetd, atd, crond und watchdogd. Dadurch konnte der Systemstart - insbesondere auf älterer Hardware - merklich beschleunigt werden. launchd wird beim Booten unmittelbar nach dem Kernel und dessen Extensions als Prozess Nummer 1 gestartet und kann nachfolgende Prozesse initiieren. Ein einfacher Blick in das Dienstprogramm »Aktivitätsanzeige« und die Sortierung der Prozesse nach Hierachie zeigt dies deutlich:

aktivitaetsanzeige.jpg


Unmittelbar nach dem Kernel (0) läuft launchd (1) und alle übrigen Prozesse sind in Abhänigkeit von launchd. launchd ist also schon im Sinne der Hierachie ein Super-Dämon. Aber auch von seinem Leistungsspektrum her verdient er dieses Attribut, wie wir gleich sehen werden.

Unterscheiden wir zunächst einmal zwei grundlegende Konzepte für den Start von Prozessen. Dämonen (Daemons) und Agenten (Agents). Daemons starten Dienste, die permanent im Hintergrund laufen - sie sind beispielsweise für Serverdienste unerlässlich und bringen i.d.R. nicht mal eine Programmoberfläche mit. Agents dagegen starten ein Programm einmalig zu einem bestimmten Zeitpunkt oder auf ein bestimmtes Event hin. Sie können, müssen aber keine GUI haben.

Neben der Unterscheidung von Dämonen und Agenten wäre dann noch erheblich, wer diese Prozesse aufruf. Hier sind 3 Hierachien zu unterscheiden:

OS X selbst - systemeigene Prozesse, die entweder als Dämon oder Agent gestartet werden können. Faktisch sind an dieser Stelle (zumindest im Moment) nur Dämonen zu finden.
Prozesse die systemweit, unabhängig vom Benutzer wirken, aber nicht von OS X stammen
Benutzerspezifische Prozesse. Auch hier die Einschränkung: nur Agenten machen an dieser Stelle wirklich Sinn.
Demgemäß gibt es 5 Ordner im System die launchd überwacht und nach Aufgaben für sich durchsucht:

/System/Library/LaunchDaemons : hier sind OS X Daemons zu finden. Wie wir etwas weiter unten sehen werden, sogar reichlich!
/System/Library/LaunchAgents : im Gegensatz dazu findet sich hier nichts. Aber theoretisch hätte Apple hier die Möglichkeit Programme zu hinterlegen, die bei Anmeldung irgendeines Benutzer ausgeführt würden
/Library/LaunchDaemons : hier werden vom Admin eigene Dämonen einstellt, die beim Start des Rechners und ohne das eine Benutzeranmeldung notwendig ist ausgeführt werden.
/Library/LaunchAgents : hier werden Programmaufrufe platziert, die beim Login irgendeines Benutzers gestartet werden.
~/Library/LaunchAgents : die Tilde verrät es - hier finden sich Programmaufrufe die dem jeweiligen eingeloggten Benutzer zugeordnet sind.
Die beiden ersten lassen wir mal außen vor, da sie soz. Apples Hoheitsgebiet sind. Man kann hier eingreifen, aber man sollte sehr genau wissen, was man an dieser Stelle tut!

Mit diesem Hintergrundwissen ausgestattet ergeben sich beim Blick auf das geöffnete Lingon gleich ein paar Aha-Effekte. Exakt die oben beschriebene Struktur von Ordnern findet sich in Lingon unter den Reitern, allerdings in umgekehrter Reihenfolge:

My Agents = ~/Library/LaunchAgents
Users Agents = /Library/LaunchAgents
Users Daemons = /Library/LaunchDaemons
System Agents = /System/Library/LaunchAgents (das leere, theoretische ;))
System Daemons = /System/Library/LaunchDaemons

lingon.jpg


Die Ziffern hinter den Rubriken bezeichnen die Anzahl der darin zu findenden Einträge. Über ihren Zustand - gestartet oder nicht - sagen die Zahlen noch nichts aus. Entsprechend bestätigt sich, das System Agents, wie oben schon angesprochen, keine nachfolgende Ziffer enthält, also leer ist.

Beim versuchten Wechsel in den Reiter "SystemDaemons" warnt Lingon sehr drastisch vor den möglichen Folgen.

warnung.jpg


Mit dem heiligen Versprechen »nur gucken, nicht anfassen« bestätigen wir das »OK« und finden eine reichliche Liste von Diensten die OS X verwaltet und - z.T. je nach Einstellungen unsererseits - gestartet hat oder eben auch nicht:

systemdaemons.jpg


Wie man sehen kann, sind die eigentlich durch launchd ersetzten Prozesse atd (com.apple.atrun) und cron (com.vix.cron, com.apple.periodic-daily, -monthly, -weekly) durchaus noch mit an Bord. Cron wird sogar aus Gründen der Abwärtskompatibilität sogar noch mitgestartet.

Gehen wir lieber wieder in die unverfänglichere Abteilung der User Daemons. Bei mir finden sich dort auf meinem Clientrechner 3 Einträge.

userdaemons.jpg


Schauen wir uns einmal exemplarisch den ersten Eintrag en detail an:

lsd1basic.jpg


Über das Label bekommen die aufzurufenden Prozesse eine eindeutige Kennung. Es wird empfohlen, die umgekehrte Domain-Notation zu verwenden. Im vorliegenden Fall geht es um den Systemstart von Little Snitch von Objetive Development aus Wien. Entsprechend lautet der Eintrag »at.obdev.littlesnitchd«. Würden wir hier für uns einen Eintrag erstellen wollen, könnte dieser z.B. »local.rechnername.prozessname« heissen. Unter diesem Namen, erweitert um .plist finden sich dann die XML-Dateien in den entsprechenden Ordnern - hier eben in /Library/LaunchDaemons.

finderpendant.jpg


Unter ProgramArguments finden sich die Einträge für den Aufruf das zu startenden Dämonen. Sofern weitere Schalter, Parameter und Argumente anzufügen wäre, sind pro Eintrag eine Zeile zu erzeugen. Also: für jedes Leerzeichen auf der Kommandozeile ist hier durch das "+" eine neue Zeile zu erzeugen. Ein Beispiel wäre der Aufruf von Fetchmail: Die Befehlszeile

/usr/bin/fetchmail -f /etc/fetchmailrc -L /var/log/fetchmail.log -d 300

also: starte das Programm /usr/bin/fetchmail im Daemon-Mode (-d), nutze die Konfigurationdatei (-f) /etc/fetchmailrc und schreib den Logfile (-L) nach /var/log/fetchmail.log und frage die Mails alle 5 Minuten (=300 sec., also die 300 am Ende) ab, wäre unter ProgramArguments wie folgt

/usr/bin/fetchmail
-f
/etc/fetchmailrc
-L
/var/log/fetchmail.log
-d
300

auf insgesamt 7 Zeilen zu verteilen.

Die nachfolgenden Ankreuzfelder erklären sich von selbst. Starte nicht (Disabled), beim Hochfahren (RunAtLoad) oder bedarfsweise (OnDemand). Alternativ zu ProgramArguments könnte der komplette Aufruf inkl. aller Argumente auch unter Program eingetragen werden. Aus Gründen der Übersichtlichkeit empfehle ich aber ProgramArguments. Die ServiceDescription ist ein Klartext, der lediglich als Kommentar zu verstehen ist.

lsd2misc.jpg


Auch wenn die zweite Seite der Einstellungen im vorliegenden Fall von LittleSnitch leer ist, bietet Sie doch ein paar sehr interessante Erkenntnisse für unsere spätere Arbeit. Die Angabe eines StartIntervals macht aus einem Programm sozusagen einen Quasi-Daemon. Auf diese Weise kann ich einen bestimmten Prozess wiederkehrend in einem fixen Abstand - alle 5 Minuten, alle 24 Stunden etc. aufrufen lassen. Noch weiter gehen die Möglichkeiten von StartCalendarInterval. Faktisch sind hier die gleichen Mechanismen wie unter cron zu finden. So können bestimmte zu Prozesse zu festen Zeiten ausgeführt werden, wichtig z.B. für Backups! Die Eingabe von 15-22-leer-1-leer würde dazu führen, das ein Prozess jeden Montag (1) um 22.15 Uhr ausgeführt würde. Leere Felder werden als Wildcard interpretiert. Würde die 1 für Montag leer bleiben, würde der Prozess an jedem Tag der Woche stattfinden. Einen entscheidenden Unterschied zu cron gibt es jedoch! Während cron sklavisch zur vorgegebenen Uhrzeit die Arbeit aufzunehmen versucht und im Falle eines abgeschalteten Rechners ebenso sklavisch nichts tut, holt launchd versäumte Arbeiten bei Wiederverfügbarkeit des Rechners nach!

Bauen wir uns doch selbst mal einen launchd-Job. Organisieren wir uns ein Backup unseres Homeverzeichnisses auf einem zentralen Server. Ein einfacher rsync-Aufruf soll die eigentliche Arbeit im Hintergrund erledigen:

rsync -Cavz /Users/meinuserkurzname meinserver.local:/Volumes/externePlatte/backup

Die Schalter bei rsync sorgen dafür, dass

-C gemäß den CVS-Regeln Dateien ausgeschlossen werden. Die Details sind auf der Manpage von rysnc nachzulesen, beispielsweise werden Dateien die auf *.bak oder *.old passen so ausgeschlossen.
-a der Archiv-Modus eingeschaltet wird. Damit werden z.B. auch die Unterverzeichnisse verarbeitet, Rechte, Eigentümer, Datum und andere Dateiattribute bleiben beim Kopieren unangetastet
-v der Verbose-Modus eingeschaltet wird, also reichlich Protokoll-Output über die Aktion erzeugt wird.
-z das Backup komprimiert wird.
Um einen regelmässigen Aufruf zu erhalten starten wir nun Lingon und erzeugen uns einen Eintrag unter "My Agents":

neuereintrag.jpg

backup1.jpg


Die Grundkonfiguration, wie oben schon exemplarisch beschrieben

backup2.jpg


Die Zeitsteuerung für das Backup

backup3.jpg


Die fertige XML-Struktur des launchd Aufrufs

Weiterführende Infos

Wikipedia Artikel zu launchd
launchd auf MacOSForge
Apple Developer Connection Infos zu launchd
Apple Developer Connection Doku zum Startup (.pdf, 505 kB)
MacMarks Seite zu launchd
AFP548 Artikel zu launchd
Google Video mit einem Vortrag des launchd Chefentwicklers
Webseite von Lingon
 

Anhänge

  • header.jpg
    header.jpg
    34,7 KB · Aufrufe: 1.404

quarx

Brauner Matapfel
Registriert
17.04.05
Beiträge
8.444
Vielen Dank für den ausführlichen Tipp! :)
 

stk

Grünapfel
Registriert
05.01.04
Beiträge
7.141
Moin,

wie ich eben sehe ist mir ein entscheidendes Häkchen abhanden gekommen und ein Dreher ist drin:

* bei dem rsync-Beispiel muß in der Basic-Konfiguration noch das "OnDemand" angehakt werden, damit der Aufruf zur passenden Uhrzeit erfolgt
* und da eben steckt der Dreher: zuerst wird die Minute, dann die Stunde eingetragen. Ergo würde mein Beispiel um 15:22 statt um 22:15 laufen o_O.

Gruß Stefan
 

robertmk

Normande
Registriert
04.09.07
Beiträge
583
zu beachten ist, dass man immer den kompletten Pfad angibt! Also anstatt rsync => /usr/bin/rsync. Ansonsten kappt es nicht. Ich persönlich mag cron lieber, auch wenn es nicht so eine schöne GUI hat. Cron hat den Vorteil, dass die Einträge als Benutzer ausgeführt werden und mehr Möglichkeiten für die Zeitkonfiguration bietet.
 

stk

Grünapfel
Registriert
05.01.04
Beiträge
7.141
Moin,

wenn Du (oder sonst wer) eine GUI für Cron braucht: Cronnix anschauen. Aber in der Tat: ein paar Sachen, wie die erweiterten Wildcards (also 1-5 in den Tage um die Arbeitstage MO - FR abzudecken) gehen launchd ab :(.

Gruß Stefan
 

pepi

Cellini
Registriert
03.09.05
Beiträge
8.740
zu beachten ist, dass man immer den kompletten Pfad angibt! Also anstatt rsync => /usr/bin/rsync. Ansonsten kappt es nicht. Ich persönlich mag cron lieber, auch wenn es nicht so eine schöne GUI hat. Cron hat den Vorteil, dass die Einträge als Benutzer ausgeführt werden und mehr Möglichkeiten für die Zeitkonfiguration bietet.

Lingon ist auch nur ein GUI um launchd items zu schreiben und zu verwalten. Technisch ist es nicht mehr als ein XML File und launchctl. Du kannst übrigens auch für launchd items angeben als welcher Benutzer sie ausgeführt werden sollen, dahingehend steht launchd cron um nichts nach.
Bei den Zeitkonfigurationen muß ich Dir bisweilen leider recht geben. Entgegen der man page von launchd sind die möglichen Zeitangaben doch nicht sooo much like crontab entries. Mal sehen ob sich das mit Leopard bessert.
Originellerweise wird ja cron unter 10.4 auch von launchd gestartet. :)

Ich bin immer noch auf der Suche nach einem hilfreichen CLI Assistenten der die Funktionalitäten von Lingon in einem curses Interface abbildet. (Ich schreib XML nicht so gerne von Hand.)


@stk
Du solltest bei Deinem rsync Backup übers Netzwerk auf Deinen Server noch ergänzen, daß dafür unbedingt SSH Hostkey Aauthentication notwendig ist. Sonst kann sich rsync als Transport nicht am Server anmelden. (Alternativ ist ein rsync Server notwendig, den wohl auch die wenigsten User betreiben werden.)
Gruß Pepi
 
Zuletzt bearbeitet:

Bier

Pomme au Mors
Registriert
24.08.07
Beiträge
867
Hat jemand da mal rumgefummelt und die Apple Sachen da rausgenommen... -> aua...

Noch mehr zu init-Systemen
Da gabs letztens nen netten Workshop, systemübergreifend, zu ;)
 

stk

Grünapfel
Registriert
05.01.04
Beiträge
7.141
Moin,

@stk
Du solltest bei Deinem rsync Backup übers Netzwerk auf Deinen Server noch ergänzen, daß dafür unbedingt SSH Hostkey Aauthentication notwendig ist. Sonst kann sich rsync als Transport nicht am Server anmelden. (Alternativ ist ein rsync Server notwendig, den wohl auch die wenigsten User betreiben werden.)

wo Du Recht hast … aber

a) wäre rsync mal ein komplett eigenes Thema in das ich mich
b) überhaupt mal etwas tiefer einarbeiten müßte.

Ich kenne aber jemanden aus Wien, der tolle Backup-Scripte auf der Basis von rsync schreibt und der sich deutlich besser damit auskennen dürfte als ich. Vielleicht schreibt der ja mal einen Artikel dazu (hint, hint) ;).

Gruß Stefan
 

pepi

Cellini
Registriert
03.09.05
Beiträge
8.740
[...]a) wäre rsync mal ein komplett eigenes Thema in das ich mich
b) überhaupt mal etwas tiefer einarbeiten müßte. [...](hint, hint) ;)[...]
Aaachtung, Apfeltalker (mit großem Zaunpfahl bewaffnet) treibt sein Unwesen im Geektip-Forum! :p Du kennst Leute...
Gruß Pepi
 

schnydi

James Grieve
Registriert
08.01.06
Beiträge
137
Mann euer wissen möchte man haben :):cool: Wieder mal eine reife Leistung!

Na dann bekommt man ja gerade Lust einmal mit launchd zu "spielen"

Ich mochte gerne mit launchd ein script ausführen. Die Anleitung dazu auf MacScripter.com.
Klappt ja alles wunderbar bar bis auf den Schönheitsfehler in der Console sehe ich dann
Code:
launchd[3535]: WatchingVolumesPath: 8 more failures without living at least 60 seconds will cause job removal
Funktionieren tut ja alles wie bereits gesagt. Aber eben dieser log eintrag muss nun wirklich nicht sein.
So sieht meine plist Datei
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>WatchingVolumesPath</string>
	<key>LowPriorityIO</key>
	<true/>
	<key>Program</key>
	<string>/usr/bin/osascript</string>
	<key>ProgramArguments</key>
	<array>
		<string>osascript</string>
		<string>/Library/Application Support/CineMac/etc/data/volumechecker.scpt</string>
	</array>
	<key>ServiceDescription</key>
	<string>Runs Applescript directly when Volumes Path changes</string>
	<key>StandardOutPath</key>
	<string>/Library/Application Support/CineMac/etc/data/volumecheck.txt</string>
	<key>WatchPaths</key>
	<array>
		<string>/Volumes</string>
	</array>
</dict>
</plist>

PS: Noch eine kleine Frage: mit launchctl load -w pfad_zur_datei lässt sich eine configurations Datei laden, aber wie kann ich sie eigentlich wieder "entladen" gemäs man pages sollte es mit unlolad pfad_zur_datei gehen, tut es aber nicht. Mit list sieht man den Prozess (WatchingVolumesPath) noch immer.
 

Xjs

Prinzenapfel
Registriert
04.10.07
Beiträge
547
Das ist auch ein super Tipp. Für die, die GUI-faul sind ;)
 

AgentSmith

Hochzeitsapfel
Registriert
15.07.07
Beiträge
9.304
Ich glaube, ich bin blind: Wie entferne ich denn in Lingon einen Agent?
 

stk

Grünapfel
Registriert
05.01.04
Beiträge
7.141
Moin,

auswählen, Backspace drücken, fertig

Gruß Stefan
 

AgentSmith

Hochzeitsapfel
Registriert
15.07.07
Beiträge
9.304
Geht nicht, da kommt nur der "Tastendruck an dieser Stelle unpassend"-Ton.
 

stk

Grünapfel
Registriert
05.01.04
Beiträge
7.141
Moin,

Unloaded muß der Agent auch sein:
unload.jpg


delete.jpg


erscheint jeweils, wenn ich das Teil mit Backspace zu löschen versuche.

Gruß Stefan
 

AgentSmith

Hochzeitsapfel
Registriert
15.07.07
Beiträge
9.304
Nur um sicher zugehen: Backspace ist bei uns beiden die Taste über Enter, oder? ;)
Bei mir passiert da wirklich nichts, egal ob ich einen eigenen oder irgendnen beliebigen anderen Agent markiere.. es kommt nur der Ton. :-?
 

MacMark

Jakob Lebel
Registriert
01.01.05
Beiträge
4.874

<key>Label</key>
<string>WatchingVolumesPath</string>

PS: Noch eine kleine Frage: mit launchctl load -w pfad_zur_datei lässt sich eine configurations Datei laden, aber wie kann ich sie eigentlich wieder "entladen" gemäs man pages sollte es mit unlolad pfad_zur_datei gehen, tut es aber nicht. Mit list sieht man den Prozess (WatchingVolumesPath) noch immer.

[sudo] launchctl stop WatchingVolumesPath

a) Definitionladen und Dämonstarten ist unterschiedlich.
b) Richtige Instanz von launchd ansprechen
http://www.macmark.de/osx_launchd.php#launchctl
 

MetalSnake

Gala
Registriert
16.03.07
Beiträge
53
Nur um sicher zugehen: Backspace ist bei uns beiden die Taste über Enter, oder? ;)
Bei mir passiert da wirklich nichts, egal ob ich einen eigenen oder irgendnen beliebigen anderen Agent markiere.. es kommt nur der Ton. :-?

Über Enter ist die Plus Taste, Backspace befindet sich über Return.
 

AgentSmith

Hochzeitsapfel
Registriert
15.07.07
Beiträge
9.304
Oh, ich hatte die beiden Bezeichnungen bisher synonym verwendet, Danke für die Begriffsklärung. Jedenfalls meinte ich dann mit Backspace schon die richtige. Bei mir klappt das nach wie vor nicht, ich kann einfach keine Agents mehr löschen. Macht nicht wirklich was, da ich sie ja Disablen kann, aber ein wenig blöde find ichs schon. o_O
 

MacMark

Jakob Lebel
Registriert
01.01.05
Beiträge
4.874
… Bei mir klappt das nach wie vor nicht, ich kann einfach keine Agents mehr löschen. Macht nicht wirklich was, da ich sie ja Disablen kann, aber ein wenig blöde find ichs schon. o_O
Ein Grund, warum ich von solchen Tools nichts halte. Man weiß nicht, was passiert, wenn man des Knöbbsche drigge dut. Und wenn man es wüßte, dann bräuchte man das Duuhl auch nüscht. Ein weiterer Grund ist, daß es gefährlich ist, wenn man jedem Laien das Rumfummeln am "Process 1" per Knöbbschedrigge erlaube dut.
Gombjuder-Raum

Achdung!!
Dieser Raum is voll bis unner de Deck
mit de dollste elekdrische unn vollelekdronische Anlaache.
Staune un gugge derf jedder,
awer romworschtele un Gnöbsche drigge
uff de Gombjuder dörfe nur mir, die Experde.