💾 Archived View for rawtext.club › ~faildev_mode › gemlog › perfect-os-what.gmi captured on 2023-09-08 at 17:56:32. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-07-22)
-=-=-=-=-=-=-
2023-07-11
Microsoft Windows, GNU/Linux czy MacOS stanowią trójkę najbardziej rozpoznawalnych systemów operacyjnych. Należą do nich także mobilne systemy Android i iOS. Systemy operacyjne zasilają nasze urządzenia, pozwalają na instalację i uruchamianie aplikacji i pracę z nimi, i dostarczają im wszystko czego potrzebują. Kontrolują dostęp do zasobów: do sieci, plików, urządzeń zewnętrznych. Są realizacją idei jak powinny działać komputery i w jaki sposób użytkownicy z nich korzystają. Ponieważ realizują tak wiele skomplikowanych zadań, a także z uwagi na brak przenośności aplikacji pomiędzy platformami istnieje daleka droga od stworzenia pierwszego prototypu systemu operacyjnego do jego gotowości do użytku w codziennej pracy większości osób.
Istnieją także mniej znane, niszowe, wręcz eksperymentalne projekty systemów operacyjnych, starające się w oryginalny sposób rozwiązać problemy jakich jeszcze nikt nie zaadresował lub dostępne rozwiązania są niewystarczające. Jest to świat tym bardziej fascynujący, im bardziej jesteśmy świadomi zasad funkcjonowania popularnych systemów operacyjnych i owych problemów z jakimi się borykają. Przykładami takich projektów (mógłbym je wpisać do mojej listy projektów FLOSS) są:
Znajdujące się na pograniczu tych powszechnie znanych (w społeczności wolnego oprogramowania) a tych owianych tajemnicą. Oczywiście sam system jest otwarty i nie ma żadnych tajemnic. Korzysta z własnego jądra, ale zapewnia warstwę kompatybilności z Linuxem. Może to właśnie dlatego rzadko znajdujemy wersje popularnych programów dla FreeBSD. Jest to system skupiony na bezpieczeństwie. Podobno ma lepiej zorganizowane zarządzanie sieciami, a jądro kfreebsd zapewnia dodatkowe featury m.in. pozwalające na lepszą izolację programów.
Alternatywne jądro które pierwotnie miało zasilać system operacyjny GNU, zanim nie powstał Linux. Został stworzony zgodnie z designem mikrojądra, co okazało się trudne w realizacji, niemniej jednak projekt wciąż jest rozwijany i już dziś można uruchomić najnowszego Debiana albo GUIX z jądrem HURD zamiast Linuxa. HURD stosuje także rewolucyjne i elastyczne podejście jeśli chodzi o zarządzanie systemem plików: zamiast montowania, do obiektów systemu plików przypisuje się translatory (programy w przestrzeni użytkownika) decydujące o ich zachowaniu. Translator może nawet sprawić, że obiekt będzie się zachowywał jednocześnie jak katalog i plik!
„Prawdziwy” klon Windowsa, kompatybilny nie tylko wizualnie (wizualnie przypomina Windowsa XP), ale przede wszystkim binarnie. Ten projekt poprzez inżynierię wsteczną zastrzeżonego systemu operacyjnego Microsoftu odtwarza własne jądro NT działające z windowsowymi sterownikami. W dużej części wykorzystuje dorobek projektu Wine, który już wcześniej „przerobił” systemowe biblioteki i narzędzia pozwalając na emulację (he he) windowsowego środowiska na systemach unixowych. ReactOS jest we wczesnej fazie rozwoju i nadaje się tylko do eksperymentowania, jednak w przyszłości ma szansę stać się otwartoźródłowym zamiennikiem Windowsa, tak jak GNU był początkowo zamiennikiem własnościowego Unixa.
Jak sama nazwa wskazuje projekt akademicki. Ten system operacyjny, choć niekompatybilny ze standardem POSIX, eksploatuje filozofię "wszystko jest plikiem" do granic możliwości, udostępniając wszystkie systemowe zasoby jako wirtualne pliki. Ponadto, podobnie jak HURD, Plan 9 umożliwia zwykłym programom operowanie jako serwer plików. Design systemu jest mocno nastawiony na decentralizację. Importując odpowiednie pliki z innych maszyn, można np. odtwarzać na nich audio, wyświetlać grafikę, debugować procesy czy korzystać z ich sieci. System jest bardzo minimalistyczny, grafika mocno zintegrowana z systemem. Nie ma serwera X ani kompozytorów Wayland – każdy program może renderować we własnym oknie pisząc do jednego pliku. Elegancki i przemyślany design Plan 9 zainspirował wiele projektów wolnego oprogramowania, np. dodanie namespace-ów do Linuxa, na których opiera się bubblewrap i Flatpak.
Unixowy system operacyjny jeszcze starszy od GNU/Linuxa (wydany po raz pierwszy w 1987) przeznaczony do urządzeń wbudowanych i ogólnie miejsc z ograniczoną pamięcią czy mocą obliczeniową. Jest wykorzystywany jako podstawa do badań nad systemami operacyjnymi. Kompatybilny z POSIX z środowiskiem przypominającym NetBSD. Wciąż brakuje niektórych funkcji wymaganych do działania sprzętu i oprogramowania, np. obsługi USB. Wykorzystuje mikrojądro ze sterownikami działającymi jako chronione procesy w przestrzeni użytkownika, które automatycznie się restartują w przypadku wystąpienia awarii.
Kolejny system operacyjny z mikrojądrem, będący połączeniem pomysłów z Plan 9, Minixa, *BSD i GNU/Linuxa. Najważniejszą cechą tego systemu jest to, że został napisany w języku Rust gwarantującym bezpieczeństwo pamięci (pewne części jądra z konieczności korzystają z *unsafe*, a każdy taki przypadek jest poddawany audytowi bezpieczeństwa). Dzięki modularności prawie żadna zmiana nie wymaga ponownego uruchomienia. Redox jest kompatybilny źródłowo z większością unixowych programów, jednakże wymaga ponownej kompilacji. Nie jest też jeszcze dostępna obsługa X11/Wayland, ponieważ Redox posiada własny podsystem graficzny (warstwa kompatybilności może zostać dodana w przyszłości), tylko jedno środowisko graficzne – orbital, zatem aplikacje graficzne aby zadziałały muszą zostać przeportowane. Redox odchodzi też od tradycyjnego modelu bezpieczeństwa na rzecz uprawnień (capabilities) i namespace-ów. Filozofia "wszystko jest plikiem" została zastąpiona "wszystko jest adresem URL", tak więc mimo kompatybilności ten system znacznie się różni od pozostałych.
Drobna uwaga: poza ReactOS nie uruchamiałem żadnego z wyżej wymienionych systemów/kerneli, moje opisy wzięły się z pobieżnego przejrzenia oficjalnych stron projektów i mogą być częściowo nieprawdziwe. W razie odkrycia nieprawidłowości wprowadzę odpowiednie poprawki.
A tak poza tym to był tylko wstęp. W tym wpisie mam bowiem zamiar jako laik (chyba mogę się tak nazwać?) podzielić się własną wizją nieidealnego systemu operacyjnego oraz subiektywnymi przemyśleniami na ich temat. Nie będzie to kompletny plan projektu, raczej lista cech jakie mógłby posiadać kolejny ciekawy projekt. Możecie to potraktować jako kontynuację denerwujących rzeczy w Androidzie z punktu widzenia power usera, będzie ich bowiem sporo, zważywszy że jest to jeden z najlepiej poznanych przeze mnie ekosystemów.
Po pierwsze, istotnym problemem dzisiejszych systemów operacyjnych są zbyt duże uprawnienia aplikacji i dane do jakich mają dostęp, które mogą wykorzystywać np. do fingerprintingu. Nawet w systemie Android aplikacje bez żadnych uprawnień mogą całkiem sporo dowiedzieć się o naszym urządzeniu i systemie – m.in:
Nawet jeżeli pewna funkcja wymaga posiadania uprawnienia (np. android.permission.QUERY_ALL_PACKAGES), nie jest to w żaden sposób widoczne dla użytkownika. Podobnie dzieje się ze stronami internetowymi – osadzony na stronie kod JavaScript może pytać przeglądarkę o co chce, i rzadko otrzyma odpowiedź odmowną. A potem może to wysłać AJAX-em i przyczepić użytkownikowi ogon w postaci fingeprintu przeglądarki. Nie są do tego wymagane żadne ciasteczka. Strona może zobaczyć „o, ktoś tu używa Firefoxa, a to strona tylko dla chromiarzy” i bam!
Ta strona nie jest obsługiwana przez twoją przeglądarkę. Polecamy szybką i bezpieczną przeglądarkę Google Chrome.
Mimo, że to tylko dyskryminacja przeglądarek – w Firefoxie strona otwierałaby się równie dobrze, no może z wyjątkiem skryptów śledzących (otwiera się gdy oszukasz stronę że jesteś Chromem).
WYŁĄCZ TEGO ADBLOCKAAAAA!!!!!
Warto zauważyć, że choć jest to zjawisko powszechne, to w teorii informacji algorytmy nie wiedzą nic o otaczającym ich świecie. Informacje do aplikacji są dostarczane przez interfejsy systemu operacyjnego. W dzisiejszym świecie potrzebujemy więcej prywatności, a to oznacza pełną kontrolę użytkownika nad danymi - wszystkimi, nie tylko tymi uważanymi za wrażliwe. Natomiast kontrola użytkownika nad oprogramowaniem odbywa się poprzez oprogramowanie kontrolujące oprogramowanie. Innymi słowy, oprogramowanie pośredniczy w sprawowaniu kontroli użytkownika nad oprogramowaniem.
Wyobrażam sobie taki model bezpieczeństwa, w którym proces nie dostaje z automatu nic, żadnych globalnych identyfikatorów, żadnych informacji o sprzęcie, nawet bieżącego czasu, natomiast o dostępie do zasobów decyduje proces kontrolujący – może to być skrypt napisany przez użytkownika, powłoka lub część środowiska graficznego.
Po drugie, użytkownik jest w centrum i to on decyduje o całym przebiegu. Może on bez uprawnień administratora manipulować systemem plików jaki widzą aplikacje i dzięki temu na przykład przechowywać dane na nośniku zewnętrznym, w chmurze, wymusić ich zaszyfrowanie, wykonywać migawki i co tylko przyjdzie mu do głowy, a aplikacja nie jest tego świadoma dopóki proces kontrolujący jej o tym nie powie. Brak możliwości wpływania na system plików przez użytkownika to słabość wielu współczesnych systemów operacyjnych. Nie stanowi co prawda zagrożenia dla bezpieczeństwa, jednak przez brak odpowiednich narzędzi odpowiedzialność za wybór miejsca i sposobu przechowywania danych spada na twórców aplikacji. Weźmy na przykład Joplin – notatnik synchronizujący się z chmurą z opcją szyfrowania notatek end-to-end (którego używam właśnie w tej chwili) – funkcja szyfrowania i synchronizacji została wbudowana w aplikację. Nie musiałaby, gdyby użytkownik mógł w łatwy sposób „zakrzywić czasoprzestrzeń” systemu plików przed uruchomieniem, może nawet w jakimś nieskomplikowanym interfejsie graficznym. Już dziś systemy unixowe dają nam do dyspozycji dowiązania symboliczne, ale to trochę za mało. A nie każdy ma przywilej bycia administratorem systemu na którym pracuje.
Pomysł z pozwoleniem dowolnemu użytkownikowi na dokonywanie operacji montowania może wydawać się kontrowersyjny, zwłaszcza gdy jedna maszyna jest dzielona przez wielu użytkowników. Potrzebne są dodatkowe zabezpieczenia separujące użytkowników od siebie nawzajem. W GNU HURD każdy użytkownik żyje we własnym namespace, ma własny widok systemu plików, a zmiany które wprowadzi nie wpływają na innych. Plan 9 umieszcza każdy proces w oddzielnym namespace montowania. W GNU/Linuxie możemy skorzystać z narzędzia bubblewrap, na którym, śmiem twierdzić, dałoby się zbudować [eko]system podobny do tego, który właśnie opisuję, choć pewnych ograniczeń nie da się przeskoczyć. Oczywiście mówiąc o bezpieczeństwie nie możemy nie wspomnieć o tym, że nieuprzywilejowany użytkownik nie powinien móc montować zasobów do których nie ma praw dostępu – np. /dev/sdb1 należący do root:root.
To samo można by odnieść do innych zasobów niż pliki (które jednakże mogłyby być udostępniane jako pliki zgodnie z filozofią „wszystko jest plikiem”). Na przykład proces nadrzędny udostępniając obraz kamery może go w locie modyfikować, np. automatycznie wykryć i zamazać twarze, wyciąć tło, nałożyć filtry, przekierować obraz z innego urządzenia czy zamrozić strumień. A może strumień audio... również można wyciszyć, poprawić spektrum, wyciąć szumy i robić dowolne inne rzeczy. W systemach takich jak Android użytkownik może jedynie zdecydować **czy** przydzielić aplikacji dostęp, ale potem nie ma już wpływu na to co dokładnie otrzyma aplikacja. „Czy chcesz aby aplikacja X miała dostęp do kalendarza”? A może lepiej „wybierz kalendarze do których aplikacja X może mieć dostęp” z przełącznikami odczyt/odczyt i zapis oraz opcją „utwórz nowy pusty kalendarz” – specjalnie dla tej jednej aplikacji. A aplikacja nie może mieć pretensji że w otrzymanym kalendarzu nic nie ma. Może użytkownik nie używa kalendarza, a może umyślnie nie dał dostępu do swojego kalendarza. Aplikacja nie będzie tego wiedzieć. Taki przykład.
To nie tylko zwiększenie kontroli użytkownika, to także ekstremalna elastyczność i uproszczenie kodu aplikacji, które nie muszą już oddzielnie obsługiwać „tego wszystkiego” i skupić się tylko na jednym. To moja własna interpretacja filozofii Unixa: „program ma robić jedną rzecz i robić ją dobrze”. Synchronizację zostaw innym. Szyfrowanie end-to-end jest fajne, ale od tego są inne programy. Ty masz dobrze organizować, edytować i wyświetlać notatki. Użytkownik może łatwo zastępować jedne komponenty drugimi, a nawet pisać własne jeżeli ma czas i umiejętności. A na pewno nie musiałby narzekać: „fajna ta aplikacja, tylko szkoda że nie ma szyfrowania”.
Przez „użytkownik jest w centrum” rozumiem też, że absolutnie niedopuszczalna jest sytuacja, w której jakiś proces może więcej niż użytkownik – np. przechowywać dane w miejscu niedostępnym dla użytkownika.
Po trzecie, aplikacje powinny mieć możliwość udostępnienia własnych zasobów, także (a może przede wszystkim) przy pomocy wirtualnego systemu plików, do którego użytkownik daje dostęp jak chce. Zgodnie z ostatnim akapitem, aplikacja udostępniająca nie ma prawa wiedzieć jaki program uzyskuje dostęp do jej zasobów, ani co z nimi dalej robi (nie chcemy przecież DRM-a!)
Jak takie udostępnianie zasobów mogłoby się hipotetycznie odbywać? Skoro przydzielanie dostępu do zasobów szło w dół – do procesów potomnych, to udostępnianie zasobów prawopodobnie będzie szło w odwrotnym kierunku – w górę, do procesów nadrzędnych. Proces nadrzędny otrzymuje sygnał, że jeden z jego potomków coś udostępnił. Pytanie czy taki sygnał powinien otrzymywać jedynie bezpośredni rodzic, czy wszystkie procesy nadrzędne. Czy taka informacja powinna dojść aż do procesu najwyższego poziomu? A może będzie to zbyt duże obciążenie dla systemu? Przyznam, że nie znam się na projektowaniu systemów operacyjnych, ja tylko puszczam wodze fantazji, a ten szczegół jest jak dla mnie mało istotny. Ja tylko chcę jako użytkownik posiadać pełną kontrolę nad uruchamianymi przeze mnie programami. Wydaje mi się, że sygnał powinien wędrować aż do samej góry, a jeśli chodzi o optymalizację, tylko programy które „zasubskrybowały się” do danego sygnału przypisując mu jakiś trigger – reszta wykona domyślną akcję, czyli – nic z tym sygnałem nie zrobi. Nie może też go w żaden sposób zatrzymać, ponieważ równie dobrze mogłaby to zrobić sama aplikacja, która się wewnątrz „rozdwoiła”.
Dzięki wirtualnym systemom plików udostępnianym przez nieuprzywilejowane procesy, moglibyśmy np. przeglądać pliki z chmury w naszym menedżerze plików, oglądać filmy z Internetu lub słuchać muzyki w dowolnym odtwarzaczu, mieć wirtualne kamery, mikrofony, wyświetlacze, sieci... w zasadzie Plan 9 na sterydach lub też z większym zasobem aplikacji.
Ten feature jest dopełnieniem poprzedniego. Oba wzajemnie się uzupełniają i pozwalają stworzyć... system operacyjny bez roota? Czy to w ogóle jest możliwe? Miałem jakiś czas temu taki pomysł, aby zmodyfikować trochę tradycyjny model w którym konta użytkowników są równe, a root jest... równiejszy. Pomysł polegał na tym, aby użytkownicy mogli tworzyć innych użytkowników i mieć nad nimi kontrolę (jakkolwiek to brzmi). Użytkownicy byliby ułożeni w hierarchiczną drzewiastą strukturę w której każdy użytkownik jest rootem dla użytkowników podrzędnych. To umożliwiłoby użytkownikom podzielenie swoich plików na różne domeny bezpieczeństwa. Oczywiście zmiana aby była sensowna musiałaby także pociągnąć za sobą zmiany w grupach i dokładne przemyślenie wszystkiego, dokonanie audytów bezpieczeństwa, etc. Ostatecznie pomysł ten przerodził się w projekt „midsu” (middle-superuser) nad którym pracuję. Nie daje on co prawda takiej mocy, ale dzięki mocy administratora można utworzyć drugiego użytkownika, powiązać go z pierwszym, przydzielić do jednej grupy, a następnie dzięki mocy bubblewrap tworzyć kontenery z sekretną pamięcią. Z woli użytkownika nic poza Firefoxem nie dostanie się do ~/.mozilla.
Po czwarte... integracja z innymi systemami operacyjnymi. Tak, żeby nie trzeba było ustawiać maszyn wirtualnych. Chciałbym móc uruchomić swój system operacyjny jako aplikację, która zintegruje się z np. GNU/Linuxem i będzie wyświetlać natywne okna, przydzielać dostęp do plików hosta i innych zasobów. System ma być skonstruowany w taki sposób, aby programy nie wiedziały czy pracują na systemie bare-metal czy a'la WSA. Ponieważ nie zawsze mam dostęp do bare-metal, a fajnie by było zabrać swoje środowisko ze sobą i wszystkie programy. Nawet na Androida czy iOS.
Po piąte... porozmawiajmy o dystrybucji oprogramowania. Pewne programy nie będą zaufane ani otwartoźródłowe i choć nie mam zamiaru używać żadnego z nich, system powinien być przystosowany do uruchamiania niezaufanego oprogramowania w bezpieczny sposób. Nie oznacza to kompletnego lockdownu jak w Androidzie czy iOS, to użytkownik decyduje jakie dokładnie dane otrzyma program, zatem to od niego zależy jak bezpieczne lub niebezpieczne będą jego dane. W jego imieniu program nadrzędny (np. launcher aplikacji) przygotuje środowisko i przypnie zasoby, które użytkownik chce udostępnić aplikacji. Z kolei aplikacja może udostępnić własne zasoby z powrotem do launchera, który może je udostępnić dalej (działając w założeniu wedle preferencji użytkownika).
Niektóre programy zostały napisane w językach kompilowanych, co ma duże znaczenie dla wydajności. Zakładając, że kod źródłowy jest dostępny na wolnej licencji (lub użytkownik ma ekskluzywne prawo dostępu do kodu źródłowego), proces budowania programu powinien być:
Kompilacja musi odbywać się w izolacji, musi skutkować identycznymi danymi wyjściowymi, a warunkiem tego są identyczne dane wejściowe i brak losowości (jak zablokowany /dev/random i /dev/urandom). Dwa pierwsze cele zostały już osiągnięte w świecie FLOSS m.in. przez projekty F-Droid, dystrybucję GUIX i Nix od której się wywodzi. Reprodukowalne buildy są ważnym elementem budowania zaufania, np. używanie komunikatorów wykorzystujących szyfrowanie end-to-end ale bez weryfikowalnych buildów niesie ze sobą przekazania treści zaszyfrowanych wiadomości przez niezaufanego klienta, który w oficjalnym kodzie zawiera coś jeszcze. Jest to szczególnie niebezpieczne przy automatycznych aktualizacjach kontrolowanych przez upstreamowego developera, który może mieć pokusę do dodania backdoorów.
Ostatni punkt – możliwie bezbolesna kompilacja – wymagałby moim zdaniem radykalnych zmian. Obecnie mamy taką sytuację, że oprogramowanie kompiluje się długo, nie ma żadnego paska postępu, w połowie dostajemy po głowie błędem że brakuje zależności i musimy zaczynać od nowa. Niewesoła sytuacja. Niestety kod źródłowy często jest zależny od systemów budowania, dodatkowych skryptów, narzędzi, konfiguracji i nie jest tylko statycznym procesem konwersji postaci źródłowej do postaci binarnej. Należałoby to jakoś ujednolicić, uniezależnić kod źródłowy od systemów budowania i wynaleźć jeden, który poradzi sobie ze wszystkimi językami programowania, będzie wiedział ile zostało do końca, jakie są zależności, do tego ujednolicić konfiguracje aby można było je zautomatyzować. Zmiana niewątpliwie wymagająca albo kooperacji z programistami, albo mozolnego przepakowywania projektów, albo dziwnych hacków, które czasami będą działać a czasami będziemy mieli progres nieokreślony.
Bezbolesna kompilacja to też możliwość pobrania kodu źródłowego i przekompilowania tylko tego fragmentu programu, który uległ zmianie. Choć nie znam zbyt dobrze C++, wiem że wiele plików źródłowych często jest łączonych w jedną binarkę, ale po drodze znajdują się pliki obiektowe, z których każdy odpowiada pewnemu plikowi źródłowemu, a które są dopiero później łączone w plik wykonywalny. Zauważyłem też, że proces kompilacji (konwersji źródła do plików obiektowych) trwa zauważalnie dłużej niż linkowanie, które trwa zaledwie kilka sekund. Jeżeli modyfikowanie oprogramowania miałoby być „user-friendly” – niestety rzadko się o tym myśli, zdecydowanie za rzadko – budowanie musi trwać tak krótko jak to możliwe. Użytkownik końcowy przegląda kod źródłowy online, modyfikuje jeden plik który mu się nie podoba, wciska duży zielony przycisk „kompiluj” i tu zaczyna się magia. Chwilę tylko pobierają się zależności budowania, następnie kompiluje się tylko ten jeden plik z tą samą konfiguracją co obecnie zainstalowana wersja, produkując jeden plik obiektowy, który jest linkowany z innymi plikami obiektowymi już skompilowanymi, dzięki czemu trwa to parę sekund zamiast – niekiedy – paru godzin. Użytkownik uruchamia zmodyfikowaną aplikację i voilla! Ma co chce, w możliwie najmniej bezbolesny sposób. Możliwe, że dałoby się nawet wyciągnąć oryginalne pliki obiektowe z binarki, ale aż tak daleko moja wiedza nie sięga.
Bo to nie jest tak, że żaden zwykły użytkownik nie poradzi sobie ze zrozumieniem kodu źródłowego, a jeżeli sobie poradzi, to na pewno poradzi sobie też z kompilacją. W przypadku Androida (podobno taki user-friendly) mam ogromne problemy z ogarnięciem Gradle i tego całego syfu który zostawia na moim komputerze. Nigdy nie udało mi się zbudować niczego z jego użyciem, a próbowałem wiele razy. Nawet najmniejszej, najprostszej apki. Oto jak wygląda user-friendliness wg wujka na literę G. To nie zrozumienie kodu źródłowego było dla mnie trudne, ale użeranie się z systemem budowania. Idealny system koniecznie musi zaadresować ten problem i umożliwić modyfikowanie aplikacji zwykłym, nietechnicznym użytkownikom (i użytkownikom z ograniczonymi pokładami cierpliwości).
Po szóste – porozmawiajmy o **dystrybucji** oprogramowania (tak, wiem, to temat polityczny). W jaki sposób pakiety i ich zależności są dostarczane? I te binarne i źródłowe? Jakikolwiek by menedżer pakietów nie był, musi posiadać następujące cechy:
I tutaj wkraczamy na ciężki grunt decentralizacji Internetu. Krótko mówiąc, niełatwo zrobić to dobrze. Co zrobić z tym ogromem danych rozsianych po nodach? Kto ma zamiar je utrzymywać i jak długo? Bo jeśli usuniemy mało popularny pakiet w celu zaoszczędzenia miejsca, ryzykujemy uszkodzeniem zależności dla jakiegoś innego pakietu. Na przykład brak jakiejś niszowej biblioteki (której programiści przecież mają prawo używać) uniemożliwi zbudowanie lub uruchomienie aplikacji która jej używa. Mirrory się nie skalują i gdy np. taki GNU/Linux zdobędzie szersze grono użytkowników (niewykluczone), trzeba będzie w jakiś sposób rozwiązać problem dystrybucji oprogramowania, najlepiej bez polegania na wielkich graczach.
Można też nieco inaczej: pakować wszystkie zależności razem tak jak to robi AppImage, Snap czy Flatpak, ale dokonywać deduplikacji już po zainstalowaniu. To rozwiązanie dobre do dystrybucji pakietów offline, np. na płycie. Przy podejściu mirrorowym, zależności trafią do tego samego repozytorium, ale te muszą być podpisane cyfrowo przez oryginalnych developerów.
Całkowite rozproszenie wymaga niestety wyboru konkretnej sieci. I tak, na pewno nie chcemy niczego związanego z blockchainem i crypto (ale darowizny mogą być w crypto). W całkowitej dystrybucji w istocie będzie to taki wielki „worek na pakiety”, a na potrzeby wyszukiwania i łatwej identyfikacji istniałyby metarepozytoria spinające zaufane pakiety razem, na przykład utrzymywane przez opiekunów dystrybucji, aby trzymać pakiety o wątpliwej reputacji z dala. Mógłby to być zwykły plik tekstowy z podpisem cyfrowym hostowany na zwykłym serwerze, pobierany przez menedżer pakietów i trzymany w pamięci. Plik ten zawierałby metadane dotyczące nazw, identyfikatorów, wersji, zależności, sygnatur, opisów, screenshotów, tagów, projektów-matek, zawartości, zajmowanego miejsca i czego tam jeszcze trzeba. Upstreamowi developerzy również posiadaliby takie metarepozytoria. Jeżeli ufasz autorowi – dodajesz go do listy źródeł.
Kolejna kwestia – jak identyfikujemy pakiety? Aby zminimalizować ryzyko konfliktu nazw, można skorzystać ze standardu odwróconej domeny, z którego korzysta m.in. Android i Flatpak. Jednak aby unikalność **zagwarantować**, a także by umożliwić pracę w rozproszonej sieci, potrzebne są unikalne identyfikatory wygenerowane na podstawie sumy kontrolnej wyciągniętej z zawartości (jak torrenty). Ostateczny ciąg jednoznacznie identyfikujący konkretną wersję pakietu musi się składać z hasha oraz opcjonalnie nazwy i wersji (tylko dla zwiększenia czytelności). Z czymś takim zetknąłem się w GUIX-ie. Nie będzie to ten sam identyfikator co identyfikator pliku w sieci rozproszonej, ponieważ różne sieci rozproszone stosują różne identyfikatory. Ten adres będzie w metarepozytorium. Choć preferowane jest użycie jednej sieci, warto trzymać się myśli, że kiedyś może ona ulec zmianie i być na to choć częściowo przygotowanym. Plusem jest też możliwość hostowania takiego repozytorium w clearnecie. Oryginalny identyfikator pakietu zostanie wykorzystany przy weryfikacji czy aby na pewno zostało pobrane to, co chcieliśmy.
Czy to już koniec? Na razie tak. To była taka moja lista życzeń. Podzieliłem się z wami moimi – być może oderwanymi od rzeczywistości – przemyśleniami na temat tego, jak mogłyby funkcjonować systemy operacyjne. Czy przyjdzie taki dzień, że będziemy mieli jeden system operacyjny ogólnego przeznaczenia na każdym z naszych urządzeń? Czy będzie to GNU/Linux? A może rzeczywistość nas zaskoczy, nastąpi niespodziewany zwrot akcji i coś innego zmiecie Androida i iOS-a z rynku?
Przedstawiłem wam także parę interesujących projektów systemów operacyjnych, wszystkie FLOSS, ale większość to oprogramowanie alpha stage, ciekawostka. Uważam, że przedstawiają bardzo oryginalne, nowatorskie i kreatywne podejście do spraw życia codziennego jakim stały się cyfrowe technologie i inne dojrzalsze projekty mogą czerpać garściami z ich pomysłów. Dzięki wolnemu oprogramowaniu – wolnemu od restrykcji, patentów i umów licencyjnych EULA – technologia może się swobodnie rozwijać bez ograniczeń i wszyscy na tym korzystamy. Warto wiedzieć o istnieniu tego drugiego świata, o tych niesamowitych projektach.
Który z tych projektów jest najlepszy? Który ma największe szanse powodzenia? Cóż... ja osobiście kibicuję wszystkim, polecam postawić sobie maszynę wirtualną dla zabawy, a na dzień dzisiejszy właściwie tylko GNU/Linux i może *BSD są jedynymi systemami operacyjnymi które zwykły użytkownik może używać z zachowaniem prywatności i wolności cyfrowej.
A jaki byłby wasz idealny system operacyjny? Jakie problemy by rozwiązywał? W jaki sposób? Zachęcam do podzielenia się swoimi pomysłami na fediversum.