Uživatelské nástroje

Nástroje pro tento web


Kompilace Turris OS ze zdrojových kódů

Systém Turris OS je založený na distribuci OpenWrt, do které jsou zahrnuty různé úpravy a software, který například zajišťuje automatické aktualizace nebo analyzuje síťový provoz. Kompletní zdrojové kódy systému jsou k dispozici v gitovém repositáři a je možno jej zkompilovat do binární podoby a nainstalovat na zařízení.

Turris OS je možné zkompilovat prakticky na libovolném počítači. V produkčním prostředí je systém kompilován automaticky na systému Ubuntu a následující postupy jsou na tomto systému ověřeny. Přesto je možné ho obdobným postupem zkompilovat i na jiných systémech.

V prvním kroce je nutné naklonovat si repositář Turris OS. To je možné provést některým z následujících dvou příkazů (druhý příkaz je pro naklonování z mirroru na serveru GitHub):

git clone https://gitlab.labs.nic.cz/turris/openwrt.git
git clone https://github.com/CZ-NIC/turris-os.git

Příprava vývojového prostředí

Nejlepším způsobem jak zajistit hladký průběh kompilace je použít totožné prostředí jako v produkci. Nejlépe pak nasazením tohoto prostředí do kontejneru, což také umožní oddělení hlavního systému od systému pro kompilaci. Jsou podporovány dvě varianty jak toto učinit, buďto pomocí nástroje Vagrant a nebo pomocí Dockeru.

Vagrant

Vagrant slouží ke snadné správě vývojových prostředí a v repositáři s Turris OS jsou již připraveny skripty, které umožňují toto prostředí vytvořit zadáním několika málo příkazů. Zároveň automaticky zajišťuje synchronizaci mezi hostitelským systémem a vývojovým prostředím, takže je možné v rámci repositáře pracovat se sadou programů, které jsou nainstalovány v hostitelském systému (například s oblíbeným textovým editorem), a změny se okamžitě projeví v jinak izolovaném prostředí, které s hostitelským systémem sdílí pouze složku naklonovaného repositáře a ve kterém spouštíme kompilaci systému.

V prvním kroku je nutné nainstalovat aplikaci Vagrant. To je možné provést pomocí správce balíků (např. APT v Ubuntu/Debian). V repositářích některých distribucí se však nachází zastaralé verze, které pozbývají potřebné funkce a mohou tak způsobovat problémy. V tom případě je doporučeno nainstalovat verzi staženou z oficiálních stránek.

Po instalaci aplikace Vagrant je nutné doinstalovat plugin vagrant-lxc, který umožňuje používat LXC kontejnery. Ty usnadňují oddělení systému pro kompilaci od hlavního systému bez výraznějšího snížení rychlosti kompilace. Tento plugin samozřejmě vyžaduje také instalaci podpory LXC v hlavním systému. Instalaci tohoto pluginu a jeho závislostí by mělo zajistit zadání těchto příkazů (předpokladem je již nainstalovaná aplikace Vagrant):

sudo apt-get install lxc
vagrant plugin install vagrant-lxc

V posledním kroku je potřeba vytvořit symbolický odkaz (nebo zkopírovat) na soubor s definicí vývojového prostředí do kořenového adresáře s naklonovaným repositářem:

ln -s vagrant/Vagrantfile

Nyní je již možné spustit instanci vývojového prostředí, se kterou budete pracovat, to provedete příkazem vagrant up --provider=lxc (příznak --provider=lxc je potřebný pouze při prvotní inicializaci). Tento příkaz se nám bude hodit pokaždé, kdy instanci ukončíme (pomocí vagrant halt nebo po restartu hostitelského systému). Pokud budete z nějakého důvodu potřebovat vývojové prostředí přeinstalovat (ekvivalent přeinstalování celého systému) nebo odstranit, bude se hodit příkaz vagrant destroy.

Pro přístup do systému slouží příkaz vagrant ssh spuštěný v kořenovém adresáři repositáře. Tím se otevře SSH spojení do kontejneru s vývojovým prostředím, se kterým je již možné pracovat jako s normálním systémem. Adresář, který je synchronizován s repositářem v hostitelském systému, je v systému dostupný v cestě /openwrt.

Docker

Docker je oproti nástroji Vagrant více rozšířený a tak je možné že již na vašem systému je nainstalovaný a nastavený. Soubory potřebné k vytvoření Docker kontejnerů se nacházejí v naklonovaném repositáři Turris OS v adresáři 'Docker'. Obsahem jsou dva skripty a to build-all a run a především soubory popisující Docker kontejnery.

