Typicky bulvární titulek, ale v tomto případě jsem si ho nemohl
odpustit, jelikož cituji přímo blog
vývojáře. Kdo neví, Paludis je alternativní balíčkovací
systém s podporou více formátů, momentálně ebuildů pro
distribuce Gentoo a Exherbo. Vývoj se žene kupředu rychlostí blesku a již
před rokem jím bylo bez větších problémů možné z velké části
nahradit současný Portage. Vývojáři však nyní uvedli nový
klientský program cave, který by měl jednou provždy umlčet
věčné flamewary ohledně příkazové nekompatibility mezi těmito
systémy.
Paludis, paludis a paludis
Paludis již od počátku disponoval klientským programem
paludis, na kterém jsme všichni společně vyrostli a vžili si
do paměti příkazy typu:
paludis -pi world
paludis --dl-blocks discard -i world
A nebo mé oblíbené:
paludis -pu --with-unused-dependencies --permit-unsafe-uninstalls cat/some-pkg
… a oni nám to chtějí zrušit!
Představuje se cave
Dle mého názoru naprosto nevhodně zvolené jméno programu, ale jinak
cave vypadá mnohem robustněji a elegantněji. Elegance na nás
srší již od prvního pohledu, kupříkladu příkaz install
neexistuje, jmenuje se resolve. A když se chceme podívat do
nápovědy, cave resolve --help vypíše neuvěřitelných
151 řádků! V tom aby se prase vyznalo, je tedy lepší
používat man. Manuálovým stránkách dávám bod za
rozčlenění, další krátkému příkazu help za jednoduchý a
stručný výpis nejčastějších funkcí. Mile mě potěšil
fix-linkage, díky kterému je vyřazen další klient, a to
reconcilio. Pamatuji si, jak jsem prvních několik měsíců
používání Paludise měl neskutečný problém vzpomenout si na ten
připitomělý název, abych opravil špatné linkování knihoven. Příkaz
purge zjednodušuje původní paludis -u
--uninstall-unused, hlavně je hned v základní nápovědě, a tak ho
člověk nemusí hledat kdesi v manuálu. Za zmínku už snad stojí jen
sync, uninstall a search, jehož
hledání je snad ještě zdlouhavější než dřív – a u toho se
zastavím, odjakživa je nepoužitelné.
Obecná vsuvka o vyhledávání
Vyhledat jeden balíček mi trvá přibližně 5 minut, takže kešovaná
SQLite databáze v programu eix je k nezaplacení. Stále se
ptám, proč při operacích hledání Paludis kontroluje strukturu
všech ebuildů a ještě k tomu drze vypisuje, abych
přepsal řádek se SLOT="0" na SLOT=""? K čemu mi
to je, běžnému uživateli? To si snad tohoto problému vývojáři nevšimli
a nebo je to jen hluboký defekt ext3
filesystému v kombinaci s mým strojem, diskem či tak?
Závěrem
Před pár dny vyšla nová verze Paludise, která oficiálně publikovala
i výše zmíněný cave. Zhruba hodinu jsem studoval dokumentaci
a možnosti tohoto klienta a nakonec upravil svůj synchronizační skript tak,
aby ho používal. Na závěr uvádím ukázky nové příkazové syntaxe
včetně starších ekvivalentů:
cave sync || paludis -s --multitask
cave resolve -c world || paludis -pi world
cave resolve -cx world || paludis -i world
cave fix-linkage || reconcilio
Nutno podotknout, že při updatu world oba klienti řeší
závislosti trochu odlišně. To ostatně možná zjistíte sami hned při
prvním použití :)
Odkazy
Štítky:
Tipy a triky
GNU Screen je textový skoro window manager umožňující uchování
otevřených terminálů uvnitř jediného okna s možností použití jako
vzdálené session. Jednoduše řečeno, vezmu-li SSH spojení, screen udrží
spuštěné např. irssi, centerim, SSH na další
stroj a mnohem více.
Bohužel ve výchozí konfiguraci je poněkud nešťastný, protože ihned
nevidíte např. otevřená okna nebo ve kterém okně momentálně jste. Navíc
jsou některé klávesové zkratky nepřirozené, a proto jsem kdysi začal
zkoumat manuál a možnosti konfigurace. Naneštěstí jsem dlouho nebyl
úspěšný. Nakonec mi však kamarád Jedjisch poslal svůj konfigurační
soubor, který téměř vyřešil veškeré mé problémy.
Celý konfigurační soubor se do článku nevejde, proto prosím použijte
odkaz pro stažení na konci článku. Za zmínku stojí přemapované klávesy
pro aktivaci okna 0 a 10, ke kterým se na české klávesnici přistupovalo
špatně, upravený řádek hardstatus, který na spodním řádku
screenu ukazuje barevně výpis oken (barevné kódy dalo práci zjistit,
nakonec vyhrála metoda pokus-omyl), nastavení monitorování aktivity a
výchozího okna v posledních řádcích souboru.
Konfigurační soubor je k dispozici zde.
Přejmenujte na .screenrc a umístěte do domovského adresáře.
Pro načtení do již běžícího screenu použijte příkaz:
^a :source ~/.screenrc
kde ^ značí klávesu Control.
Štítky:
Tipy a triky
K tomuto nápadu mě kdysi přivedl kamarád Chytrex během jednoho z mnoha
povídání o své náplni práce. Ve stručnosti, přijde tiket
(v konkrétním příkladu mi byl ukázán řádek ze systémového logu), a
jeho úkolem je problém vyřešit. A to mi vnuklo nápad nechat si zasílat
problémy ze syslogu na e-mail.
Chvíli jsem googlil a nakonec našel jednoduchý perl skript (zdroj již
bohužel neznámý), který se nechá pouštět od syslog-ng a hloupě
přeposílá zprávu přes sendmail. Několik let mi to takto
stačilo, ale pak mě začaly obtěžovat zprávy s nesmyslně vysokou
facility (prioritou) bez jakékoli informační hodnoty.
Rekompilovávat upravené zdrojové kódy několika balíčků mě po chvilce
přestalo bavit, a tak jsem skript obohatil o pár řádků s podporou
klíčových slov k vyloučení (viz pole @exclude).
#!/usr/bin/perl -n
# thanks to Brian Dowling for an example with security in mind.
$TO = 'admin@dragonjake.net';
$FROM = 'system@dragon.dragonjake.net';
@exclude = ("_nss_mysql_getspnam_r conf file parsing failed", # nss-mysql
"Statement may not be safe to log in statement format", # mysql-server
"Error getting poly dir context, No data available", # pam
"sshd.+(already in use|cannot listen to port)", # sshd
"pam_namespace.+Unmount" # pam
);
foreach $item (@exclude) {
if ($_ =~ m/$item/i == 1) {
exit;
}
}
s/^<\d{1,2}>//;
open(MAIL, "|/usr/sbin/sendmail -t -i");
print MAIL << "EOT";
To: $TO
From: $FROM
Subject: Log Alert: $_
$_
EOT
close(MAIL);
Skript by sám o sobě nefungoval, a tak je potřeba syslog-ng
sdělit, že ho chceme používat. Vlastní filtry f_grsec a
f_nmail používám pro omezení zbytečného spamu generovaného
grsec patchem a mailserverem. Představte si totiž případ, kdy se
mailserver rozbije a syslog-ng začne jeho chybové hlášky ukládat
jako e-maily k odeslání. Výsledkem je téměř nekonečná smyčka chyb a
fronta přesahující velikost několika tisíců e-mailů. Konfigurace
v útržcích vypadá následovně:
...
# e-mail alert
destination da_admin { program("/home/bin/syslog-alert.pl"); };
...
# ignore grsec spam
filter f_grsec { not match("grsec"); };
filter f_nmail { not facility(mail); };
...
# e-mail alert with at least err priority
log {
source(s_all);
filter(f_grsec);
filter(f_nmail);
filter(f_at_least_err);
destination(da_admin);
};
Filtr f_at_least_err je v mé distribuci (Debian, Ubuntu)
nativně, pro jistotu uvedu jeho definice:
filter f_at_least_err { level(err..emerg); };
Štítky:
Tipy a triky
Stává se vám, že se při práci emulátor terminálu zasekne? Nereaguje,
bušení do klávesnice nepomáhá a jediná možnost je tvrdý
kill? Možná jste omylem narazili na kouzelnou klávesovou zkratku
Ctrl+S…
Proč?
Zkratka Ctrl+S (dále jen ^S) a její opačný
ekvivalent Ctrl+Q (dále jen ^Q) řídí funkce
takzvaného flow control, v překladu řízení toku.
V dobách minulých a již dávno zapomenutých totiž neexistovaly emulátory
terminálů. Hádáte správně, byly pouze terminály. Takový terminál je
obecně vzato kus hardware s monitorem, klávesnicí a komunikačním portem
(foto).
Terminál se pak připojí k cílovému počítači a práce může začít.
Avšak aby komunikace mohla probíhat správně, je potřeba definovat protokol.
A zde přichází kámen úrazu. Řízení toku musí být implementováno
oběma komunikujícími stranami, což je splněno i v dnešní době na nám
moc dobře známých softwarových emulátorech.
Jak se toho zbavit?
Obecně vzato, příkaz ^S potlačuje výstup a příkaz
^Q toto potlačení ruší. Někteří by mohli namítat, ale je
důležité si uvědomit, že výstup v chápání terminálu znamená
i vytištění napsaného textu. Proto se ^S chová, jako by
způsobil úplné zamrznutí.
Naštěstí je řešení jednodušší, než by se mohlo zdát. Černou magii
odstraní příkaz:
stty -ixon -ixoff
Tento řádek doporučuji umístit do .bashrc či do jiného
souboru vykonávaného při inicializaci vašeho oblíbeného shellu.
Odkazy
Štítky:
Tipy a triky
Po updatu na CyanogenMod 4.2.7 se mi v trayi telefonu opět
objevila nepříjemná ikonka signalizující nedostatek místa v interní
paměti telefonu. Na tom by nebylo zas až tak nic špatného, kdyby mi
z nenadání přestala fungovat synchronizace a download aplikací v Marketu.
Obětoval jsem celé odpoledne na to, abych zjistil, že onu nefunkční
synchronizaci má za následek právě nedostatek místa, na který jsem byl
non-stop upozorňován. Takže co s tím?
Apps2sd
Řešení integrované přímo do CyanogenModu spočívající
v jednoduchém shell skriptu, který pří bootu telefonu na základě
předpokládané existence druhého diskového
oddílu na SD kartě tento oddíl použije a přesune na něj veškeré
nainstalované aplikace a data s nimi související. Nevýhodou je předchozí
úprava karty pomocí nástrojů na dělení disku a naformátování na
linuxový filesystém ext2/3/4. Za odměnu ale dostanete přenositelné aplikace
i s nastavením.
Skript pracuje zcela automaticky, tudíž stačí jen mít připravenou
partition.
Mé vlastní řešení
Přišel jsem na něj doslova metodou pokus-omyl. Při šťourání se
v datové partition jsem si všiml adresáře /data/dalvik-cache,
který zabíral úctyhodných 40 MB a tím pádem byl ihned nominován za
největšího žrouta místa. Tento adresář slouží běhovému prostředí
Dalvik VM jako cache optimalizovaného bytekódu, jinými slovy jako
úložiště překompilovaných a upravených binárek používaných aplikací.
Do detailu Dalvik buduje strom závislostí jednotlivých tříd (funkčních
celků aplikace) tak, aby nainstalovaná aplikace běžela co možná nejlépe.
Tento strom je regenerován při každé aktualizaci ROM, proto první boot po
updatu trvá i několik minut.
Dalším zajímavým místem je adresář /cache, který je
stále téměř prázdný. V dosavadním Androidu je použit výhradně jako
dočasné úložiště pro stahované aplikace v Marketu, jenže v poměru
velikosti celé parititon (~60 MB) a jednoho stahovaného balíčku (řádově
jednotky MB) je až škoda toto místo nevyužít. Proto jsem si napsal krátký
skript, který dalvik-cache přesune do tohoto volného
prostoru.
#!/system/bin/sh
# move dalvik cache from internal data memory to /cache
if [ ! -d /cache/dalvik-cache ];
then
mkdir /cache/dalvik-cache
fi
busybox chown 1000:1000 /cache/dalvik-cache
busybox chmod 771 /cache/dalvik-cache
if [ -d /data/dalvik-cache ] && [ ! -h /data/dalvik-cache ];
then
busybox cp -a /data/dalvik-cache/* /cache/dalvik-cache
busybox rm -f /data/dalvik-cache/*
# bind mount dalvik-cache
busybox mount -o bind /cache/dalvik-cache /data/dalvik-cache
Tento skript stačí umístit např. jako /etc/init.d/06custom.
Toho můžeme efektivně docílit vytvořením souboru na SD kartě a
následným zkopírováním do systému těmito příkazy:
mount -o remount,rw /system
cp /sdcard/06custom /etc/init.d
chmod 755 /etc/init.d/06custom
… a pokračovat rebootem telefonu.
Pokud jste vše udělali správně, máte nyní v interní paměti (aka
/data) okolo 40 MB volného místa. Povedlo se!
Pozn.: Uvedený postup je třeba opakovat po každém updatu ROM, kdy
dojde k přepsání systémové partition a tedy i vlastního skriptu.
Doporučuji proto skript na SD kartě ponechat a před bootem
do updatlé ROM spustit konzoli a zopakovat příkazy uvedené výše.
Štítky:
Tipy a triky
Trocha teorie
Dlouholetým problémem UNIXově
založených operačních systémů je adresář /tmp sloužící
jako dočasné úložiště pro všechny. Tento adresář má práva nastavená
na rwxrwxrwx, tedy zápis pro kohokoli. Nevýhodou však byl
i absolutní přístup k datům jiných uživatelů, a proto byl zaveden tzv.
sticky bit, který omezuje zápis pouze na soubory a adresáře
vlastněné patřičným uživatelem. Každý tedy může zapisovat nové
soubory, ale jen do těch existujících, které vlastní.
Novou možnost fyzické separace pak nabízí tzv.
polyinstantiation. Každému uživateli namapuje daný adresář na
jiný, pro něj v původní cestě nepřístupný. V případě adresáře
/tmp by se např. jednalo o mapu z /tmp-inst nebo
klidně i /tmp/users. Mechanismus, který polyinstancování
zajišťuje, automaticky vytvoří adresář dle uživatelského jména a jím
nahradí cílový adresář dle mapy.
Ukázka z praxe
Nastavení se provádí v konfiguračním souboru
/etc/security/namespace.conf prostřednictvím PAM modulu
pam_namespace.so:
# /etc/security/namespace.conf
#
# See /usr/share/doc/pam-*/txts/README.pam_namespace for more information.
#
#/tmp /tmp-inst/ both root,adm
#/var/tmp /var/tmp/tmp-inst/ both root,adm
#$HOME $HOME/$USER.inst/inst- context
/tmp /tmp/users/ user root
Zakomentované příklady zahrnují polyinstancing /tmp,
/var/tmp (který osobně doporučuji nastavit jako symbolický
odkaz do /tmp) a domovského adresáře uživatele. Důležitý
parametr je typ, který zpravidla může být:
- user (na základě uživatelského jména)
- context (na základě bezpečnostního kontextu, pouze
SElinux)
- both (obojí)
Poslední čtvrtý parametr udává výjimky. V mém případě bude na
základě uživatelského jména namapován adresář /tmp z
/tmp/users s výjimkou uživatele root.
Jak na to
Nejprve vytvoříme adresář, ze kterého budeme mapovat, v mém případě
/tmp/users. Tomuto adresáři nastavíme z bezpečnostních
důvodů nulová práva a zadáme mapu
v konfiguračním souboru /etc/security/namespace.conf.
Nyní je třeba pečlivě zvážit nastavení modulů PAM. Po zkušenostech
z praxe nedoporučuji spouštět PAM modul ve
všech případech autentizace (soubor
/etc/pam.d/common-session, způsobí to více problémů než
užitku. Polyinstancování jsem proto zúžil na dva jediné typy
autentizace – login a sshd.
Ukázka začlenění PAM modulu do souboru s autentizací:
# Enable polyinstantiation
session required pam_namespace.so
Je třeba dát si pozor na to, kam modul umístíme. Existují místa, kdy je
moc brzy a kdy zase moc pozdě – lepší je si to párkrát zkusit a pozorně
sledovat logy (např. auth.log). Pokud se mechanismus aplikuje,
měli bychom po novém přihlášení mít adresář /tmp
v ideálním případě prázdný. Přihlásíme-li se na roota, měli bychom
vidět /tmp/users a v něm adresář s naším a případně
dalšími uživatelskými jmény. Máme hotovo.
Osobně mám přímé přihlášení na root uživatele zakázané a
přistupuji přes sudo. Bohužel v tomto případě se mi nepodařilo sudo
nijak donutit vyvolat čistý login (nejspíše proto, že sudo je spouštěno
z shellu, na který již bylo polyinstacování aplikované), takže ani po
přihlášení na roota mi /tmp neodhalil žádná svá tajemství.
Pokud nedejbože nutně potřebuji vidět obsah neořezaného /tmp,
obejdu bezpečnostní mechanismus mountnutím root partition např. do
/mnt a podívám se tam :)
Štítky:
Tipy a triky
Standardní chybové hlášky v Apachi jsou z informativního charakteru
naprosto dostačující, avšak z toho estetického nikoli. Kdekoho posléze
napadne, jak tyto chybové hlášky přenastavit. Na tom samozřejmě není nic
těžkého, stačí vhodná úprava do souboru .htaccess typu:
ErrorDocument 404 /neexistuje.html
Mít pro každý kód chyby jinou stránku je pak zbytečně komplikované.
Naštěstí existuje řešení, jak různé kódy efektivně zpracovat na
úrovni PHP. Základní zjednodušené nastavení souboru .htaccess
pak bude vypadat obdobně:
ErrorDocument 400 http://400.dragonjake.net
# speciální hack pro 401 Authorization Required
Alias /401/ /var/www/html/
ErrorDocument 401 /401/index.php
ErrorDocument 403 http://403.dragonjake.net
ErrorDocument 404 http://404.dragonjake.net
ErrorDocument 500 http://500.dragonjake.net
Ve svém řešení využívám externí http:// adresy pro
jednotlivé kódy zvlášť, v Apachi nastavené zhruba takto:
<VirtualHost *:80>
ServerName dragonjake.net
ServerAlias 400.dragonjake.net 403.dragonjake.net 404.dragonjake.net 500.dragonjake.net
DocumentRoot /var/www/html
</VirtualHost>
V adresáři /var/www/html se nachází nejočekávanější
soubor, skript index.php, který chybové kódy zpracovává.
Klíčová je superglobální proměnná
$_SERVER['REDIRECT_STATUS'], která vrací HTTP stavový kód,
podle kterého následně skript rozlišuje typ chyby.
Bohužel pro chybu 500 nevrátí proměnná z nepochopitelných důvodů
nic. Skript používám i jako výchozí lokaci pro požadavky, které
neodchytne žádný <VirtualHost>, např. když někdo zadá
přímo IP adresu do prohlížeče. Zjištění chyby jsem tedy oprasil díky URL přes
regulární výraz.
if (empty($code)) {
preg_match('~(\d+)\.dragonjake\.net$~', $_SERVER['HTTP_HOST'], $m);
$code = $m[1];
}
Úmyslně ve své implementaci nepoužívám žádný výpis URL adresy,
která se běžně u podobných chybových hlášení objevuje. Zvědavcům
napovím, že se jedná o proměnné $_SERVER['REQUEST_URI'] a
$_SERVER['REDIRECT_URL']. Na závěr přikládám celý kód
„chybového“ skriptu.
if (empty($code)) {
preg_match('~(\d+)\.dragonjake\.net$~', $_SERVER['HTTP_HOST'], $m);
$code = $m[1];
}
switch ($code) {
case 400:
$h = '400 Bad Request';
$t = 'Err... what did you say?!';
break;
case 401:
$h = '401 Authorization Required';
$t = 'You haven\'t given me a gold!';
break;
case 403:
$h = '403 Forbidden';
$t = 'Step back before you get eaten!';
break;
case 404:
$h = '404 File Not Found';
$t = 'Are you looking for something?!';
break;
case 500:
$h = '500 Internal Server Error';
$t = 'Whops! Something got wrong!';
break;
default:
$h = '';
$t = 'Server is up and running.';
}
if (!empty($h))
header($_SERVER['SERVER_PROTOCOL'] . ' ' . $h, TRUE, $code);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xml:lang="cs" lang="cs" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta http-equiv="content-language" content="cs" />
<meta name="author" content="Dragon Jake; e-mail: admin@dragonjake.net" />
<meta name="copyright" content="© 2006 Dragon Jake" />
<meta name="robots" content="noindex,nofollow" />
<link rel="stylesheet" type="text/css" href="/401/main.css" />
<link rel="shortcut icon" type="image/x-icon" href="/401/favicon.ico" />
<title><?php if (!empty($h)) echo $h . ' | '; ?>Dragon's Server</title>
</head>
<body>
<div id="logo"></div>
<h1><?php echo htmlspecialchars($t); ?></h1>
<a href="http://www.dragonjake.net">www.dragonjake.net</a>
</body>
</html>
Štítky:
Tipy a triky