Cvičení: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14.

V tomto cvičení se budeme zabývat dvěma velkými tématy. Nejprve se podíváme na nástroje související se správou úložišť a poté prozkoumáme, jak vyvíjet projekty v jazyce Python ve virtuálním prostředí, které lze snadno distribuovat mezi jednotlivé vývojáře ve velkém softwarovém týmu. Mezi to vmáčkneme krátkou poznámku o kompresi (a archivaci) souborů v systémech Linux.

Správa uložiště

Než budete pokračovat, připomeňte si, že soubory se nacházejí v souborových systémech, což jsou struktury na skutečných blokových zařízeních (typicky discích).

Práce se souborovými systémy a blokovými zařízeními je nutná při instalaci nového systému, při záchraně dat z poškozeného zařízení nebo při prosté kontrole volného místa.

Běžné soubory a adresáře již znáte. V systému Linux však můžete najít i jiné typy souborů.

Symbolické odkazy

Linux umožní vytvořit symbolický odkaz na jiný soubor. Tento speciální druh souboru nemá žádný obsah a jen odkazuje na další soubor.

Zajímavou vlastností symbolických odkazů je, že jsou transparentní pro standardní I/O API. Pokud zavoláte Pythoní open na symbolickém odkazu, otevřete tím (transparentně) soubor, na který odkazuje. To je zamýšlené chování.

Účelem symbolických odkazů je umožnit jiný pohled na stejné soubory bez nutnosti cokoliv kopírovat a synchronizovat.

Například uvažujme, že přehrávač videí umí přehrávat jen soubory v adresáři Videos. Ve skutečnosti ale máme soubory jinde, protože jsou na sdíleném disku. S pomocí symbolického odkazu můžete složku Videos nasměřovat na skutečné úložiště a přehrávač nic nepozná. (Pro pořádek, neznáme žádný přehrávač s podobných chováním, ale existuje spousta jiných programů, kde podobná magie umožní jejich funkci i v prostředí, pro které nebyly navrženy.)

Symbolický odkaz je něco jiného než zástupce na ploše apod. Tito zástupci jsou ve skutečnosti normální soubory, kde kromě cílového souboru určíte třeba i ikonu apod. Symbolické odkazy fungují o úroveň níže.

Speciální soubory

Kromě toho také existují speciální soubory, které reprezentují fyzická zařízení, nebo soubory, které fungují jako kukátka do stavu systému.

Hlavním důvodem je, že je to tak mnohem jednodušší pro vývojáře. Nepotřebujete speciální programy na práci s diskem, nepotřebujete zvláštní program na zjištění stavu paměti. Prostě jen přečtete obsah dobře známého souboru a máte potřebná data.

Je také mnohem jednodušší takové programy testovat – můžete jim předhodit jiný soubor jen změnou cesty. Což je změna, která by neměla rozbít zbytek programu.

Soubory, které reprezentují stav systému, jsou typicky textové. Například soubor /proc/meminfo může vypadat takto:

MemTotal:        7899128 kB
MemFree:          643052 kB
MemAvailable:    1441284 kB
Buffers:          140256 kB
Cached:          1868300 kB
SwapCached:            0 kB
Active:           509472 kB
Inactive:        5342572 kB
Active(anon):       5136 kB
Inactive(anon):  5015996 kB
Active(file):     504336 kB
Inactive(file):   326576 kB
...

Tento soubor není nikde na disku, ale když soubor otevřete, Linux vytvoří jeho obsah za běhu.

Všimněte si, jak je informace strukturována: jde o textový soubor, takže nepotřebujete žádné speciální nástroje na přečtení. Navíc je obsah snadno čitelný pro člověka. Na druhou stranu, struktura souboru je pevně daná: co řádek, to záznam; klíč a hodnota jsou odděleny dvojtečkou. Snadné i pro zpracování programem.

Hierarchie souborových systémů

Nyní si stručně uvedeme některé důležité soubory, které najdete prakticky na každém počítači s Linuxem.

Nebojte se skutečně zobrazit obsah souborů, které zde uvádíme. hexdump -C je opravdu skvělý nástroj.

/boot obsahuje zavaděč pro načtení operačního systému. Po instalaci systému se tímto adresářem budete zabývat jen zřídka.

/dev je speciální adresář, ve kterém jsou umístěny soubory reprezentující hardwarová zařízení Pravděpodobně tam uvidíte soubor sda nebo nvme0, který reprezentuje váš pevný (nebo SSD) disk. Pokud tedy nepracujete pod superuživatelem, nebudete mít k těmto souborům přístup ale kdybyste je hexdumpovali, viděli byste bajty tak, jak jsou na skutečném pevném disku.

A zápis do takových souborů by přepsal data na disku!
Diskové nástroje v Linuxu totiž přijímají cesty k diskovým jednotkám, na kterých budou pracovat. Je tedy velmi snadné zadat jim soubor a předstírat, že se jedná o disk, který je třeba naformátovat. Toho lze využít k vytváření obrazů disků nebo k obnově souborů. A značně to zjednodušuje testování takových nástrojů, protože k testování není třeba mít skutečný disk.

Je důležité si uvědomit, že tyto soubory nejsou fyzickými soubory na disku (to by přece znamenalo mít disk uvnitř disku). Při čtení z nich to jádro rozpozná a vrátí správná data.

Tento adresář obsahuje také několik speciálních, ale velmi užitečných souborů pro vývoj softwaru.

/dev/urandom vrací náhodné bajty po neomezenou dobu. Pravděpodobně se interně používá uvnitř vašeho oblíbeného programovacího jazyka k implementaci jeho funkce random(). Zkuste na tomto souboru spustit hexdump (a připomeňte si, že <Ctrl>-C program ukončíte, až vás už náhodnost přestane bavit).

K dispozici je také /dev/full, který emuluje plný disk, /dev/null, který zahodí vše, co se na něj zapíše, nebo /dev/zero, který poskytuje nekonečný proud nulových bajtů.

/etc/ obsahuje konfiguraci systému. Většina programů v systémech UNIX se obvykle konfiguruje prostřednictvím textových souborů. Důvodem je to, že správce se musí naučit pouze jeden nástroj – dobrý textový editor – pro správu systému. Výhodou je, že většina konfiguračních souborů má podporu pro komentáře a je možné komentovat i konfiguraci. Pro představu, příklad takového konfiguračního souboru si můžete prohlédnout v /etc/systemd/system.conf.

Asi nejdůležitějším souborem je /etc/passwd, který obsahuje seznam uživatelských účtů. Všimněte si, že se jedná o textový soubor, kde každý řádek představuje jeden záznam a jednotlivé atributy jsou jednoduše odděleny dvojtečkou :. To je velmi jednoduché na čtení, velmi jednoduché na úpravu a velmi jednoduché na pochopení. Jinými slovy, princip KISS v praxi.

/home obsahuje domovské adresáře pro běžné uživatelské účty (tj. účty pro skutečné – lidské – uživatele).

/lib a /usr obsahují dynamické knihovny, aplikace a celosystémové datové soubory.

/var je určen pro volatilní data. Pokud byste chtěli na svůj počítač nainstalovat databázi nebo webový server, byly by jeho soubory uloženy zde.

