Když na letošním Installfestu představoval Pavel Píša systém bootování Debian Linuxu po síti, jen tak mimochodem přitom zmínil program etckeeper, který jsem do té doby neznal. Jeho myšlenka mě zaujala natolik, že jsem se ho rozhodl nainstalovat a prakticky vyzkoušet.
O co jde
Program, či spíše sada skriptů se společným názvem etckeeper
, slouží k zálohování a dokumentování změn v systémovém adresáři /etc
pomocí systémů pro správu verzí. Podporován je Git, Mercurial, Darcs a Bazaar. Je plně integrován s debianským správcem balíčků dpkg
, stejně jako s redhatím rpm
. Existuje i experimentální podpora pro systém portage
distribuce Gentoo.
Konfigurační adresář /etc
obsahuje i několik velmi citlivých souborů, u kterých je velmi důležité, aby nebyly zpřístupněny jiným uživatelům. Příkladem takového souboru je /etc/shadow
obsahující databázi hesel všech uživatelů. Protože systémy správy verzí obvykle nepodporují ukládání kompletní informace o souboru, včetně vlastníka a oprávnění, udržuje si etckeeper tato metadata ve zvláštním souboru a v případě potřeby je dokáže obnovit.
Instalace a konfigurace
Vzhledem k tomu, že jde o program šitý na míru debianským distribucím, je instalace zcela triviální, stačí libovolným způsobem nainstalovat balíček etckeeper
. Jako závislost se automaticky nainstaluje Git, který je také výchozím revizním systémem. Při instalaci, v konfigurační fázi, je automaticky adresář /etc
převeden na Gitovský repozitář, do kterého jsou commitnuty všechny soubory, které se tam právě nachází:
Setting up etckeeper (0.48) ... Initialized empty Git repository in /etc/.git/ [master (root-commit) 214af6a] Initial commit Committer: root <root@test.example.cz> Your name and email address were configured automatically based on your username and hostname. Please check that they are accurate. You can suppress this message by setting them explicitly: git config --global user.name "Your Name" git config --global user.email you@example.com If the identity used for this commit is wrong, you can fix it with: git commit --amend --author='Your Name <you@example.com>' 718 files changed, 24582 insertions(+), 0 deletions(-) create mode 100755 .etckeeper create mode 100644 .gitignore create mode 100644 adduser.conf create mode 100644 alternatives/README …
Od této chvíle je adresář /etc
spravován Gitem. Pokud nechcete, nemusíte se dále o nic starat. Etckeeper se postará o commit všech změn v adresáři před a po každém použití balíčkovacího systému, navíc pravidelně commituje změny v repozitáři každý den.
Bič na administrátory
Bezobslužnost výchozího nastavení programu se může jevit jako výhoda – prostě etckeeper
nainstalujeme a od té chvíle máme archivovánu historii změn konfiguračního adresáře. Problém ale nastane v momentě, kdy začneme historii prozkoumávat. Zjistíme například, že daný program nefunguje od minulého týdne. Co se od té doby stalo? Někdo změnil konfigurační soubor. Kdo a proč to překonfiguroval? Nevíme.
Řešením podobných situací je řádná dokumentace všech konfiguračních zásahů. V případech, kdy počítač spravuje více správců, jde takřka o nutnost. Každý správce obdrží „čistý“ adresář /etc
(to znamená, že všechny soubory odpovídají poslední verzi v repozitáři) a ve stejném stavu po ukončení zásahu adresář odevzdá. Takové podmínky dokáže etckeeper
poměrně snadno vynucovat. Stačí v konfiguračním souboru /etc/etckeeper/etckeeper.conf
odkomentovat následující volby:
# Uncomment to avoid etckeeper committing existing changes to # /etc before installation. It will cancel the installation, # so you can commit the changes by hand. AVOID_COMMIT_BEFORE_INSTALL=1 # Uncomment to avoid etckeeper committing existing changes # to /etc automatically once per day. AVOID_DAILY_AUTOCOMMITS=1
První volba zakáže automatické commity před instalací balíků. Je-li odkomentována, není možné instalovat žádné balíky, pokud adresář /etc
není „čistý“. To proto, aby bylo vždy zřejmé, které konfigurační soubory změnila právě spuštěná instalace.
Druhá volba zakáže automatické denní ukládání změn do repozitáře. Aby měla historie změn vypovídající úroveň, commitování by mělo probíhat po logických krocích, tak jak je administrátor provádí. Na druhou stranu adresář /etc
obsahuje i soubory, které kromě správce mohou měnit (byť nepřímo) i uživatelé. Příkladem takového souboru je /etc/shadow
(změna hesla uživatelem), nebo /etc/passwd
(změna jména, přihlašovacího shellu, apod.). Denní commitování umožňuje sledovat i takové změny, což se může někdy hodit.
Dokumentovaná administrace
K ukládání konfiguračních změn do repozitáře není nutné používat služby etckeepera, je možné přímo ovládat verzovací systém, v tomto případě Git. Postup práce typického administrátora může vypadat takto:
- Kontrola, zda je adresář
/etc
čistý. Provedeme pomocí příkazugit status
. - Instalace a konfigurace potřebných balíčků, provedení konfiguračních zásahů.
- Ověření, že všechno funguje, jak má.
- Zjištění, které sledované soubory byly změněny, opět pomocí
git status
. - Commit všech změn do repozitáře pomocí příkazu
etckeeper commit
.
Po zadání příkazu v posledním kroku se spustí textový editor a vyzve administrátora k napsání zprávy, která se objeví v repozitáři u commitu. Použití příkazu etckeeper commit
je šikovnou zkratkou, která do repozitáře přidá nově vytvořené soubory v pracovním adresáři, odebere soubory odstraněné a před samotným uložením ještě nastaví jméno autora commitu na skutečné uživatelské jméno administrátora. To funguje za předpokladu, že administrátor používá běžný uživatelský účet a k elevaci oprávnění používá nástroje sudo
nebo su
.
V případě, kdy jeden zásah upravuje několik logicky nesouvisejících souborů, je výhodnější rozdělit takový zásah do samostatných commitů. K tomu je potřeba použít přímo git. Nejprve příkazem git add
připíšeme všechny změněné soubory na seznam změn ke commitu. Příkazem git status
ověříme, že jsme přidali správné soubory a nakonec příkazem git commit
provedeme vlastní commit. Pro snadné odlišení ručních commitů od automatických v historii změn se hodí, pokud ruční commit zprávy opatřujeme vlastní značkou, například my:
. Celý ruční postup ilustruje následující příklad změny jména serveru:
root@server:/etc# echo server.example.net > /etc/hostname root@server:/etc# git status # On branch master # Changed but not updated: # (use "git add ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # modified: hostname # no changes added to commit (use "git add" and/or "git commit -a") root@server:/etc# git add hostname root@server:/etc# git status # On branch master # Changes to be committed: # (use "git reset HEAD ..." to unstage) # # modified: hostname # root@server:/etc# git commit -m "my: hostname update" [master 3f03222] my: hostname update Committer: root <root@server.example.net> …</root@server.example.net>
Jedno z možných řešení, jak i při ručním commitování zachovat v historii reálné jméno administrátora, je nastavení proměnných prostředí GIT_AUTHOR_NAME
a GIT_AUTHOR_EMAIL
v uživatelském profilu. Tyto proměnné se při použití su
(bez parametru -
) zachovají, při použití sudo lze zachování vynutit přidáním následujícího řádku do souboru /etc/sudoers
(příkazem visudo
):
Defaults env_keep += "GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL"
Ignorované soubory
Používáním etckeepera také velmi rychle odhalíme soubory, které by spíše měly být umístěny v adresáři /var
, nicméně z mnoha různých důvodů straší v adresáři /etc
. Jde například o soubor mtab
, obsahující aktuálně připojené svazky, konfigurační soubory vygenerované za běhu DHCP klientem, nebo třeba stavový soubor programu OpenVPN. Etckeeper při vytvoření repozitáře vytvoří i seznam ignorovaných souborů, ve kterém jsou tyto nejběžnější soubory podchyceny. V případě Gitu jde o soubor /etc/.gitignore
. Ten můžeme editovat ručně, etckeeper v něm upravuje jen svou část, ostatní zachovává. Protože samotný soubor .gitignore
není na seznamu ignorovaných, je třeba po jeho úpravě změny standardním způsobem commitovat.
Práce s repozitářem
Samotnou práci s repozitářem etckeeper
nijak neřeší, je třeba použít přímo rozhraní systému pro správu verzí. V případě Gitu lze odkázat na komplexní publikaci Pro Git, která je díky sdružení CZ.NIC k dispozici i v českém jazyce.
Pro běžnou správu si však vystačíme s několika základními příkazy:
Příkaz | Význam |
---|---|
git log |
Zobrazí historii změn. Každý commit je označen jedinečným hash kódem, kterým na něj je možné odkazovat. |
git diff [hash][..hash] |
Vygeneruje rozdílový soubor mezi zadanými commity, případně k aktuálnímu stavu. Bez parametrů vygeneruje patch od posledního commitu k aktuálnímu stavu. |
git checkout [hash|master] |
Změní obsah pracovního adresáře tak, aby odpovídal historické verzi po určeném commitu. Hodí se pro rychlou opravu problémů. Zpět na poslední commit se vrátíme použitím slova master , což je výchozí jméno pro výchozí větev v Gitu. |
Tabulka rozhodně není úplná, ani zcela přesná, ukazuje jen nejjednodušší možnosti používání Gitu. Pro podrobnější a přesnější informace doporučuji třeba výše uvedenou dokumentaci. Je také možné používat nejrůznější grafické nadstavby nad Gitem, tedy pokud se vyrovnáme s tím, že je třeba takové programy spouštět s právy uživatele root
.
Závěr
Etckeeper osobně považuji za killer-feature debianovských systémů. Vytváření a především udržování dokumentace je vždy nesmírně náročný úkol a každý program, který v takovém úkolu může být nápomocen, vítám s otevřenou náručí. Nadarmo nepřijde ani možnost rychle obnovit historickou podobu adresáře /etc
a tím zjistit, kde asi může být chyba, proč služba, která fungovala, najednou nefunguje.
Použití systému správy verzí také přirozeně umožňuje odesílat změny do vzdáleného repozitáře. V tom bych však byl velmi opatrný, vzhledem k citlivému charakteru konfiguračních dat je třeba obezřetně řídit, kam jsou ukládána a kdo k nim může získat přístup.