Statuetka idioty roku wędruje do...

Ku pamięci na przyszłość:

[japhy@trinitrotoluen japhy]$ cd leeloo.moo.pl/
[japhy@trinitrotoluen leeloo.moo.pl]$ ls 
~japhy  ~zombiwock
[japhy@trinitrotoluen leeloo.moo.pl]$ rm -rf ~japhy/
rm: cannot remove directory `/home/users/japhy/': Permission denied
[japhy@trinitrotoluen leeloo.moo.pl]$ rm -rf \~japhy/
[japhy@trinitrotoluen leeloo.moo.pl]$ 

Kryzys? Jaki kryzys?

Brytyjski punkt widzenia na obecną sytuację finansową. But we are exaggerating, aren't we?

Bez dodatkowego komentarza.

Note to self: statyczny backup RESTowego serwisu WWW

Właśnie (jakoś od czternastej rano) przygotowuję raport na projekt zespołowy dla mojej kochanej uczelni. Od paru dni zastanawiałem się, jak do tego raportu dołączyć statyczną kopię Trac, którego używaliśmy do organizacji pracy. I nie żeby taka kopia to była moja nadgorliwość, prowadzący przedmiot sobie tego zażyczył.

Problem z tym jest podwójny. Po pierwsze, trac ma miłe RESTowe adresy nie kończące się na .html. Z tego powodu mirror strony ściągnięty bezpośrednio na dysk (wget -m adres) będzie później trudno otworzyć lokalnie. Z pomocą przychodzą dwie opcje wgeta:

-E
dodaje końcówkę .html do ściągniętych plików typu text/html, które tej końcówki nie mają w adresie
-k
Zamienia linki w ściągniętych plikach HTML tak, żeby lokalna kopia działała

Ale to tylko połowa problemów. Druga polega na tym, że oprócz ładnych RESTowych adresów strona rozgałęzia się w tysiące różnych zapytań GET, które zawierają różne warianty widoku. Jak zapuściłem ściąganie z tymi dwoma parametrami, po trzech godzinach działania i ponad 250 przeciągniętych megabajtach prawie samego tekstu dałem sobie spokój. Tylko jak powiedzieć wgetowi, żeby nie ściągał wszystkiego, co ma jakikolwiek znak zapytania?

Samemu wgetowi się nie da. Po prostu nie da. Tak czy inaczej będzie ściągał cały HTML, może go później skasuje (nie miałem na tyle cierpliwości, żeby sprawdzić). Odpada. Może z drugiej strony... ale nie tylko nie da się wgetowi podać lokalnego pliku robots.txt, ale też i w samym robots.txt nie da się zabronić dostępu do samych ścieżek z łańcuchem zapytania.

Nie byłoby jednak sensu pisać o tym publicznie, gdybym nie miał jakiejś formy rozwiązania. Do tego jest to rozwiązanie na tyle od dupy strony, że stwierdziłem, że warto je umieścić tutaj. Otóż, na serwerze, na którym działa ów trac, działa też mod_rewrite. Dopisałem szybko do .htaccess:

RewriteCond %{HTTP_USER_AGENT} ^Wget/ # Tylko dla naszego ściągania kopii, przeglądarki niech mają dostęp do wszystkiego
RewriteCond %{QUERY_STRING} !="" # Dla niepustego łańcucha zapytania
RewriteRule .* /drzewo [G] # Kierujemy na drzewo (G oznacza kod 410 Gone)

Wydaje się działać, co ku pamięci niniejszem odnotowuję.

Idealna licencja OSS

WTFPL. Open Source/Free Software w czystej postaci.

           DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
                   Version 2, December 2004 

Copyright© 2004 Sam Hocevar 
 14 rue de Plaisance, 75014 Paris, France 
Everyone is permitted to copy and distribute verbatim or modified 
copies of this license document, and changing it is allowed as long 
as the name is changed. 

           DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
  TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

 0. You just DO WHAT THE FUCK YOU WANT TO.

Aż mnie kusi, żeby napisać jakąś biblioteczkę, tylko po to, żeby była na powyższej licencji…

Nix – czysto funkcyjny menedżer pakietów

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.