Prvním krokem je vytvoření kontejnerů. Skript build-all obsahuje pět řádek volajících docker, které postupně vytvoří pět kontejnerů. Jejich jména a význam je následující:

  • base - Základní systém obsahující všechny závislosti potřebné pro sestavení Turris OS. Do adresáře '/home/build/openwrt' jsou naklonovány zdrojové kódy a to v nejnovější verzi z větvě `test` (větev na které probíhá vývoj).
  • omnia-toolchain - Vyžaduje a vychází z base. Je v něm nastavena konfigurace pro Turris Omnia a obsahuje zkompilovaný toolchain. Balíčky ale nejsou zkompilovány. Toto se může hodit pokud je nutné nestavit pouze jeden balíček, nikoli celý systém.
  • omnia - Vyžaduje a vychází z omnia-toolchain. V tomto kontejneru je sestaven základní systém, systém pro Turris Omnia a kompilace při malé změně by tak měla být rychlá. Ale ani v tomto kontejneru nejsou zkompilovány všechny balíčku (to by vyžadovalo velké množství času).
  • turris-toolchain - Vyžaduje a vychází z base. Je v něm nastavena konfigurace pro Turris 1.x a je v něm zkompilovaný toolchain. Balíčky ale nejsou zkompilovány. Toto se může hodit pokud je nutné sestavit pouze jeden balíček, nikoli celý systém.
  • turris - Vyžaduje a vychází z turris-toolchain. V tomto kontejneru je sestaven základní systém pro Turris 1.x a kompilace při malé změně by tak měla být rychlá. Ale ani v tomto případě nejsou zkompilovány všechny balíčky (to by vyžadovalo velké množství času).

Pokud chcete ušetřit čas a místo tak můžete odstranit řádky pro vámi necílenou platformu. Následně spusťte skript build-all. Tento proces může trvat i hodiny, záleží na výkonu hardwaru na kterém kompilace běží a na tom které kontejnery vytváříte.

Poté co jsou kontejnery vytvořeny, tak je do nich možné přistoupit pomocí skriptu run. Tento skript jako první argument očekává volitelně jméno kontejneru (tedy např. ./run omnia). Pokud není žádný argument předán, tak se pokusí připojit do kontejneru omnia-toolchain.

Pozor, v případě Dockeru, po ukončení kontejneru jsou všechny změny zahozeny, pokud nenastavíte jinak. Také na rozdíl od nástroje Vagrant nepracuje Docker s originálním vámi naklonovaným repositářem.

V následujících sekcích rozlišujte který kontejner jste se rozhodli použít. V případě base musíte provést celý postup jak je popsán. V případě ostatních Docker kontejnerů není nutné dělat update feedů a nastavení konfigurace, můžete se rovnou přesunout na kompilaci. V takovém případě také není doporučeno používat compile_fw skript, protože jako první krok provádí čištění repositáře.

Nastavení prostředí bez kontejnerů

Pokud na vašem systému nemůžete nebo nechcete používat prostředí Vagrant či Docker, je možné nainstalovat závislosti kompilace systému přímo do hostitelského systému. Tyto závislosti lze nalézt v inicializačním skriptu vagrant/vagrant_bootstrap.sh, který se spouští po prvním spuštění prostředí Vagrant. V systémech založených na distribuci Debian bude možné pravděpodobně příkazy v něm použité použít beze změny, v jiných systémech bude nutné nalézt a nainstalovat software, který instalovaným balíčkům odpovídá. V hledání může pomoct tabulka na wiki OpenWrt. Uvedený skript zároveň upravuje URL pro stahování balíčků a volitelně též umožňuje instalaci doplňování argumentů pro příkaz make v buildrootu pomocí rozšíření openwrt-bash-completion.

Poslední možností je použít pro kompilaci plně virtualizovaný systém. Tato metoda je nejnáročnější na prostředky (CPU a operační paměť), ale je možné ji použít na nejširším množství systémů, včetně OS Windows. Pro virtualizaci lze použít například volně dostupnou aplikaci VirtualBox. V tomto případě je vhodné jako instalovaný systém zvolit distribuci Ubuntu - v tom případě stačí po instalaci systému naklonovat repozitář Turris OS a spustit výše uvedený inicializační skript, který se postará o vše ostatní.

Vlastní kompilace Turris OS

Buildroot (kompilační prostředí) Turris OS, respektive OpenWrt, se skládá z velkého množství skriptů, které zajišťují cross kompilaci (kompilaci pro cílovou platformu) prostřednictvím rozhraní nástroje GNU Make. Hlavním příkazem, kterým proto budete buildroot ovládat, je příkaz make.

