Debian: jak zrobić własny pakiet

ByTomasz Sanecki

Debian: jak zrobić własny pakiet

Debian posiada bardzo rozbudowany system robienia pakietów.

Na szczęście samo tworzenie prostych paczek (bez rzeczy wymaganych żeby paczka była zaakceptowana do “oficjalnego” repo Debiana/Ubuntu) jest dosyć proste.

By uprościć i maksymalnie zautomatyzować proces budowania/aktualizowania pakietów, debian dostarcza szereg narzędzi.

W przypadku modułów DKMS ogromne znaczenie ma nazwa samego modułu.

Jako, że budujemy moduł DKMS, to określamy --with dkms .

Struktura pakietu Debian

Co właściwie budujemy i dlaczego

W pracy admina po jakimś czasie chyba każdy zbiera sobie kolekcję skryptów i programów które używa do debugowania błędów, czy do automatyzacji czynności.

Od tooli typu nmap, socat czy tcpdump które są niesamowicie użyteczne ale nie są instalowane w domyślnej instalacji, po własne skrypty automatyzujące niektóre czynności, czy służące np.

Rozwiązanie jest proste, albo trzymać wszystkie skrypty na NFSie ( ale to raczej obejście problemu ), albo zapaczkować je i dodać repo z paczkami do /etc/apt/sources.list.

Wszystkie paczki .deb, które wpadły nam w łapy, mamy już zassane, zainstalowane i włączone do naszego repozytorium.

Pozostaje jeszcze przygotować pliki .deb tzn dokonać procesu spakowania istniejących pakietów do plików .deb i wrzucenie tych plików do folderu /var/repo.

Na szczęście samo tworzenie prostych paczek (bez rzeczy wymaganych żeby paczka była zaakceptowana do “oficjalnego” repo Debiana/Ubuntu) jest dosyć proste.

Źródła pakietu i debianizacja

Każdy moduł kernela ma swoje źródła, które musimy sobie pierw pozyskać.

Mając źródła, trzeba je zdebianizować.

Przy pomocy override_dh_install: przepisujemy domyślny target instalacji plików.

W katalogu /usr/share/doc/pbuilder/examples/ jest również szereg skryptów, z których pbuilder może skorzystać podczas operacji budowania pakietu.

Powinniśmy mieć już dostępny katalog debian/ .

To polecenie stworzyło nam katalog debian/ .

Wszystkie zewnętrzne repozytoria będą wymagać publicznych kluczy GPG.

Zwykle będziemy przechodzić przez następujące kroki:

  • pobrać źródła
  • zdebianizować katalog
  • uzupełnić pliki w debian/
  • zbudować pakiet
  • sprawdzić wynik i podpisać artefakty

Narzędzia potrzebne do pracy

By móc zacząć budować pakiety z prawdziwego zdarzenia niczym debianowy maintainer, musimy doinstalować szereg pakietów.

- devscripts -- ten pakiet zawiera szereg skryptów ułatwiających zarządzanie plikami w katalogu debian/ , więcej info o tym jakie skrypty ten pakiet zawiera (oraz ich zależności) można odczytać z opisu samego pakietu, np. - dh-* -- różne moduły dla debhelpera, potrzebne podczas budowania pewnych pakietów, np.

Jak widać jest tego dość sporo, no i oczywiście będzie tego więcej gdy każdy z powyższych pakietów dociągnie swoje zależności.

Powyższe pakiety są (za wyjątkiem pewnych dodatków) jedynymi pakietami, które będziemy instalować w swoim systemie głównym.

Wszelkie zależności budowanych pakietów będą już pakowane do środowiska chroot, które zostanie zbudowane przez pbuilder.

Przykładowy plik konfiguracyjny dla pbuildera znajduje się w /usr/share/doc/pbuilder/examples/pbuilderrc -- trzeba go skopiować do katalogu /etc/ i odpowiednio przerobić.

Dostęp do narzędzia pbuilder jest standardowo zarezerwowany jedynie dla użytkownika root.

To zbytnio wygodne i przydałoby się umożliwić korzystanie z niego zwykłemu użytkownikowi.

Przydałoby się umożliwić korzystanie z niego zwykłemu użytkownikowi.

Wszystkie zewnętrzne repozytoria będą wymagać publicznych kluczy gpg -- trzeba je również dostarczyć pbuilderowi.

Najważniejsze narzędzia

Narzędzie Zastosowanie
devscripts skrypty pomocne przy pracy z katalogiem debian/
debhelper szkielet i makra budowania pakietów
pbuilder budowanie w czystym środowisku chroot
lintian kontrola jakości i wykrywanie błędów pakietu
apt-file wyszukiwanie, który pakiet dostarcza plik