/tmp je obecné umístění pro dočasné soubory. Tento adresář je automaticky vyčištěn při každém restartu, proto jej nepoužívejte pro trvalé uložení souborů. Mnoho systémů také automaticky odstraňuje soubory, které nebyly změněny v v posledních několika dnech.

/proc je virtuální souborový systém, který umožňuje ovládání a čtení nastavení jádra (operačního systému). Například soubor /proc/meminfo obsahuje poměrně podrobné informace o využití paměti RAM.

Opět platí, že /proc/* nejsou normální soubory, ale virtuální. Dokud je nepřečtete, jejich obsah nikde fyzicky neexistuje.

Když otevřete /proc/meminfo, jádro přečte své vnitřní datové struktury, připraví jeho obsah (pouze v paměti) a předá vám ho. Není to tak, že by se tento soubor fyzicky zapisoval každých 5 sekund nebo tak nějak, aby obsahoval nejaktuálnější informace.

Připojování a přípojné body (mounts, mount-points)

Každý souborový systém (ke kterému chceme přistupovat) je někde přístupný jako adresář (v porovnání například s písmenem jednotky v jiných systémech).

Pokud chceme přistoupit k zařízení /dev/sda3 pod /home, říkáme, že /dev/sda3 je připojené do /home, /home je potom přípojný bod a /dev/sda3 se často také nazývá svazek (volume).

Většina zařízení je připojena automaticky při startu. To zahrnuje / (kořen, root) kde je systém, ale také /home, kde jsou data uživatelů. Všimněte si, že /dev a /proc (kromě jiných) jsou speciální souborové systémy připojené do těchto míst. Takže, soubor /proc/uptime fyzicky vůbec neexistuje (tj. nenajdete žádný sektor na disku, který by obsahoval jeho data).

Souborové systémy připojené při startu jsou vyjmenovány v /etc/fstab. Málokdy jej budete muset měnit (obzvláště na notebooku) a tento – instalátorem vytvořený – soubor zůstane často beze změn. Všimněte si, že obsahuje identifikaci svazku (čili cestu k oddílu – partition), přípojný bod a další možnosti.

Když připojíte vyjímatelný USB disk, vaše desktopové prostředí ho obvykle připojí automaticky. Je možné ho připojit i ručně pomocí programu mount. Nicméně, program mount musí běžet pod uživatelem root (tohle vlákno vysvětluje, proč může připojení disku být bráno jako nebezpečná operace). Takže si s mountem můžete hrát jen na svých instalacích, kde máte oprávnění superuživatele. Na sdílených strojích to fungovat nebude.

Technická poznámka: výše uvedený text se může zdát jako protimluv, protože když mount vyžaduje rootovské heslo, jak může vaše desktopové prostředí (DE) připojit disk bez ptaní se na administrátorské heslo. Vaše DE totiž uvnitř nezavolá mount, ale použije jiný program (obvykle postavený nad Udisks nebo Polkitem) které dohromady ověří, že připojované zařízení je skutečně flash disk (nebo něco podobného) a uživatel je tzv. lokální (tj. aby to nefungovalo přes SSH). Pokud jsou tyto podmínky splněny, může disk pro uživatele připojit. Mimochodem, s UDisks můžete mluvit z shellu pomocí udiskctl.

Pokud chcete otestovat připojování ručně, připojte USB disk a odpojte ho v GUI (pokud byl připojen automaticky). Obvykle je zařízení připojeno někam do podadresáře v /media.

Vaše USB bude pravděpodobně dostupné jako /dev/sdb1 nebo /dev/sda1 podle toho, jaký disk v počítači máte (mrkněte do další části o lsblk, pokud chcete vidět seznam zařízení).

Připojování disků není omezeno jen na ty fyzické. V další části budeme mluvit o obrazech disků, ale jsou i jiné možnosti. Je možné připojit síťový disk (třeba NFS nebo AFS, které je používané na MFF) nebo dokonce vytvořit síťové blokové zařízení a to připojit.

Pokud máte virtualizovaný Linux, např. skrz VirtualBox, připojování disků je trochu složitější. Můžete přidat další virtuální disk a ten připojit ručně. Nebo můžete vytvořit tzv. pass-through a dovolit virtuálnímu stroji přistupovat přímo k vašemu fyzickému disku. Například ve VirtualBoxu je možné přistupovat k fyzickému oddílu skutečného disku ale pro experimentování je asi bezpečnější začít s USB pass-through, které zpřístupní USB “flešku” uvnitř hosta. Ale vždy se ujistěte, že fyzické zařízení v ten okamžik nepoužívá hostitel.

Práce s obrazy disků (disk images)

Linux má zabudovanou podporu pro práci s obrazy disků. To jest, se soubory, které obsahují zrcadlový obraz skutečného disku. Ve skutečnosti jste s nimi už také pracovali, pokud jste instalovali Linux do virtuálky nebo si stáhli obraz USB disku na začátku semestru.

Linux vám umožní takovýto obraz připojit, jako by to byl fyzický disk a dokonce na něm měnit soubory. To je potřeba pro následující činnosti:

  • Vývoj a ladění souborových systémů (což je spíše neobvyklá činnost)
  • Vykopírování souborů z obrazů disků virtuálních strojů
  • Obnova souborů z poškozených disků (neobvyklé, ale k nezaplacení)
Při obnově dat z poškozených disků je obvyklý postup ten, že se pokusíte zkopírovat disk tak, jak je, na co nejnižší úrovni (tj. kopírujete prostě bajty z disku bez jakékoliv interpretace). A teprve poté, co máte zkopírovaný obraz, se pokusíte o vlastní záchranu dat. To zabrání dalšímu poškozování disku a dá vám to větší množství času na vlastní obnovu dat.

Ve všech případech ale pro připojení obrazu disku stačí systému říct, že má k souboru přistupovat jako k dalšímu blokovému zařízení (vzpomeňte si na /dev/sda1 z příkladu výše).

Připojování disků ručně

sudo mkdir /mnt/flash
sudo mount /dev/sdb1 /mnt/flash

Vaše data budou viditelná v adresáři /mnt/flash.

Chcete-li disk odpojit, spusťte následující příkaz:

sudo umount /mnt/flash

Všimněte si, že spuštění příkazu mount bez argumentů vypíše seznam aktuálně připojených disků. K tomu nejsou vyžadována práva roota.

Určen svazku

Doposud jsme k určení svazku vždy používali název blokového zařízení (např. /dev/sdb1). Zatímco u malých systémů je to triviální, u větších to může být neuvěřitelně matoucí – názvy zařízení závisí na pořadí, v jakém systém disky objevil. Toto pořadí se může mezi jednotlivými spuštěními systému měnit a u vyměnitelných disků je ještě méně stabilní. Nechcete přece dopustit, aby náhodně připojený USB flash disk způsobil, že váš počítač nebude možné spustit :-).

Stabilnějším způsobem je odkazovat se na bloková zařízení pomocí symlinků pojmenovaných podle fyzického umístění v systému. Například /dev/disk/by-path/pci-0000:03:00.1-ata-6-part1 odkazuje na oddíl 1 disku připojeného k portu 6 řadiče SATA, který se nachází jako zařízení 00.1 na sběrnici PCI 0000:03.

Ve většině případů je ještě lepší popsat oddíl podle jeho obsahu. Většina souborových systémů má identifikátor UUID (univerzální jedinečný identifikátor, 128bitové číslo, obvykle náhodně generované) a často také štítek disku (krátký textový název). Můžete spustit lsblk -f pro zobrazení UUID a štítků všech diskových oddílů a poté zavolat mount s UUID=číslo nebo LABEL=štítek místo názvu blokového zařízení. Váš etc/fstab bude pravděpodobně odkazovat na vaše svazky jedním z těchto způsobů.

Připojování obrazů disků

Obrazy disků lze připojit téměř stejným způsobem jako bloková zařízení, pouze je třeba přidat k příkazu mount volbu -o loop.

Připomeňme, že mount vyžaduje práva roota (sudo), proto musíte následující příklad provést na svém vlastním počítači, nikoli na některém ze sdílených počítačů.

Chcete-li si to vyzkoušet, můžete si stáhnout tento FAT obraz disku a připojit jej.

sudo mkdir /mnt/photos-fat
sudo mount -o loop photos.fat.img /mnt/photos-fat
... (prace se soubory v /mnt/photos-fat)
sudo umount /mnt/photos-fat

Případně můžete spustit udisksctl loop-setup a přidat obraz disku jako vyměnitelnou jednotku, která se automaticky připojí na plochu:

# Pomoci udisksctl and automatickeho pripojovani v GUI
udisksctl loop-setup -f fat.img
# Tohle vytiskne asi /dev/loop0 ale cislo se muze lisit
# Ted to muzete pripojit v GUI (coz muze probehnout i automaticky)
... (prace se soubory v /run/media/$(whoami)/07C5-2DF8/)
udisksctl loop-delete -b /dev/loop0

Prográmky pro zjištění zaplněnosti disku

Základním nástrojem pro kontrolu volného místa na disku je df (disk free).

Filesystem     1K-blocks    Used Available Use% Mounted on
devtmpfs         8174828       0   8174828   0% /dev
tmpfs            8193016       0   8193016   0% /dev/shm
tmpfs            3277208    1060   3276148   1% /run
/dev/sda3      494006272 7202800 484986880   2% /
tmpfs            8193020       4   8193016   1% /tmp
/dev/sda1        1038336  243188    795148  24% /boot

Ve výchozím provedení (výše) se používají kilobajtové bloky. Pro čitelnější výstup jej spusťte s -BM nebo -BG (megabajty a gigabajty) nebo s -h, abyste jej nechali vybrat nejvhodnější jednotku.

Nezaměňujte df s du, které lze použít k odhadu využití místa souborem. Obvykle se du spouští jako du -sh DIR, aby se vypsalo celkové místo zabrané všemi soubory v DIR. Pro vypsání velikostí adresářů nejvyšší úrovně ve vašem $HOME můžete použít du -sh ~/*. Buďte však opatrní, protože prohledání všech adresářů může trvat poměrně dlouho.

Můžete si také všimnout, že využití prostoru hlášené pomocí du se nerovná součtu velikostí všech souborů. K tomu dochází proto, že soubory jsou organizovány v blocích, takže velikosti souborů jsou obvykle zaokrouhleny na násobek velikosti bloku. Kromě toho také adresáře spotřebovávají určitý prostor.

Chcete-li zjistit, jak jsou svazky (oddíly) vnořené a která bloková zařízení jádro rozpoznává, můžete použít příkaz lsblk. Na sdíleném počítači se zobrazí následující:

NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0   480G  0 disk
├─sda1   8:1    0     1G  0 part /boot
├─sda2   8:2    0   7.9G  0 part [SWAP]
└─sda3   8:3    0 471.1G  0 part /

To ukazuje, že počítač má 480G disk rozdělený na tři oddíly: malý /boot pro boostrapování systému, 8G odkládací oddíl a nakonec 470G zbývá pro systém a uživatelská data. Nepoužíváme samostatný svazek pro /home.

Mnoho dalších výstupních formátů najdete v manuálové stránce.

Zkoumání a úpravy svazků (oddílů)

Toto téma přenecháme více na pokročilý kurz. Pokud se chcete něco naučit sami, můžete začít s následujícími nástroji:

  • fdisk(8)
  • btrfs(8)
  • mdadm(8)
  • lvm(8)

Archivace a komprese souborů

S výše uvedeným tématem do jisté míry souvisí i způsob, jakým Linux řeší archivaci a kompresi souborů.

Archivace v systému Linux obvykle znamená sloučení více souborů do jednoho (pro snadnější přenos) a kompresi tohoto souboru (pro úsporu místa). Někdy se za archivaci považuje pouze první krok (tj. sloučení).

Ačkoli se tyto dvě činnosti obvykle provádějí společně, Linux je od sebe odděluje, protože to umožňuje kombinovat vhodné nástroje a formáty pro každou část práce. Všimněte si, že v jiných systémech, kde je preferovaným formátem soubor ZIP, jsou tyto činnosti sloučeny do jedné.

Nejpoužívanějším programem pro archivaci je tar. Původně byl primárně určen k archivaci na pásky, odtud jeho název: tape archiver. Spouští se vždy s volbou určující režim práce:

  • -c pro vytvoření nového archivu z existujících souborů,
  • -x pro extrakci souborů z archivu,
  • -t pro vypsání tabulky souborů uvnitř archivu.

Jméno archivu se zadává pomocí volby -f; pokud není jméno zadáno, archiv se čte ze standardního vstupu nebo zapisuje na standardní výstup.

Volba -v jako obvykle zvyšuje upovídanost programu. Například tar -cv vypíše jména souborů přidávaných do archivu, tar -cvv vypíše také atributy souborů (podobně jako ls -l). (Vše se vypíše na stderr, takže stdout lze stále používat pro archiv) Obyčejný tar -t vypíše pouze názvy souborů, tar -tv vypíše i atributy souborů.

Tímto způsobem lze vytvořit nekomprimovaný archiv:

tar -cf archiv.tar adresar_k_archivaci/

Komprimovaný archiv vytvoříte tak, že výstup příkazu tar předáte příkazu gzip:

tar -c adresar_k_archivaci/ | gzip >archiv.tar.gz

Protože je to však velmi časté, tar podporuje přepínač -z, který automaticky volá gzip, takže můžete psát:

tar -czf archiv.tar.gz adresar_k_archivaci/

tar má další přepínače pro další (de)kompresní programy: bzip2, xz atd.. Nejdůležitější je přepínač -a, který vybírá (de)kompresní program podle názvu archivního souboru.

Pokud chcete komprimovat jen jeden soubor, často se používá prostý gzip bez tar. Některé nástroje nebo rozhraní API mohou dokonce zpracovávat soubory komprimované pomocí gzip transparentně.

Chcete-li archiv rozbalit, můžete do tar rourou poslat gzip -d (dekomprimovat) nebo použít -z následujícím způsobem:

tar -xzf archive.tar.gz
Stejně jako mnoho jiných programů souvisejících se souborovým systémem přepíše tar existující soubory bez jakéhokoli varování.

Pro usnadnění práce s archivy vám doporučujeme nainstalovat si atool jako obecný obal kolem tar, gzip, unzip a mnoha dalších nástrojů. Například:

apack archive.tar.gz dir_to_archive/
aunpack archive.tar.gz

Všimněte si, že atool ve výchozím nastavení nepřepisuje existující soubory (což je další velmi dobrý důvod pro jeho použití).

Je dobré vždy archivovat jeden adresář. Uživatel, který váš archiv rozbalí, tak nebude mít vaše soubory roztroušené v aktuálním adresáři, ale přehledně připravené v jediném novém adresáři.

Pro vypsání souborů v archívu můžete spustit příkaz als.

Vývoj softwaru ve virtuálním prostředí

Během předchozích cvičení jsme viděli, že doporučovaným způsobem instalace aplikací (a knihoven nebo datových souborů) na Linuxu je skrze správce balíčků. Ten nainstaluje aplikaci pro všechny uživatele, umožní upgrade celého systému a celkově udržuje systém v rozumném stavu.

Nicméně, ne vždy se systémová instalace hodí. Typický příklad jsou závislosti pro konkrétní projekt. Ty se obvykle neinstalují do systému a to hlavně z následujících důvodů:

  • Potřebujete různé verze závislostí pro různé projekty.
  • Nechcete si pamatovat, co všechno máte odinstalovat, když na projektu přestanete pracovat.
  • Potřebujete určit, kdy dojde k jejich upgradu: upgrade OS by neměl ovlivnit váš projekt.
  • Verze, které potřebujete, jsou jiné, než které zná správce balíčků.
  • A nebo nejsou vůbec ve správci balíčků dostupné.

Z výše uvedených důvodů je mnohem lepší vytvořit instalaci určenou pro jeden projekt, která je lépe oddělena (izolována) od zbytku systému. V tomto ohledu instalace pro uživatele (tj. někam do $HOME) nemusí poskytnout takovou míru odstínění, jakou chceme.

Tento přístup podporuje většina rozumných programovacích jazyků a obvykle je najdeme pod názvy jako virtual environment, local repository, sandbox nebo něco podobného (koncepty nejsou 1:1 ve všech jazycích a nástrojích, ale základní myšlenka je stejná).

S virtuálním prostředím (virtual environment) jsou závislosti obvykle instalovány do určeného adresáře ve vašem projektu. Tento adresář potom neverzujeme (Gitem). Překladač/interpret je pak nasměrován na tento adresář.

Instalace do jednoho adresáře nezanese váš systém. Umožní vám pracovat na více projektech s nekompatibilními závislostmi, protože jsou kompletně oddělené.

Instalační adresář je zřídkakdy nahráván do Gitového repozitáře. Místo toho se nahraje konfigurační soubor, který určuje, jak prostředí připravit.

Každý vývojář si pak může prostředí vytvořit, aniž by do repozitáře přibývaly soubory, které jsou specifické pro danou distribuci nebo operační systém. Ale konfigurační soubor zajistí, že všichni budou pracovat s identických prostředím (tj. stejné verze všech závislostí).

Také to znamená, že noví členové softwarového týmu si mohou prostředí jednoduše připravit právě s pomocí takového konfiguračního souboru.

Instalace závislostí

Uvnitř virtuálního prostředí projektu se obvykle nepoužívají správci balíčků (jako DNF). Místo toho jsou závislosti instalovány správci balíčků daného programovacího jazyka.

Ty jsou obvykle platformě nezávislé a používají vlastní repozitáře. Tyto repozitáře pak obsahují jen knihovny pro daný programovací jazyk. Opět může být těchto repozitářů více a je na vývojářích, jak si vše nastaví

Technicky vzato, i jazykoví správci balíčků umí nainstalovat balíčky globálně do systému. Čímž zasahují do práce klasických správců balíčků. Je na administrátorovi, aby to nějak rozumně uřídil. Obvykle to znamená, že existuje hranice, kam instaluje systémový správce balíčků a kam správce balíčků daného jazyka.

V našem případě budeme vždy instalovat jen do adresářů virtuálního prostředí a do systému jako takového zasahovat nebudeme.

Instalační adresáře

Na typickém Linuxovém systému existuje několik míst, kam může být software nainstalován:

  • /usr – systémové balíčky jak je instaluje správce balíčků dané distribuce
  • /usr/local – software instalovaný lokálně administrátorem; sem obvykle instalují svoje balíčky správci balíčků daného jazyka, pokud je instalují globálně (system-wide)
  • /opt/$PACKAGE – velké balíčky, které neinstaluje správce balíčků, mají často celý vlastní adresář uvnitř /opt.
  • $HOME (obvykle /home/$USER/) – jazykoví správci balíčků spuštění ne-rootem mohou balíčky nainstalovat do domovských adresářů (přesné umístění záleží na jazyce).
  • $HOME/.local je obvyklé místo pro lokální instalaci, které kopíruje /usr/local, ale je jen pro jednoho uživatele (spustitelné soubory jsou pak v $HOME/.local/bin)
  • virtuální prostředí pro každý projekt

Python Package Index (PyPI)

Zbytek textu se bude zabývat Pythoními nástroji. Podobné nástroje jsou ale dostupné i pro další jazyky: věříme, že ukázky nad Pythonem jsou dostačující pro demonstraci principů v praxi.

Python má repozitář zvaný Python Package Index (PyPI), kde kdokoliv může zveřejnit své Pythonovské knihovny či programy.

Repozitář je možné používat buď skrz webový prohlížeč, nebo přes klienta na příkazové řádce, který se jmenuje pip.

pip se chová podobně jako DNF. Můžete s ním instalovat, upgradovat nebo odinstalovat Pythoní moduly.

Pokud ho spustíte s právy superuživatele, může instalovat balíčky do systému. Nedělejte to, pokud si nejste jistí tím, co chcete, a zda chápete možné důsledky.

Problémy s důvěryhodností

Všechny balíčky z hlavního repozitáře vaší distribuce jsou obvykle kontrolovány někým z bezpečnostního týmu pro danou distribuci. To bohužel není pravda pro repozitáře, jako je PyPI. Takže jako vývojář musíte být opatrnější, když budete instalovat software z těchto zdrojů.

Ne všechny balíčky dělají to, co slibují. Některé jejich chyby jsou jen neškodné hlouposti, ale některé jsou záměrně škodlivé. Používání existujícího kódu je obvykle dobrý nápad, ale měli byste se zamyslet nad důvěryhodností autora. Konec konců, kód poběží na vašem účtu, až jej budete spouštět nebo instalovat.

Typickým příkladem je tzv. typosquatting, kdy lumpové zveřejní svůj zákeřný balíček a jeho jméno se liší jen překlepem od jiného známého balíčku. Můžeme doporučit tenhle článek, ale na webu jich lze najít mnohem víc.

Na druhou stranu, mnoho PyPI balíčků je také dostupných jako balíčky pro vaši distribuci (klidně si zkuste dnf search python3- na vašem Fedořím stroji). Takže byly pravděpodobně už některým ze správců distribuce zkontrolovány a jsou v pořádku. Pro balíčky, které takto dostupné nejsou, se vždy dívejte na znaky normálního a zákeřného projektu. Oblíbenost repozitáře se zdrojáky. Uživatelské aktivita. Jak reagují na bug reporty? Kvalita dokumentace. Atd. atd.

Nezapomeňte, že dnešní software je málokdy stavěn na zelené louce. Nebojte se zkoumat, co už je hotové. Zkontrolujte si to. A pak to použijte :-).

Obvyklý průběh práce

Zatímco konkrétní nástroje se liší podle programovacího jazyka, základní kroky pro vývoj projektu uvnitř virtuálního projektu jsou v podstatě vždy stejné.

  1. Vývojář naklonuje projekt (třeba z Gitového repozitáře).
  2. Virtuální prostředí (sandbox) je inicializováno. To obvykle znamená vytvoření nového adresáře s čistým prostředím pro daný jazyk.
  3. Virtuální prostředí musí být aktivováno. Obvykle virtuální prostředí musí změnit $PATH (nebo nějaký podobný ekvivalent, který je používán pro hledání knihoven a modulů), takže vývojář musí source (nebo .) nějaký aktivační skript, aby byly změněny příslušné proměnné.
  4. Potom může vývojář nainstalovat závislosti. Obvykle jsou uloženy v souboru, který lze přímo předat správci balíčků (daného programovacího jazyka).
  5. Teprve teď může vývojář začít na projektu pracovat. Projekt je kompletně izolován, odstraněním adresáře s virtuálním prostředím odstraníme i veškeré stopy po instalovaných balíčcích.

Každodenní práce pak zahrnuje jen krok č. 3 (nějaký způsob aktivace) a krok 5 (vlastní vývoj).

Poznamenejme, že aktivace virtuálního prostředí obvykle odstraní přístup ke globálně (systémově) nainstalovaným knihovnám. Uvnitř virtuálního prostředí vývojář začíná s čistým štítem: jen s holým překladačem. To je ale velmi rozumné rozhodnutí: zajistí, že libovolná systémová instalace neovlivní nastavení projektu.

Jinými slovy to zlepší opakovatelnost (reproducibility) celého nastavení. Také to znamená, že vývojář musí uvést každou závislost do konfiguračního souboru. I pokud je to závislost, která je obvykle vždy nainstalovaná.

Virtuální prostředí pro Python (také známé jako virtualenv nebo venv)

Abychom si mohli bezpečně vyzkoušet instalaci balíčků Pythonu, nastavíme nejprve virtuální prostředí pro náš projekt. Python má naštěstí vestavěnou podporu pro vytvoření virtuálního prostředí.

Ukážeme si to na následujícím příkladu:

#!/usr/bin/env python3

import argparse
import shutil
import sys

import fs

class FsCatException(Exception):
    pass

def fs_cat(filesystem, filename, target):
    try:
        with fs.open_fs(filesystem) as my_fs:
            try:
                with my_fs.open(filename, 'rb') as my_file:
                    shutil.copyfileobj(my_file, target)
            except fs.errors.FileExpected as e:
                raise FsCatException(f"{filename} on {filesystem} is not a regular file") from e
            except fs.errors.ResourceNotFound as e:
                raise FsCatException(f"{filename} does not exist on {filesystem}") from e
    except Exception as e:
        if isinstance(e, FsCatException):
            raise e
        raise FsCatException(f"unable to read {filesystem}, perhaps misspelled path or protocol ({e})?") from e


def main():
    args = argparse.ArgumentParser(description='Filesystem cat')
    args.add_argument(
        'filesystem',
        nargs=1,
        metavar='FILESYSTEM',
        help='Filesystem specification, e.g. tar://path/to/file.tar'
    )
    args.add_argument(
        'filename',
        nargs=1,
        metavar='FILENAME',
        help='File path on FILESYSTEM, e.g. /README.md'
    )

    config = args.parse_args()

    try:
        fs_cat(config.filesystem[0], config.filename[0], sys.stdout.buffer)
    except FsCatException as e:
        print(f"Fatal: {e}", file=sys.stderr)
        sys.exit(1)

if __name__ == "__main__":
    main()

Uložte tento kód do souboru fscat.py a nastavte mu spustitelný bit. Všimněte si, že fs.open_fs dokáže otevírat různé souborové systémy a přistupovat k souborům v nich, jako byste použili vestavěný pythonovský open.

V našem programu zadáme cestu k souborovému systému a souboru (z tohoto filesystému), který má být vypsán na obrazovku (odtud název fscat, protože simuluje cat uvnitř jiného souborového systému).

Než budete pokračovat, ujistěte se, že celému programu rozumíte.

Zkuste spustit program fscat.py.

Pokud nemáte v systému nainstalovaný balíček python3-fs, mělo by dojít k chybě ModuleNotFoundError: No module named 'fs'. Je pravděpodobné, že tento modul nainstalovaný nemáte.

Pokud jste již nainstalovali python3-fs, odinstalujte jej a zkuste to znovu (jen pro tuto ukázku). Ale dvakrát zkontrolujte, zda byste neodstranili nějaký jiný program, který jej může vyžadovat.

Nyní bychom mohli nainstalovat python3-fs pomocí DNF, ale již jsme vysvětlili, proč to není dobrý nápad. Mohli bychom jej také nainstalovat globálně pomocí pip, ale ani to není nejlepší postup.

Místo toho pro něj vytvoříme nové virtuální prostředí.

python3 -m venv my-venv

Výše uvedený příkaz vytvoří nový adresář my-venv, který obsahuje čistou instalaci Pythonu. Neváhejte a prozkoumejte obsah tohoto adresáře.

Nyní je třeba toto prostředí aktivovat.

source my-venv/bin/activate

Váš prompt by se měl změnit: nyní začíná (my-venv).

Spuštění souboru fscat.py přesto skončí s chybou ModuleNotFoundError.

Nyní nainstalujeme závislost:

pip install fs

To bude chvíli trvat, protože Python bude stahovat také tranzitivní závislosti této knihovny (a jejich závislosti atd.). Po dokončení instalace spusťte znovu soubor fscat.py.

Tentokrát by to mělo fungovat.

./fscat.py

Dobře, vypsalo to chybovou zprávu o požadovaných argumentech. Stáhněte si tento archív a spusťte skript následujícím způsobem:

./fscat.py tar://test.tar.gz testdir/test.txt

Měl by vypsat Test string, protože je schopen pracovat i s tar archívy jako se souborovými systémy a vypsat na nich soubory (ověřte, zda je soubor skutečně k dispozici, buď pomocí atool, MC, nebo přímo pomocí tar).

Jakmile jsme s vývojem hotovi, můžeme prostředí deaktivovat voláním deactivate (tentokrát bez zadávání zdrojů).

Spuštění souboru fscat.py mimo prostředí opět skončí chybou ModuleNotFoundError.

Jak to funguje?

Virtuální prostředí Pythonu používá při své implementaci dva triky.

Nejprve skript activate rozšíří $PATH o adresář my-venv/bin. To znamená, že volání python3 bude preferovat aplikaci z adresáře virtuálního prostředí (např. my-venv/bin/python3).

Vyzkoušejte si to sami: vypište $PATH před a po aktivaci virtuálního prostředí.

To také vysvětluje, proč bychom měli v shebangu vždy zadávat /usr/bin/env python3 místo /usr/bin/python3. env se bude řídit proměnnou $PATH, která byla změněna aktivací virtuálního prostředí.

Můžete si také prohlédnout skript activate a zjistit, jak je implementován. Všimněte si, že deactivate je ve skutečnosti funkce.

Proč není skript activate spustitelný? Hint.

Druhý trik spočívá v tom, že Python hledá moduly (tj. soubory implementující importovaný modul) vzhledem k cestě k binárnímu souboru python3. Pokud je tedy python3 uvnitř my-venv/bin, Python bude hledat moduly uvnitř my-venv/lib. To je adresář, kde budou umístěny lokálně nainstalované soubory.

To si můžete ověřit spuštěním následujícího jednořádkového příkazu, který vypíše prohledávané adresáře Pythonu (opět před a po aktivaci):

python3 -c 'import sys; print(sys.path)'

Toto chování ve skutečnosti není v interpretu jazyka Python pevně zabudováno. Při spuštění Pythonu se automaticky importuje modul site. Tento modul obsahuje nastavení specifické pro dané umístění: upraví soubor sys.path tak, aby obsahoval všechny adresáře, do kterých vaše distribuce instaluje moduly Pythonu. Detekuje také virtuální prostředí tak, že hledá soubor pyvenv.cfg v prarodičovském adresáři binárního souboru python3. V našem případě tento konfigurační soubor obsahuje include-system-site-packages=false, což modulu site říká, aby adresáře s moduly distribuce vynechal. Vidíte, že princip je velmi jednoduchý a samotný interpret nemusí o virtuálních prostředích nic vědět.

Instalace balíčků specifických pro Python pomocí pip

pip VS. python3 -m pip?

Obecně se doporučuje používat python3 -m pip, nikoli surový pip. Důvody, které vedly k těmto dalším deseti stiskům kláves, jsou dobře popsány v článku Why you should use python3 -m pip. Aby však byl následující text čitelnější, budeme používat kratší variantu pip.

Jedno použití pipu v praxi jsme si již ukázali, ale pip toho umí mnohem více. Pěkný přehled všech možností pipu najdete v článku Using Python’s pip to Manage Your Projects' Dependencies.

Zde uvádíme stručný přehled nejdůležitějších pojmů a příkazů.

Ve výchozím nastavení pip install prohledává registr balíčků PyPI, aby nainstaloval balíček zadaný na příkazovém řádku. Nebyli bychom daleko od pravdy, kdybychom řekli, že všechny balíčky uvnitř tohoto registru jsou jen archivované adresáře, které obsahují předepsaným způsobem uspořádaný zdrojový kód v jazyce Python.

Pokud chcete tento výchozí registr balíčků změnit, můžete použít argument --index-url.

Protože jste již s GitLabem obeznámeni, mohl by vás zajímat GitLab PyPI Package Registry Support.

V další části se naučíme, jak z adresáře s kódem vytvořit správný balíček Pythonu. Za předpokladu, že jsme to již udělali, můžeme tento balíček nainstalovat přímo (bez archivace/balení) příkazem pip install /path/to/python_package.

Představte si například situaci, kdy máte zájem o open-source balíček třetí strany. Tento balíček je k dispozici ve vzdáleném repozitáři git (typicky na GitHubu nebo GitLabu), ale NENÍ zabalen a zveřejněn v PyPI. Můžete jednoduše klonovat repozitář a spustit pip install .. Díky pip VCS Support se však můžete fázi klonování vyhnout a balíček nainstalovat přímo pomocí:

pip install git+https://git.example.com/MyProject

Chcete-li aktualizovat konkrétní balíček, spusťte příkaz pip install --upgrade [packages].

Nakonec pro odstranění balíčku spustíte pip uninstall [packages].

Verzování závislostí

Možná jste už slyšeli o sémantickém verzování. Python používá víceméně kompatibilní verzování, které je popsáno v PEP 440 – Version Identification and Dependency Specification.

Při instalaci závislostí z registru balíčků můžete tuto verzi zadat.

pkgname          # latest version
pkgname == 4.2   # specific version
pkgname >= 4.2   # minimal version
pkgname ~= 4.2   # equivalent to >= 4.2, == 4.*

Pravdou je, že specifikátor verze se skládá z řady klauzulí o verzi oddělených čárkami. Proto můžete zadat:

pkgname >= 1.0, != 1.3.4.*, < 2.0

Někdy je užitečné uložit seznam všech aktuálně nainstalovaných balíčků (včetně tranzitivních závislostí). Například jste si nedávno všimli nové chyby ve svém projektu a rádi byste si uchovali přesné verze aktuálně nainstalovaných závislostí, aby váš spolupracovník mohl chybu reprodukovat.

Za tímto účelem je možné použít pip freeze a vytvořit seznam, který nastaví konkrétní verze a zajistí tak stejné prostředí pro každého vývojáře.

Doporučujeme je uložit do souboru requirements.txt.

# Generating requirements file
pip freeze > requirements.txt

# Installing package from it
pip install -r requirements.txt

Balení Pythoních projektů

Řekněme, že jste přišli na super skvělý algoritmus a chcete obohatit svět tím, že se o něj podělíte. Oficiální dokumentace Pythonu nabízí návod krok za krokem, jak toho dosáhnout.

V následujícím textu budeme používat setuptools pro sestavování projektů v jazyce Python. Historicky to byla jediná možnost, jak sestavit Pythoní balíček. V poslední době se vývojáři Pythonu rozhodli otevřít brány alternativám, a tak můžete balíček Pythonu sestavit také pomocí Poetry, flit nebo dalších. Popis těchto nástrojů je mimo rámec tohoto kurzu.

Struktura adresáře balíčků Pythonu

Úplně prvním krokem, než jej můžete publikovat, je jeho transformace do správného balíčku Pythonu. Musíme vytvořit soubory pyproject.toml a setup.cfg. Tyto soubory obsahují informace o projektu, seznam závislostí a také informace pro instalaci projektu.

Ještě nedávno bylo obvyklé mít skript setup.py, nikoli setup.cfg a pyproject.toml. Proto v mnoha repozitářích/návodech stále můžete najít jeho použití. Obsah je víceméně 1:1, ale jsou určité případy, kdy jste nuceni použít setup.py. To naštěstí pro náš usecase neplatí, a proto jsme se rozhodli popsat moderní variantu se statickými konfiguračními soubory.
Jak se píše v setuptools Quickstart, od verze 61.0.0 nabízí setuptools možnost experimentálního použití pouze pyproject.toml. Tento přístup používá také Poetry, ale v následujícím textu zůstaneme u stabilní kombinace setup.cfg a pyproject.toml.

V repozitáři fscat najdete balíček Pythonu se stejnou funkčností, jakou má náš předchozí skript fscat.py.

Pečlivě si prostudujte adresářovou strukturu a obsah souboru setup.cfg.

Můžeme si všimnout, že potřebné závislosti jsou v souboru setup.cfg a v souboru requirements.txt duplicitní. Ve skutečnosti to není chyba. V souboru setup.cfg je třeba použít co nejslabší verzi závislosti, zatímco v souboru requirements.txt musíme všechny závislosti uvést s přesnou verzí. Existují také tranzitivní závislosti, které by se v souboru setup.cfg NEMĚLY vyskytovat.

Další podrobnosti naleznete v části install_requires vs requirements file.

Zkuste si tento balíček (s pomocí podpory VCS) následujícím příkazem nainstalovat:

pip install git+http://gitlab.mff.cuni.cz/teaching/nswi177/2023/common/fscat.git

Možná jste si všimli, že soubor setup.cfg obsahuje sekci [options.entry_points]. Tato sekce určuje, jaké jsou skripty váš projekt aktuálně obsahuje. Všimněte si, že po spuštění výše uvedeného příkazu můžete spustit příkaz fscat přímo. Pip pro vás vytvořil obalový skript a přidal jej do $PATH virtuálního prostředí.

fscat tar://tests/test.tar.gz testdir/test.txt

Nyní balíček odinstalujte pomocí:

pip uninstall matfyz-nswi177-fscat

Naklonujte repozitář do místního počítače a vstupte do jeho adresáře. Nyní spusťte:

pip install -e .

pip install -e vytvoří editovatelnou instalaci pro snadné ladění. Namísto kopírování vašeho kódu do virtuálního prostředí nainstaluje pouze věc podobnou symlinku (ve skutečnosti soubor fscat.egg-link, který má podobný účinek na mechanismus Pythonu pro vyhledávání modulů) odkazující na adresář s vašimi zdrojovými soubory.

Sestavení Pythoního balíčku

Když už máme správnou adresářovou strukturu, zbývají nám už jen dva kroky k jejímu zveřejnění v registru balíčků.

Nyní připravíme distribuční balíčky pro náš kód. Nejprve nainstalujeme balíček build příkazem pip install build. Poté můžeme spustit příkaz

python3 -m build

V podadresáři dist se vytvoří dva soubory:

  • matfyz-nswi177-fscat-0.0.1.tar.gz – archiv zdrojového kódu

  • matfyz_nswi177_fscat-0.0.1-py3-none-any.whlwheel soubor, což je sestavený balíček (py3 je požadovaná verze Pythonu, none a any říkají, že se jedná o balíček nezávislý na platformě).

Všimněte si, že wheel soubor není nic jiného než jednoduchý zip archiv.

$ file dist/matfyz_nswi177_fscat-0.0.1-py3-none-any.whl
dist/matfyz_nswi177_fscat-0.0.1-py3-none-any.whl: Zip archive data, at least v2.0 to extract, compression method=deflate

$ unzip -l dist/matfyz_nswi177_fscat-0.0.1-py3-none-any.whl
Archive:  dist/matfyz_nswi177_fscat-0.0.1-py3-none-any.whl
  Length      Date    Time    Name
---------  ---------- -----   ----
       51  2023-04-11 13:17   fscat/__init__.py
      837  2023-04-11 14:44   fscat/fscat.py
      777  2023-04-11 14:19   fscat/main.py
     1075  2023-04-11 15:20   matfyz_nswi177_fscat-0.0.1.dist-info/LICENSE
     1039  2023-04-11 15:20   matfyz_nswi177_fscat-0.0.1.dist-info/METADATA
       92  2023-04-11 15:20   matfyz_nswi177_fscat-0.0.1.dist-info/WHEEL
       42  2023-04-11 15:20   matfyz_nswi177_fscat-0.0.1.dist-info/entry_points.txt
        6  2023-04-11 15:20   matfyz_nswi177_fscat-0.0.1.dist-info/top_level.txt
      769  2023-04-11 15:20   matfyz_nswi177_fscat-0.0.1.dist-info/RECORD
---------                     -------
     4688                     9 files

Možná vás zajímá, proč existují dva archivy s velmi podobným obsahem. Odpověď najdete v článku What Are Python Wheels and Why Should You Care?.

Nyní se můžete přepnout do jiného virtuálního prostředí a nainstalovat balíček pomocí pip install package.whl.

Publikování Pythoního balíčku

Pokud si myslíte, že by balíček mohl být užitečný i pro další lidi, můžete jej zveřejnit v Python Package Index. To se obvykle provádí pomocí nástroje twine. Přesný postup je popsán v části Uploading the distribution archives.

Vytváření distribučních balíčků (např. pro DNF)

I když se může zdát, že práce s vytvářením projektových souborů je velmi komplikovaná, ve skutečnosti z dlouhodobého hlediska šetří čas.

Prakticky každý vývojář Pythonu by nyní mohl nainstalovat váš program a mít jasný výchozí bod při zkoumání dalších detailů.

Všimněte si, že pokud jste instalovali nějaký program prostřednictvím DNF a tento program byl napsán v jazyce Python, někde uvnitř byl soubor setup.cfg, který vypadal velmi podobně jako ten, který jste právě viděli. Jen místo toho, aby se skript nainstaloval do vašeho virtuálního prostředí, byl nainstalován globálně.

Žádné jiné kouzlo za tím opravdu není.

Všimněte si, že například Ranger je napsán v jazyce Python a tento skript popisuje jeho instalaci (jedná se o skript pro vytváření balíčků pro DNF). Všimněte si, že %py3_install je makro, které ve skutečnosti volá setup.py install.

Nástroje vyšší úrovně

Na pip a virtualenv můžeme pohlížet jako na nízkoúrovňové nástroje. Existují však i nástroje, které oba tyto nástroje kombinují a přinášejí větší komfort při správě balíčků. V jazyce Python existují přinejmenším dvě oblíbené možnosti, a to Poetry a Pipenv.

Interně tyto nástroje používají pip a venv, takže stále můžete mít nezávislé pracovní prostory a také možnost nainstalovat konkrétní balíček z Python Package Index (PyPI).

Úplné představení těchto nástrojů je mimo rámec tohoto kurzu. Obecně se řídí stejnými principy, ale přidávají některé funkce navíc, které je hezké mít. Ve stručnosti lze uvést tyto hlavní rozdíly:

  • Mohou zmrazit určité verze závislostí, takže se projekt sestaví na všech počítačích stejně (pomocí souboru poetry.lock).
  • Balíčky lze odstranit spolu s jejich závislostmi.
  • Inicializace nového projektu je jednodušší.

Ostatní jazyky

Ostatní jazyky mají vlastní nástroje s podobnými funkcemi:

Úlohy před cvičením (deadline: začátek vašeho cvičení, týden 24. dubna - 28. dubna)

Následující úlohy musí být vyřešeny a odevzdány před příchodem na vaše cvičení. Pokud máte cvičení ve středu v 10.40, soubory musí být nahrány do vašeho projektu (repozitáře) na GitLabu nejpozději ve středu v 10.39.

Pro virtuální cvičení je deadline úterý 9:00 (každý týden, vždy ráno, bez ohledu na možné státní svátky apod.).

Všechny úlohy (pokud není explicitně uvedeno jinak) musí být odevzdány přes váš repozitář na úkoly. Pro většinu úloh existují automatické testy, které vám mohou pomoci zkontrolovat úplnost vašeho řešení (zde je popsáno jak číst jejich výsledky).

11/romandate.py (100 bodů, skupina devel)

Napište program v jazyce Python, který pomocí balíčků roman a dateparser vypíše uživatelem zadané datum římskými číslicemi.

Program nejlépe vystihují níže uvedené příklady (za předpokladu, že byly provedeny 24. dubna 2023).

./romandate.py
XXIV.IV.MMXXIII
./romandate.py 2021-01-01
I.I.MMXXI
./romandate.py 40 years ago
XXIV.IV.MCMLXXXIII

Testy předpokládají, že jsou již spuštěny ve virtuálním prostředí, kde jsou nainstalovány výše uvedené balíčky (při spuštění na GitLabu se tyto dva balíčky nainstalují automaticky).

Dodané testy kontrolují pouze přesná data (až je budeme hodnotit po deadline, vložíme do nich aktuální datum).

Nezapomeňte zkontrolovat, že vaše řešení také funguje

  • když je spuštěno bez parametrů (čas nyní, tedy now)
  • když je spuštěno s relativními daty jako třeba 5 days ago

Úlohy po cvičení (deadline: 14. května)

Očekáváme, že následující úlohy vyřešíte po cvičení, tj. poté, co budete mít zpětnou vazbu k vašim řešením úloh před cvičením.

Všechny úlohy (pokud není explicitně uvedeno jinak) musí být odevzdány přes váš repozitář na úkoly. Pro většinu úloh existují automatické testy, které vám mohou pomoci zkontrolovat úplnost vašeho řešení (zde je popsáno jak číst jejich výsledky).

11/project-name/ (70 bodů, skupina devel)

Připravte Pythoní balíček, který poskytuje příkaz project-name, který se pokusí automaticky určit název projektu.

Podobně jako v jednom z prvních úkolů v tomto kurzu program hledá v souborech README.md a README první neprázdný řádek (opět odstraní přebytečné bílé znaky a úvodní # v souborech *.md).

Pokud není k dispozici README.md ani README, program se pokusí najít nejvyšší adresář projektu Git (zvažte použití parametru konstruktoru search_parent_directories=True a vlastnosti working_tree_dir u typu Repo z GitPython) a vypíše jeho jméno (bez cesty).

Pokud aktuální adresář není součástí projektu Git, program vypíše jméno aktuálního adresáře (opět bez cesty).

Očekáváme, že následující postup bude fungovat (pravděpodobně nejlépe ve virtuálním prostředí).


project-name
# Prints 'NSWI177 Submission Repository'
cd 01
project-name
# Prints 'student-LOGIN'
cd ../../
project-name
# Prints directory name of the parent directory of your submission repository clone

Očekáváme, že si vytvoříte správný podadresář src a správně uspořádáte svůj balíček pomocí souboru setup.cfg atd.

Klidně použijte části svého řešení úlohy 01.

Automatické testy vždy vytvoří nové virtuální prostředí pro každý testovaný případ. Což je fajn pro závěrečnou kontrolu. Ale je též možné testy spustit v aktivovaném virtuálním prostředí, kdy očekávají, že příkaz project-name už je nainstalován. A sice přes nastavení NSWI177_LAB11_NO_INSTALL=true (takže pak přeskočí část pip install 11/project-name, což je docela dost zrychlí):

env NSWI177_LAB11_NO_INSTALL=true ./bin/run_tests.sh 11-post/project_name

11/fat.txt (30 bodů, skupina admin)

Soubor linux.ms.mff.cuni.cz:~/lab11.fat.img je obraz disku s jediným souborem. Vložte jeho (dekomprimovaný) obsah do 11/fat.txt (do GitLabového repozitáře).

Soubor ~/lab11.fat.img vám můžeme vytvořit jen tehdy, když se k počítači alespoň jednou přihlásíte.

Pokud tam soubor nemáte, počkejte, prosím, do druhého dne.

Nenechávejte úlohu na poslední chvíli a ozvěte se, pokud se soubor neobjevil, jak je popsáno výše.

Tato úloha je pouze částečně testována automatickými testy.

Učební výstupy

Učební výstupy podávají zhuštěný souhrn základních konceptů a dovedností, které byste měli umět vysvětlit a/nebo použít po každém cvičení. Také obsahují absolutní minimum, které je potřebné pro pochopení navazujících cvičení (a dalších předmětů).

Znalosti konceptů

Znalost konceptů znamená, že rozumíte významu a kontextu daného tématu a jste schopni témata zasadit do většího rámce. Takže, jste schopni …

  • vysvětlit, co je to obraz disku

  • vysvětlit, proč nejsou zapotřebí žádné speciální nástroje pro práci s obrazy disků

  • vysvětlit rozdíl mezi normálním (obyčejným) souborem, adresářem, symbolickým odkazem, souborem zařízení a souborem reprezentujícím stav systému (např. ze souborového systému /proc)

  • vyjmenovat základní adresáře nejvyšší úrovně v typické instalaci Linuxu a popsat jejich funkci

  • vysvětlit v obecné rovině, jak je strom adresářů vytvořen připojením jednotlivých (souborových) podsystémů

  • vysvětlit, co jsou požadavky (závislosti na knihovnách)

  • vysvětlit základy sémantického verzování

  • vysvětlit, jaké jsou výhody a nevýhody instalace závislostí pro celý systém vs jejich instalaci ve virtuálním prostředí

  • poskytnout vysokoúrovňový přehled virtuálních prostředí

  • vysvětlit výhod a nevýhody uvedení tranzitivních závislostí ve srovnání s uvedením jen přímých

  • vysvětlit výhody a nevýhody uvedení přesné verze nebo jen minimální

  • vysvětlit, proč Linux zachovává oddělení archivace a komprese (např. tar a gzip)

Praktické dovednosti

Praktické dovednosti se obvykle týkají použití daných programů pro vyřešení různých úloh. Takže, dokážete …

  • připojit a pracovat s disky pomocí příkazu mount (jak s fyzickými tak s obrazy disků)

  • získat souhrnné informací o využití disku pomocí příkazu df

  • použít pro práci se standardními linuxovými archivy tar nebo atool

  • vytvořit nové virtuální prostředí (pro Python) pomocí python3 -m venv

  • aktivovat a deaktivovat virtuální prostředí

  • nainstalovat závislosti projektu do virtuálního prostředí pomocí pip

  • vyvíjet program uvnitř virtuálního prostředí (s projektem používajícím setup.cfg a pyproject.toml)

  • nainstalovat projekt, který používá setup.cfg

  • volitelné: použít lsblk ke zjištění informací o úložných zařízeních

  • volitelné: připravit projekt Pythonu pro instalaci

Seznam změn na této stránce

  • 2023-04-17: Výskyty python nahrazeny python3 kvůli větší přesnosti.

  • 2023-04-20: Přidány automatické testy pro úlohy před cvičením.

  • 2023-04-28: Přidány automatické testy pro úlohy po cvičení.

  • 2023-06-14: Poznámka o připojování disků ve VirtualBoxu.