Michal Čihař - Balíčky pro Debian - 7. Skriptíky a debconf

Balíčky pro Debian - 7. Skriptíky a debconf

Balíček občas potřebuje něco provést během svojí instalace a stejně tak jako RPM umožňuje Debian začlenit různé skriptíky do různých fází instlace.

Debian nabízí čtyři skripty, kterými můžete ovlivnit průběh instalace - postinst, preinst, postrm, prerm a config. Skript config je trochu specifický a spouští se ještě před instalování všech balíčků a jeho použití je v podstatě jen ve spojení s Debconfem, a umožní získat odpovědi uživatelů na různé dotazy. Jeho přesnější použití si probereme až společně se Debconfem.

Spouštění skriptíků

Každý skript dostává v prvním parametr typ akce která se právě provádí a pokud se jedná o aktualizaci, tak verzi balíčku ze kterého se aktualizuje. Celkové pořadí a možnosti spouštění skriptů je celkem komplikované tak zájemce o podrobné studium stavových diagramů odkáži na wiki. Pro běžné použití nám však stačí zapamatovat si pořadí skriptů.

Při instalaci se nejdříve pouští preinst, rozbalí se soubory a pustí se postinst. Při aktualizaci balíčku se nejdříve pouští prerm starého balíčku, pak preinst nového, rozbalí se soubory, postrm starého a postinst z nového balíčku. Poslední důležitá akce je odstranění balíčku, kdy se nejdříve pustí prerm skript a po odstranění souborů postrm. Pokud znáte i RPM, je dobré si uvědomit, že při aktualizaci je pořadí trochu jiné.

Co v nich potřebujeme?

Pro začátek jednoduchá odpověď: pro většinu standardních balíčků všechny potřebné akce (pokud vůbec nějaké jsou) do skriptíků vygeneruje automaticky Debhelper a nemusíme se o nic starat. Mezi takové akce patří například spouštění programu ldconfig při instalaci knihovny instalace init skriptů, kompilování byte kódu pro Python a podobně.

Nicméně pokud náš balíček potřebuje například vytvoření nového systémového uživatele, už se bez psaní skriptů neobejdeme. Skriptíky pro každý balíček patří do adresáře debian a budou se jmenovat debian/binární-balíček.jméno-skriptu, například tedy debian/hello.postinst. Při psaní vlastních skriptů nesmíme zapomenout na Debhelper, který pořád může chtít vložit nějakou část do těchto skriptíků. Proto by každý námi vytvořený skript měl obsahovat speciální komentář, který značí, kam Debhelper může vkládat svůj kód:

#DEBHELPER#

Debconf

Pokud od skriptů požadujeme nějakou interaktivitu s uživatelem, měl by pro tyto účely používat Debconf. Jakákoliv interaktivita by měla být omezena na nejnutnější možnou míru, takže pokud je možné použít vhodné výchozí hodnoty, je to vždy lepší než se ptát uživatele na každou konfigurační možnost ve vašem balíčku. Odpovědi uživatelů se ukládají do databáze a uživatel není vícekrát dotazován na věci, na které již jednou odpovídal. Jediná možnost jak zobrazit již odpovězené otázky je použitím dpkg-reconfigure.

Debconf umožňuje získat informace od uživatele ve standardní formě a využívat právě používané grafické rozhraní. Zobrazování dialogů uživateli má část zvaná frontend, kterých existuje celá řada (GNOME, KDE, příkazová řádka, dialog, atd.). Otázky pro Debconf je také možné překládat, takže uživateli budou zobrazeny podle jeho locales. Pro správné používání Debconfu potřebujeme upravit minimálně tyto soubory:

Šablony

Šablony používají podobný formát jako debian/control, takže napsat ji nebude nic těžkého:

Template: jméno-balíčku/jméno-otázky
Type: typ-otázky
Default: výchozí-hodnota
Choices: volby, pro, výběrové, typy
_Description: Název položky:
 Podrobný popis položky.