Budowanie w chroot i kontrola zależności

Pbuilder musi na czymś operować, inaczej odmówi współpracy.

Musimy mu stworzyć podstawowe środowisko pracy -- chodzi o zrobienia minimalnego i do tego spakowanego chroota, który będzie używany w każdym procesie budowania pakietów.

Takie minimalistyczne środowisko ma na celu zapewnienie, że pakiet będzie się budował poprawnie na 99% maszyn, pod warunkiem, że się zbuduje bez problemu w tym chroocie.

Każdy system, nawet ten minimalny chroot zrobiony przy pomocy debootstrapa, wymaga by go aktualizować w miarę regularnie, a konkretnie, przed budowaniem pakietu.

W EXTRAPACKAGES umieściłem kilka dodatkowych pakietów, które będą instalowane po wypakowaniu środowiska chroot, a to ze względu na szereg ostrzeżeń jakie wyrzucał mi pbuilder podczas budowania pakietów.

By przyśpieszyć budowanie pakietów, pbuilder wykorzystuje ccache.

Tylko jest jeden problem -- ten ccache zadziała jedynie przy wywoływaniu polecenia pbuilder --build .

Jeśli z jakiegoś powodu nam paczka się nie zbuduje i będziemy chcieli sprawdzić co się schrzaniło i zostaniemy zrzuceni do środowiska wewnątrz chroot, to po tym jak poprawimy błąd i będziemy próbować budować pakiet via dpkg-buildpackage , nie będziemy mieli dostępu do ccache i pakiet się będzie budował tak jakbyśmy nie korzystali z ccache.

Pbuilder standardowo możemy używać tylko jako root.

Przydałoby się umożliwić korzystanie z niego zwykłemu użytkownikowi.

Od tooli typu nmap, socat czy tcpdump które są niesamowicie użyteczne ale nie są instalowane w domyślnej instalacji, po własne skrypty automatyzujące niektóre czynności, czy służące np.

W przypadku build-Depends trzeba pamiętać, że jeśli jakaś zależność nie zostanie spełniona, pbuilder nawet nie podejmie się próby stworzenia takiego pakietu.

Nie zawsze też pakiet zbuduje się nam poprawnie w przypadku gdy wszystkie zależności zostaną zaspokojone.

Wtedy będzie trzeba poszukać tych brakujących pakietów, których zapomnieliśmy dodać lub zwyczajnie je przeoczyliśmy i dlatego wymagane jest budowanie paczek w minimalnym środowisku chroot.

Podstawy chroot-a - TORGiren DevOpses #30

Jak wygląda katalog debian

Mamy tu katalog DEBIAN gdzie mamy pliki informacyjne paczki oraz skrypty uruchamiane przed/po instalacji/deinstalacji paczki, a pozostałe katalogi to są rzeczy która nasza paczka zainstaluje na dysku (i usunie przy instalacji).

W katalogu debian/ zawsze będziemy tworzyć po wypakowaniu źródeł i to w nim będziemy dokonywać większości zmian, dlatego też musimy poznać nieco jego strukturę.

W zależności od tego jaki pakiet będziemy budować, możemy skorzystać ze wzorców plików -- inaczej wyglądają one w przypadku bibliotek, a inaczej w przypadku modułów kernela, etc.

W tym przypadku budujemy pojedynczą binarkę i dlatego skorzystaliśmy z opcji -s.

Opcja -c gpl2 odpowiada za uzupełnienie pliku copyright (o nim później) o odpowiedni tekst licencji.

Ostatnia opcja -f odpowiada za podanie pliku z upstreamowymi źródłami.

Jak widać, został utworzonych szereg plików ale nie wszystkie z nich zawsze będą nam potrzebne.

Dobrze jest też wiedzieć, że w przypadku gdy skasujemy, naszym zdaniem, niepotrzebne pliki, możemy nakazać dh_make aby przywrócił ich szablony.

Control, zależności i opis

Jednym z ważniejszych plików jest debian/control .

To w nim są definiowane min. zależności potrzebne do zbudowania/instalacji pakietu i to w oparciu o te zależności właśnie menadżery pakietów, takie jak apt-get czy aptitude, będą wiedzieć jak zainstalować konkretny pakiet.

Trochę tego jest -- jedziemy zatem od góry.

Dalej mamy Section i odpowiada to za przypisanie pakietu do konkretnej sekcji, a tych jest dość sporo.

Kolejna linijka to Priority i określa ona jak ważna jest paczka z punktu widzenia prawidłowego działania systemu i z reguły tutaj będziemy wpisywać optional albo extra .

Kolejna pozycja to Build-Depends i jest to nic innego jak zależności, które muszą zostać spełnione aby podjąć próbę budowania pakietu.

