Wieki temu został mi podrzucony adres takiego cudaka jak Nix. Kliknąłem, przejrzałem, rzecz ogólnie olałem. Ładne, ale średnio przydatne. Ostatnio wróciłem… i muszę przyznać, że tym razem trafiło do mnie bardziej. Może dlatego, że w międzyczasie nauczyłem się paru bardziej teoretycznych rzeczy na temat komputerów i systemów, a może dlatego, że na roku poszła plotka, jakobyśmy powinni wybrać sobie temat magisterki, więc na mijane w sieci ciekawostki patrzę ostatnio pod nieco innym kątem.
Ale o co właściwie chodzi? Trudno rzecz zwięźle opisać, nie czyniąc przy tym nadmiernych uproszczeń. Autorzy projektu stwierdzili, że przestrzeń dyskowa jest rodzajem pamięci (co samo w sobie jest mało odkrywcze), więc do zarządzania nią można użyć mechanizmów od lat już używanych do zarządzania pamięcią operacyjną – co jest już ciekawsze. Istnieją języki programowania, które nie wspierają nadpisywalnych danych; zamiast nadpisywalnych zmiennych są niemutowalne wartości przypisywane etykietom. Takie języki nazywamy funkcyjnymi. Nix jest czysto funkcyjnym systemem pakietów.
Przestrzeń składowa
Pakiety są opisywane funkcjami nieposiadającymi efektów ubocznych, zapisywane w unikalnych katalogach przestrzeni składowej (store) i opisywane oprócz nazwy i numeru wersji haszem całej znanej konfiguracji. W jednym systemie może być więc zapisanych jednocześnie wiele wersji i wariantów tego samego pakietu. Każdy pakiet zależy od konkretnej wersji i wariantu pakietów, dla których został przebudowany (i te pakiety też są częścią konfiguracji – równie dobrze jak mieć Firefoksa 1.x, 2.x i 3.x na jednym systemie, nie mamy problemów ze skompilowaniem tego samego programu w tej samej wersji, ale z różnymi wersjami jakiejś biblioteki). Ponieważ w ścieżce występuje hasz jednoznacznie określający wariant pakietu, mamy łatwy dostęp do całego grafu zależności przy użyciu zwykłego polecenia grep.
Co więcej, pełny opis zależności jest tutaj wymuszony przez system. W tradycyjnych systemach zarządzania pakietami (rpm, dpkg, slackowe tarballe…) jeśli nie podałem w opisie pakietu któregoś z pakietów wymaganych do jej kompilacji, to jeśli posiadam ten pakiet w systemie, paczka skompiluje się i tak. U mnie. U kogo innego – niekoniecznie się skompiluje, tym bardziej niekoniecznie skompiluje się tak samo jak u mnie; zależy to od pakietów obecnych na kompilujących systemie. W Nix taki myk jest po prostu niemożliwy. Paczka, która nie jest określona w opisie budowanego pakietu, jest dla niego po prostu niewidoczna.
Domknięcia i widoki
Dobra, no to opisaliśmy w skrócie własności składowania pakietów w Nix. Podejrzewam, że u tych z Was, którzy dotarli do tego miejsca z wyłączoną już lampką Ale o co w tym chodzi?
, zapaliła się w jej miejsce lampka Ale jak się w tym połapać??
. Dobre pytanie. I tutaj przychodzą na myśl dwa kolejne pojęcia pochodzące z języków funkcyjnych i zarządzania pamięcią operacyjną: domknięcia i widoki.
Nie chcę teraz omawiać pierwotnego znaczenia tych pojęć; zainteresowani mogą zerknąć choćby w Wikipedię. Skupię się za to na opisaniu znaczenia tych pojęć w Nix. Do rzeczy: domknięcie pakietu to jest pakiet plus wszystkie pakiety, od których zależy, plus wszystkie pakiety, od których one zależą, itd. – słowem, komplet pakietów koniecznych do używania danego pakietu. Skoro znamy pełne zależności każdego z pakietów, nietrudno jest dla każdego używanego pakietu wyznaczyć domknięcie.
Widok jest to zestaw pakietów widocznych na raz. Używane są do kompilacji (aby kompilowany pakiet widział wszystkie potrzebne do kompilacji narzędzia i biblioteki), a także – co chyba istotniejsze – do implementacji środowisk użytkownika. Użytkownik widzi w swoim środowisku tylko wybrane przez siebie pakiety w wybranych wersjach – i może zmieniać środowiska wedle potrzeb czy zachcianek.
Przebieg instalacji i deinstalacji pakietu
W ramach optymalizacji implementacji, wszystko, co się da, jest robione na symlinkach (lub, na systemach nie obsługujących symlinków, skryptach odnoszących się do innych katalogów). W efekcie, używane jest minimum miejsca, a instalacja przebiega następująco:
- System upewnia się, że w przestrzeni składowej znajduje się całe domknięcie pakietu. Instalowany pakiet i brakujące zależności są dodawane do składu.
- Raz zapisany do składu komponent pozostaje niezmienny i tylko do odczytu. Zatem, na podstawie bieżącego środowiska użytkownika, tworzone jest w składzie nowe środowisko, zawierające dotychczas widoczne komponenty i zainstalowany właśnie komponent.
- Symlink „bieżące środowisko” jest przenoszony na właśnie utworzone środowisko zawierające nowy program.
Podobnie przebiega aktualizacja i usuwanie pakietu. W efekcie użytkownik zawsze widzi spójny system i nie jest narażony na nieprzyjemności podczas instalacji czy uaktualnienia. Do tego, jeśli zmiana pójdzie nie tak, zawsze może jakby nigdy nic wrócić do wcześniejszego środowiska.
Do tego, każdy użytkownik może mieć osobne środowisko. Administratorzy zapewne od razu widzą zastosowanie tego systemu: użytkownik nie musi być człowiekiem, może to być serwer o ściśle określonych wymaganiach w kwestii bibliotek i programów. Każdy webapp uruchomiony na maszynie może mieć swoje ulubione środowisko (i nic ponad to), nie tworząc konfliktów z resztą systemu! Więcej, możemy w jednym systemie mieć bez bólu głowy środowisko rozwojowe i produkcyjne czy też staging.
Śmieciarka
Pytanie, co z nieużywanymi już komponentami po deinstalacji czy uaktualnieniu pakietu? Albo z komponentami potrzebnymi do zainstalowania pakietu, ale po instalacji już zbędnymi? Przy takim podejściu, składowisko w mgnieniu oka napuchnie ponad wyraz!
Na pomoc przychodzi kolejne (spokojnie, to już ostatnie) pojęcie z zakresu zarządzania pamięcią: odśmiecanie. W każdej chwili możemy składowisko odśmiecić, czyli usunąć niewidoczne z żadnego środowiska użytkownika (i, jeśli chcemy, paru wersji tego środowiska wstecz) komponenty. Przy takim mechanizmie to jest proste: śmieciarka bierze wszystkie środowiska, które chcemy zachować, oznacza komponenty w domknięciach każdego komponentu tych środowisk jako potrzebne, po czym usuwa całą resztę.
NixOS i Nix na PLD
Na zakończenie, dla sceptyków twierdzących, że w praktyce żadne nietrywialne oprogramowanie nie zniesie takiej dyscypliny: NixOS – dystrybucja Linuksa oparta w pełni o Nix. Używa Niksa nie tylko do zarządzania pakietami oprogramowania, ale też do zarządzania konfiguracją. Poza katalogiem /nix, system praktycznie nie istnieje. Nie ma /bin (poza linkiem /bin/sh do odpowiedniego komponentu Nix), /lib, /usr… można zobaczyć to na screenshocie ze strony projektu.
Sam sprawdziłem, system instaluje się i wstaje. Wiele więcej na razie nie zdziałałem, obecnie bawię się Niksem raczej na własnej workstacji na PLD. Komputer i instalacja PLD jest 64-bitowa, a Niksa zaczynam używać do zarządzania potrzebnym mi 32-bitowym oprogramowaniem (głównie Opera i inne binarki). Poldek niby obsługuje multiliba, ale słabawo – tą metodą mam dodatkową zabawkę ;)
Nix na PLD
Bardziej jako notka do siebie, bo wątpię, czy ktoś z Czytelników wytrwał do tego miejsca. Żeby korzystać sobie z Niksa w PLD, trzeba:
- Skompilować i zainstalować paczkęnix:
./builder nix (jeśli nie wiesz, o co chodzi: http://developer-doc.pld-linux.org/baseciq/slack2pld.html)
- W moim przypadku (inna architektura Nix niż systemu), polecenia
nix-env należy poprzedzać setarch i686, a w /etc/nix/nix.conf ustawić odpowiednio zmienną system
- Dodać i zaciągnąć kanały, poinstalować paczki… jak w manualu Niksa Wszystko działa zasadniczo OOTB. Powinno działać nawet uaktualnienie Niksa w Nix (wtedy można z macierzystego PLD usunąć spokojnie paczkę z Niksem), ale tego nie próbowałem.
Nie próbowałem też jeszcze stwarzać różnych środowisk, opisywać i budować własnych paczek, za to ten artykuł dodaję z:
japhy@lizard:~/rpm/SPECS % which opera
~/.nix-profile/bin/opera
japhy@lizard:~/rpm/SPECS % ps awux |grep '[o]pera'
japhy 1223 22.8 25.6 405148 378256 pts/15 S 21:40 23:07 /nix/store/bayygjghpz8mcbcwbccp0mgj8gcgv006-opera-9.24-20071015.5/lib/opera/9.50-20071024.5/opera
japhy 1233 0.0 25.6 405148 378256 pts/15 S 21:40 0:00 /nix/store/bayygjghpz8mcbcwbccp0mgj8gcgv006-opera-9.24-20071015.5/lib/opera/9.50-20071024.5/opera
japhy@lizard:~/rpm/SPECS %
W miarę zabawy pewnie dotrę do ciekawszych zastosowań i ficzerów, których z pewnością nie omieszkam opisać. Na razie to byłoby wszytko – i tak wpis wyszedł potwornie długi… dobranoc.