Povinná pole jsou jen Template, Type a Description. To že jméno pole začíná na podtržítko, znamená že je možné toto pole přeložit. Obvykle se používá u Description, ale občas i u Choices. O překladu šablon se dozvíte více na konci dnešního článku. Jako jméno otázky použijte co nejjednodušší identifikátor, typ otázky je jeden z následujících:

Konfigurační a poinstalační skript

Do konfiguračního skriptu musíme zapsat ptaní se na všechny otázky. Všechny potřebné funkce pro tuto činnost získáme ze skriptu /usr/share/debconf/confmodule. Příkazy začínají na db_ a význam těch nejdůležitějších asi uhodnete z jejich názvů:

Jednoduchý konfigurační soubor (debian/binární-balíček.config) by mohl vypadat nějak takto:

#!/bin/sh
CONFIGFILE=/etc/foo.conf
set -e
. /usr/share/debconf/confmodule

# Load config file, if it exists.
if [ -e $CONFIGFILE ]; then
    . $CONFIGFILE || true

    # Store values from config file into
    # debconf db.
    db_set mypackage/foo "$FOO"
    db_set mypackage/bar "$BAR"
fi

# Ask questions.
db_input medium mypackage/foo || true
db_input medium mypackage/bar || true
db_go || true

Důležité je nepřepisovat uživatelovy změny v konfiguraci, proto pokud již konfigurační soubor existuje, načteme hodnoty z něj. Pak se zobrazí otázky.

V poinstalačním skriptu (debian/binární-balíček.postinst) pak musíme tyto hodnoty načíst a zpracovat. Jako pokračování výše zmíněného příkladu je uložíme do konfiguračního souboru:

#!/bin/sh
CONFIGFILE=/etc/foo.conf
set -e
. /usr/share/debconf/confmodule

# Generate config file, if it doesn’t exist.
# An alternative is to copy in a template
# file from elsewhere.
if [ ! -e $CONFIGFILE ]; then
    echo "# Config file for my package" > $CONFIGFILE
    echo "FOO=" >> $CONFIGFILE
    echo "BAR=" >> $CONFIGFILE
fi

# Substitute in the values from the debconf db.
# There are obvious optimizations possible here.
# The cp before the sed ensures we do not mess up
# the config file’s ownership and permissions.
db_get mypackage/foo
FOO="$RET"
db_get mypackage/bar
BAR="$RET"
cp -a -f $CONFIGFILE $CONFIGFILE.tmp

# If the admin deleted or commented some variables but then set
# them via debconf, (re-)add them to the conffile.
test -z "$FOO" || grep -Eq ’^ *FOO=’ $CONFIGFILE || \
    echo "FOO=" >> $CONFIGFILE
test -z "$BAR" || grep -Eq ’^ *BAR=’ $CONFIGFILE || \
    echo "BAR=" >> $CONFIGFILE

sed -e "s/^ *FOO=.*/FOO=\"$FOO\"/" \
    -e "s/^ *BAR=.*/BAR=\"$BAR\"/" \
    < $CONFIGFILE > $CONFIGFILE.tmp
mv -f $CONFIGFILE.tmp $CONFIGFILE

#DEBHELPER#

Jak vidíme, tak kromě dvojího zavolání db_get se skript jen snaží bezpečně upravit konfigurační soubor.

Překládání šablon

Na závěr jsem si nechal překládání šablon. Pro používání překladů potřebujeme nejprve náš balíček trochu upravit. O podtržítku před překladatelnými texty jsem již mluvil v části o šablonách, dále je potřeba přidat kompilační závislost na po-debconf do debian/control a vytvořit soubor debian/po/POTFILES.in se seznamem souborů pro překlad - obvykle v něm bude jediná řádka:

[type: gettext/rfc822deb] templates

Nyní již můžeme pustit program debconf-updatepo (z balíčku po-debconf), který vygeneruje šablonu pro překlad debian/po/templates.pot. Tento soubor již můžeme předhodit překladatelům a začlenit zpět překlady do adresáře debian/po (například český překlad bude patřit do souboru debian/po/cs.po). Instalaci překladů na správné místo zařídí výše zmiňovaný dh_installdebconf.