Następnie mamy Standards-Version i jest to wersja standardu polityki debiana jaka ma być spełniona aby zbudować tę paczkę i zawsze trzeba ustawiać tutaj najnowszą wersję, obecnie jest to 3.9.6 .

Opcje Homepage , Vcs-Git oraz Vcs-Browser określają położenie projektu w sieci i czy korzysta z jakiegoś systemu kontroli wersji (VCS).

Kolejna linijka to Architecture i tu możemy wpisać all albo any .

Różnica między tymi dwoma tkwi w rodzaju budowanych plików.

Następne linijki to Depends Suggests Recommends Conflicts , Breaks , Provides i Replaces i są to zależności, które muszą być spełnione przy instalacji pakietu.

Nie wszystkie z wyżej wymienionych opcji będziemy zawsze używać.

Zwykle ograniczymy się do pierwszych trzech.

Różnice między nimi są następujące -- jeśli pakiet wymaga do działania innego pakietu, dajemy go w Depends, jeśli nasz pakiet może się obyć bez innego pakietu ale traci na tym trochę ze swojej funkcjonalności, to dajemy tamten pakiet w Recommends .

Jeśli jakiś pakiet przydaje się ale można bez niego żyć, to dopisujemy go do Suggests .

Każde z tych pól może zawierać określoną wersję danego pakietu.

I ostatnia pozycja w tym pliku to Description , czyli opis pakietu.

Opis pakietu i wersje zależności

Opis pakietu jest krótki i nie powinien przekraczać 65 znaków -- więcej zostanie obciętych.

Każda nowa linia musi być wcięta.

Jeśli chcemy dodać nowy paragraf, to dajemy kropkę (również wciętą) i dalej nowy paragraf.

W opisie można też robić listy.

Każde z tych pól może zawierać określoną wersję danego pakietu.

Do definiowania zależności wersyjnych służą operatory: << , <= , = , >= oraz >> .

Jeśli wersja ma być mniejsza niż, to używamy << .

Jeśli wersja ma być mniejsza lub równa, to wtedy używamy <= .

Jeśli wersja ma być równa to używamy = .

Jeśli wersja ma być większa lub równa to używamy >= .

Jeśli wersja ma być większa, to używamy >> .

Budowanie pakietu

I teraz część najważniejsza, mianowicie budowanie paczek.

Budowanie pakietu odbywa się w etapach.

Każdy z etapów wywołuje określone narzędzie, które ma na celu coś zrobić.

Dobrze jest wyeksportować te dwie dodatkowe zmienne DH_VERBOSE oraz DH_OPTIONS .

Wszystkie z nich są puste i nadpisują odpowiadające im targety.

Przy pomocy override_dh_install: przepisujemy domyślny target instalacji plików.

To nam nie wystarcza, chcemy przecież repo dla naszych serwerów, idealnie z paczkami w gicie, podzielone na część “stabilną” i “dev”.

Przechodzimy do katalogu nadrzędnego cd ..

Na koniec musimy jeszcze zmienić format źródeł z 3.0 (native) na 3.0 (quilt) .

Wtedy zostanie utworzony plik nazwapaczki_wersja.orig.tar.xz .

Można pójść nawet na skróty i skorzystać z dpkg-buildpackage -b -us -uc .

Proces budowy modułu się zakończył, podobnie jak i proces instalacji pakietu.

Informacja na końcu, tj. .deb z modułem kernela zakończył się powodzeniem.

Jak aktualizować źródła i paczki

W przypadku pakietów z repozytorium Debian można pobrać stare źródła przy pomocy apt-get source minitube .

Następnie kopiujemy katalog debian/ do katalogu minitube/ i przechodzimy do tego katalogu.

Przy aktualizacji paczki, dobrze jest też uzupełnić wpisy w changelogu odnośnie tego co zostało zmienione.

Przy czy, nie musimy ręcznie edytować pliku debian/changelog -- są przeznaczone do tego odpowiednie narzędzia, w tym przypadku wykorzystamy dch -- zwykle będziemy korzystać z opcji -n , -i oraz -r .

W przypadku aktualizacji swojej, wykorzystujemy -i oraz -r.

Opcja -n uzupełnia wpis w changelogu o Non-maintainer upload.

Podglądając plik .changes , dostrzeżemy, że nie jest on podpisany.

Teraz zarówno plik .changes jak i .dsc są podpisane.

Tak stworzony pakiet można teraz dystrybuować, np.

Weryfikacja, podpisy i kontrola jakości

Plik taki nazywamy upstream.changelog .

Oczywiście nie edytujemy tego pliku ręcznie (choć można).

Debian posiada bardzo rozbudowany system robienia pakietów.

Wszystkie ważne informacje na temat zmian w pakiecie możemy wrzucić również do tego pliku.

