Eida.cz - Balíčky a plánované spouštění pro lenochody

Balíčky a plánované spouštění pro lenochody

Eida

 Už dlouho se nijak netajím tím, že mi úplně nevýslovně vadí, jak mnozí nagelovaní inteláčtí switcheři používají Mac a naprosto nerozumí UNIXu pod jeho křídly. Na druhou stranu se krom jejich vlastní demence a totální lenosti se něco třeba naučit není zas tolik čemu divit, OS X je totiž celkově navržen pro superjednoduché přímočaré používání a víceméně není důvod se v něm při běžných činnostech nijak extra vrtat, jako to často bývá v některých upatlaných linuxových distribucích.

Přesto existují situace, kdy je potřeba se podívat trochu víc pod tu kouzelnou slupku - ale nemusí to nutně být zrovna assemblerová krutopárty za účelem crackování PowerPC-PEF v Rosettě, může to být klidně zdánlivě snadný pokus zajistit rozumné periodické spouštění nějaké vlastní úlohy, řekněme třeba zasílající řídící informace nějakému démonovi pod rootovskými právy.

Takovým tím naivním řešením je v tomto případě samozřejmě možné využít klasický cron. V principu je cronová tabulka roota ve výchozím stavu úplně čistá, vyvolat se dá přes sudo crontab -e. Na tom není na vysvětlování pořád nic složitého, ovšem překvapení přijde v okamžiku, kdy na BFU vyskočí místo očekávaného “editoru” prostě a jednoduše vim. Haha, nojo, v tom takový běžný uživatel dneska už psát neumí a jen ho na dálku navigovat, že se z toho leze přes :q je skoro mimozemský úkol. To za to nestojí. Obecně dobrý nápad je taky si tabulku lokálně uložit (asi nejlépe v tomto případě do /var/root/.crontab) a pak ji pokaždé instalovat jako crontab .crontab, protože klávesy E a R jsou zatraceně blízko sebe a jeden by nevěřil, jak snadno se stane velká nehoda. Syntaxe cronového souboru je na každý řádek minuta, hodina, den, měsíc, den v týdnu (0-6) a příkaz, další zajímavosti o něm jsou v manpages a dokonce i na wiki. Ale to nikdo stejně číst nebude.

Nehledě na to, jak je to složité pro smrtelníky, je to taky bohužel i pěkně zastaralé. Mimo jádro je totiž v Mac OS X další brutálně zajímavou komponentou, pochopitelně taky dostupnou jako opensource, launchd. Je to chytrý spouštěcí démon, co kompletně nahradil původní UNIXový init a je zodpovědný vlastně za všechno, co se v systému děje. Víceméně. Dá se bezvadně řídit a využívat, čímž dodává onu zmiňovanou think-different superjednoduchost; cenou za ni je ovšem konfigurace každé úlohy ve vlastním XML. Ono se totiž téměř všechno konfiguruje v XML s šílenými Applími DTD, kterým se říká property lists. PListy pro launchd úlohy jsou defaultně v /Library/LaunchDaemons/. Výše zmiňovaný příklad, který by mohl být realizovaný spouštěním perzistentního shellového skriptu každou hodinu, by mohl vypadat zřejmě následovně.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>cz.eida.Test</string>
	<key>ProgramArguments</key>
	<array>
		<string>/bin/sh</string>
		<string>/var/root/cz.eida.Test/test.sh</string>
	</array>
	<key>StartInterval</key>
	<integer>3600</integer>
	<key>WorkingDirectory</key>
	<string>/var/root/cz.eida.Test/</string>
</dict>
</plist>
Spouštění skriptu každou hodinu

Velkou výhodou launchd oproti cronu je intervalové spuštění úlohy - zajistí tedy její spuštění v nejbližší možné době od posledního spuštění a ne až v okamžik, kdy udeří konkrétní časový signál. Každá celá hodina v cronu by mohla být zapsaná jako 0 * * * * skript.sh, přičemž by se mohlo stát, že k počítači přijdeme a probereme ho ze spánku v jednu minutu po celé, a to už může být pozdě - proti tomu si právě launchd z paměti umí spočítat, že poslední spuštění proběhlo před 3660 sekundami, takže příkaz prostě a jednoduše odpálí a začne zase počítat sekundy znovu.

Tohle se už dá nějak předat, zkopírovat, poslat. Teoreticky. Pořád je tu ale riziko, že by to mohl někdo pokonit, hlavně pokud nemá zkušenosti s přepínáním účtů, oprávěními a změnou vlastnictví souborů. Přišla pak taková myšlenka zkusit to nějak automatizovat, vyloženě využít všech BFU možností přímočarosti OS X, až to doslova pěkné nebude. A pro takový úkol je jako stvořený bálíčkovač - stvořitel installeru aplikací (pkgbuild). Je součástí Xcode a jeho použití je neuvěřitelně jednoduché a veselé.

Podle původního příkladu/myšlenky výše budeme uvažovat, že vytoužený intervalově spouštěný shellový skript musí být spouštěný a umístěný zvlášť a musí být persistentní, přestože žádné jiné skutečné sobory - aplikace - vytvářet nebudeme, namísto toho použijeme vlastní adresář přímo v domovském adresáři roota. Taktika to sice není úplně nejlepší, ale alespoň se to tam neztratí a jako ručně řízená služba je to celkem, dá se říct, rozumné. Instalátor by tedy měl umět zajistit

  1. Vytvoření tohoto skriptu v zadaném umístění
  2. (vytvoření kopie .plistu tamtéž, kdyby náhodou)
  3. instalaci .plistu do /Library/LaunchDaemons/
  4. prvotní natažení do launchd
  5. a rovnou první spuštění

Někde v pracovním prostoru uděláme pro přehlednost dva separátní adresáře, jeden pro instalované soubory (například payload) a druhý pro konfigurační skript (scripts). Tento skript se bude jmenovat postinstall bez jakýchkoliv přípon a především se u něj nesmí zapomenout na +x, protože je to taky jenom skript přece a musí se nějak umět spustit. Při dodržení všech dosud zmíněných uvedených předpokladů bude uvnitř skrývat následující řádky.

postinstall.txt 182 bajtů
#!/bin/sh
cp /var/root/cz.eida.Test/cz.eida.Test.plist /Library/LaunchDaemons/cz.eida.Test.plist
launchctl load /Library/LaunchDaemons/cz.eida.Test.plist
launchctl start cz.eida.Test
scripts/postinstall

V tuhle chvíli zbývá už jen dát volnou ruku procesu vytvoření instalačního balíčku. Ten se dá zavolat i s omezenými právy jako pkgbuild. Uvedeme identifikátor balíčku --identifier cz.eida.Test.pkg, jeho verzi --version 1.0, specifikujeme jaké soubory a kam je budeme instalovat --root ./payload --install-location /var/root/cz.eida.Test/ a připojíme konfigurační skripty --scripts ./scripts. Výstup si můžeme hodit třeba na plochu jako poslední parametr - ~/Desktop/testovací-instalátor.pkg.

Spuštěný instalátor

Teď už se to dá někomu opravdu poslat. Dotyčný si na balíček pak jen jednoduše poklepe, vyplní heslo pro získání superuživatelských práv a instalace zařídí zbytek - umístění skriptu a zajištění jeho spouštění v požadovaném intervalu. Think different, neasi.

Tento článek přečetlo již 305 čtenářů (0 dnes).

Komentáře

Nový komentář