Kromě klíčových komponent systému, obsažených v repositáři openwrt (resp. turris-os), jsou se systémem kompilovány další balíčky, které jsou spravovány v repositáři turris-os-packages a dalších repositářích třetích stran. O jejich zahrnutí do systému se stará skript pro správu tzv. feeds. Podívejme se tedy na příkazy, které se mohou hodit při používání buildrootu. Všechny příkazy by měly být spouštěny v kořenovém adresáři repositáře (ve složce /openwrt v prostředí Vagrant). Uvedeny jsou v pořadí, ve kterém je nutné je spustit po inicializaci čistého vývojového prostředí:

  • ./scripts/feeds update -a – Aktualizace všech feeds z jejich umístění. V tomto kroku se zpravidla stáhne obsah dalších repozitářů jako turris-os-packages do oddělených složek.
  • ./scripts/feeds install -a – Instalace balíčků ze všech feeds do buildrootu. Tím se vytvoří symbolické odkazy na definice balíčků v adresáři package/ a je tak možné balíčky vybrat a zkompilovat.
  • cp configs/omnia .config – Zkopírování konfiguračního souboru pro Turris Omnia (alternativně configs/turris pro Turris 1.x)
  • make menuconfig – Zobrazení konfiguračního menu. V rámci něj lze nastavit, jaké balíčky se mají kompilovat a případně lze upravit další parametry sestavovaného systému. Po uložení se zároveň sestaví informace o aktuální konfiguraci (toho lze docílit i spuštěním příkazu make defconfig).

Po spuštění těchto příkazů můžete spustit kompilaci všech nástrojů a systému samotného. Protože by jednovláknově tato operace trvala velice dlouho, v ukázce je použit příznak -j ČÍSLO, kde ČÍSLO reprezentuje počet úloh, které mohou souběžně probíhat. Doporučuje se volit počet, který odpovídá počtu jader CPU nebo hodnota o jedna vyšší. Parametry LOGFILE=1 BUILD_LOG=1 IS_TTY=1 zajišťují, aby se výstup kompilace zaznamenával do souboru a na konzoli se zobrazovaly pouze základní informace o průběhu kompilace:

make -j 4 LOGFILE=1 BUILD_LOG=1 IS_TTY=1

Občas operace skončí s nějakou chybou. V tom případě použijte buď parametry z uvedené ukázky a chybu poté hledejte v souboru logs/build.log nebo u spouštěného příkazu přidejte parametr V=s pro obdržení „upovídaného“ výstupu na konzoli.

Někdy je žádoucí sestavit pouze jeden balíček. Pokud už máte sestavený toolchain (například jste spouštěli příkaz make jako v ukázce výše), stažení zdrojových kódů, jejich kompilaci pro cílový systém a vytvoření .ipk balíčku pro instalaci na router odstartujete následujícím příkazem. Někdy je však ještě nutné sestavit nejprve balíčky závislostí požadovaného balíčku.

make package/nazev-balicku/install

Jako název balíčku se zadává název složky, ve které je soubor Makefile pro daný balíček, nikoliv název balíčku specifikovaný v proměnné PKG_NAME. V případě, že soubor Makefile balíčků obsahuje více balíčků, budou vytvořeny všechny, které jsou vybrány v konfiguraci.

Zkompilované balíčky (a případně další výstup kompilace, jako SDK, a další soubory) naleznete v adresáři bin/. Vytvořené .ipk soubory je pak možné v případě správně dodrženého postupu zkopírovat na router a nainstalovat.

Pro usnadnění kompilace jsou pak v repozitáři shellové skripty compile_turris_fw a compile_omnia_fw, který po spuštění odstraní staré soubory, provede inicializaci feeds a spustí kompilaci systému. Vhodné je ho spouštět s parametrem USE_CCACHE=1 a v několika úlohách (tedy například USE_CCACHE=1 ./compile_turris_fw -j4, což značně urychlí kompilaci (je nutné v systému, ve kterém probíhá kompilace, nainstalovat balík ccache). Zároveň je možné použít parametr BUILD_ALL – tím spustíme instalaci opravdu všech balíků, které jsou v systému Turris OS zahrnuty. Tato operace však trvá značně dlouhou dobu (řádově hodiny). Pro spuštění kompilace kompletního Turris OS, s využitím cache během kompilace, ve čtyřech úlohách a s chybovým výstupem zaznamenávaným do souboru:

USE_CCACHE=1 BUILD_ALL=1 ./compile_turris_fw -j 4 LOGFILE=1 BUILD_LOG=1 IS_TTY=1

Řešení problémů

Nedostatek místa při vytváření Docker kontejneru

Docker kontejnery zabírají řádově desítky gigabajtů. Pokud jejich vytváření selhalo s hláškou o nedostatku místa, tak v prvním kroku je třeba zkontrolovat zdali vám skutečně nedošlo místo a případně ho uvolnit. Pokud, ale místa máte dostatek, pak je nutné upravit konfiguraci Docker daemonu a to pomocí těchto voleb --storage-opt dm.basesize=40G --storage-opt dm.loopmetadatasize=10G. Výsledná spouštěcí řádka by tak měla vypadat například takto:

dockerd -H fd:// --storage-opt dm.basesize=40G --storage-opt dm.loopmetadatasize=10G

Po této úpravě je nutné Docker daemon restartovat a odstranit všechny doposud vygenerované soubory tak aby se změna aplikovala. Přesná cesta souborů je dána vaším systémem, ale obecně se užívá /var/lib/docker.