Jednym z częściej używanych narzędzi będzie debsign , który to będzie nam podpisywał pliki .changes i .dsc zawierające między innymi sumy kontrolne.

Konfiguracja pakietu devscripts jest trzymana w /etc/devscripts.conf .

Dobrze jest przejrzeć ten plik, choć objętościowo może nieco przytłoczyć.

Konfiguracja lintiana trzymana jest w pliku /etc/lintianrc i w dużej mierze odpowiada za to jaki rodzaj błędów będzie nam pokazywany i w jaki sposób.

Jeśli jesteśmy początkującymi amatorami, możemy się nieco pogubić w tym co będzie próbował nam powiedzieć lintian.

Dobrze jest przestawić z początku opcję verbose oraz info na yes .

Spowoduje to wyświetlenie dość obszernej informacji na temat każdego z błędu.

W tym przypadku akurat strona projektu jest w miarę rozsądna i można się doszukać na niej wszystkich informacji.

Dokumentacja, copyright i pliki dodatkowe

Dokumentacja projektu to bardzo ważna rzecz i bez niej ani rusz.

Z grubsza będziemy mieli styczność z trzema rodzajami przypadków.

W pierwszym nie będziemy mieli żadnej dokumentacji.

W drugim będzie dokumentacja ale trzeba będzie ją przeformatować.

W trzecim będziemy musieli poprawić błędy w formatowaniu, które wypunktuje nam lintian .

Jednym z ważniejszych plików jest debian/control .

Wszystkie ważne informacje na temat zmian w pakiecie możemy wrzucić również do tego pliku.

Licencja jest chyba jedną z tych rzeczy na jaką debian kładzie największy nacisk.

Nie musimy całej treści tych plików kopiować do debian/copyright .

W pliku Copyright mamy też określanie praw do plików.

Jeśli plików jest dużo, to lepiej jest tego nie robić.

Pliki związane z odpalaniem usług systemowych, bo to jest poza zakresem tego poradnika.

W każdym razie, nie ma to większego znaczenia, z której nazwy skorzystamy.

W plikach unitów, możemy znaleźć w dokumentacji systemd dostępnej tutaj.

Przykład modułu DKMS

W przypadku modułów DKMS ogromne znaczenie ma nazwa samego modułu.

Dlatego też będzie trzeba posługiwać się pośrednią wersją, np. commit'a w repozytorium git.

Ta nazwa jest jedynie tymczasowa.

W pliku control plus sufiks .dkms .

W zmiennej $PACKAGE_NAME podajemy nazwę modułu z pliku Makefile .

Nie określamy wersji modułu.

Pozostałe zmienne również zostawiamy bez zmian.

$MAKE i $CLEAN .

W przypadku modułów DKMS trzeba też pamiętać, że moduły DKMS musi kończyć się frazą -dkms .

Dlatego też w Package: mamy tpe-dkms .

Jeśli budujemy moduł DKMS, to określamy --with dkms .

W pliku dkms.conf powstaje dostosowana wersja bez potrzeby ręcznej edycji tego pliku.

Tworzenie i utrzymanie własnego repozytorium

Ale to nam nie wystarcza, chcemy przecież repo dla naszych serwerów, idealnie z paczkami w gicie, podzielone na część “stabilną” i “dev”.

git clone . for a in $(find . czyli gdy odpalimy ten skrypt w katalogu głównym repa stworzy on nam repo w podanym katalogu z brancha master, chyba że podamy mu nazwę innego brancha.

Takie repozytorium ułatwia życie.

By proces aktualizacji pakietów przebiegał sprawnie, przydałoby się poznać trochę budowę katalogu debian/ .

W przypadku pakietów, wszystkie pliki są śledzone przez menadżer pakietów.

Wszystkie paczki .deb z naszego repo można potem aktualizować średnio co kilka dni?

Warto też pamiętać, że:

  • debianizacja źródeł jest często najtrudniejsza
  • budowanie w minimalnym chroot pomaga wyłapać braki
  • lintian i debsign porządkują cały proces
  • debian/control jest centralnym plikiem opisu pakietu
  • DKMS wymaga szczególnej uwagi przy nazwie i wersji
Pakiet Debian control i zależności

tags: #debian #jak #zrobic #wlasny #pakiet

Popularne posty:

About the author

Tomasz Sanecki administrator

Informatyk z zawodu i zamiłowania. Od 2007r właściciel firmy Perfect Systems. Specjalista do spraw bezpieczeństwa IT, serwisu urządzeń elektronicznych, sieci komputerowych. Prywatnie mąż i ojciec dwójki dzieci. Pasjonat nowoczesnych technologii, motocykli oraz włoskiego espresso.