Jak działają buildery
Na infrastrukturę builderów składają się cztery główne daemony:
- request-handler,
- source-builder,
- binary-builder,
- ftp-admin.
Kod źródłowy builderów znajduje się w repozytorium SVN:
http://svn.pld-freebsd.org/svn/infrastructure/builder/trunk.
Na wstępie istotne jest omówienie jak wygląda struktura builderów. Wszystkie buildery podzielone są na
rodziny. Każda
rodzina odpowiada za budowanie pakietów dla różnych gałęzi dystrybucji. W każdej
rodzinie istnieje tylko jeden
source-builder i co najmniej jeden
binary-builder. W całej strukturze builderów istnieje tylko jeden
request-handler i tylko jeden
ftp-admin.
Wysylanie zleceń
Do wysyłania builderom zleceń służy skrypt
make-request. Jest on napisany w perlu i bazuje na klasie
RPC::PlClient.
Obsługa zleceń
Obsługą zleceń użytkownika-dewelopera zajmuje się daemon
request-handler. Jest on napisany w perlu i bazuje na klasie
RPC::PlServer. Jego głównym, i na razie jedynym, zadaniem jest nasłuchiwanie na określonym porcie i odbieranie zleceń wygenerowanych przez skrypt
make-request. Docelowo ma on mieć również za zadanie wysyłanie do
ftp-admina zleceń przenoszenia i usuwanie pakietów z FTP, wstrzymywania builderów, modyfikowania kolejki zleceń itp. W systemie builderów istnieje tylko jeden
request-handler.
Budowanie pakietów źródłowych
Do budowania pakietów
src.rpm służy daemon
source-builder. Jest on napisany w perlu i bazuje na klasie
Net::Daemon. Jego głównym zadaniem jest budowanie pakietów źródłowych. W systemie może istnieć kilka
source-builderów po jednym dla każdej
rodziny builderów, jednak na każdą maszynę na której budowane są pakiety przypada jeden
source-builder. W szczególności, jeżeli na jakiejś maszynie istnieje więcej niż jeden chroot w którym są budowane pakiety (w każdym dla innej
rodziny), to i tak są one obsługiwane przez jeden source-builder.
Source-builder wykonuje następujące zadania:
- dla każdego chroota uruchamia proces sprawdzający czy w kolejce są zlecenia zbudowania pakietu źródłowego w danym chroocie i kolejno budujący te pakiety,
- dla każdego chroota uruchamia proces sprawdzajacy czy w kolejce są zlecenia które zostały juz zakończone i jest możliwe wyczyszczenie spoola po tych zleceniach,
- nasłuchuje na zadanym porcie i na żądanie
binary-buildera i ftp-admina przesyła mu wynikowe pliki żądanych pakietów.
Budowanie pakietów binarnych
Za budowanie pakietów binarnych odpowiada daemon
binary-builder. Jest on napisany w perlu i bazuje na klasie
Net::Daemon. Jego głównym zadaniem jest budowanie pakietów binarnych. Oczywiście w systemie builderów może istnieć wiele builderów, na każdą maszynę na której budowane są pakiety przypada jeden
binary-builder. W szczególności, jeżeli na jakiejś maszynie istnieje więcej nię jeden chroot, w którym budowane są pakiety, to i tak są one obsługiwane przez jeden
binary-builder.
Binary-builder wykonuje nastepujące zadania:
- dla każdego chroota uruchamia proces sprawdzający czy w kolejce są zlecenia dla których są gotowe pakiety źródłowe, i jeżeli tak ściąga je
- dla każdego chroota uruchamia proces sprawdzający czy w kolejce są zlecenia zbudowania pakietów binarnych w danym chroocie i pakiety źródłowe dla tych zleceń zostały ściągnięte, jeżeli tak kolejno budujacy te pakiety,
- dla każdego chroota uruchamia proces sprawdzajacy czy w kolejce są zlecenia które zostały juz zakończone i jest możliwe wyczyszczenie spoola po tych zleceniach,
- nasłuchuje na zadanym porcie i na żądanie
ftp-admina przesyła my wynikowe pliki żądanych pakietów.
Zarządzanie zawartością serwera FTP
Kolejnym daemonem będącym częscią builderów jest
ftp-admin, jego zadaniem jest pobieranie gotowych pakietów z builderów i zarządzanie nimi. Jest on jak i pozostałe, napisany w perlu i bazuje na klasie
RPC::PlServer. Jego głównym zadaniem jest ściaganie wszystkich pakietów (zarówno źródłowych, jak i binarnych) z builderów, a przy spełnieniu określonych warunków umieszczanie ich w drzewie FTP i regenerowanie indeksów poldka. Docelowo
ftp-admin ma również obsługiwać zlecenia przenoszenia pakietów między drzewami FTPa, jednak ta funkcjonalność jest dopiero w fazie planowania.
Ftp-admin wykonuje nastepujące zadania:
- uruchamia proces zajmujacy się akceptacją pakietów do ściągnięcia, ma to na celu wyznaczenie (dla niektórych builderów) pakietów które spełniają kryteria pozwalające na ściągnięcie pakietów wynikowych (źródłowych i binarnych); w szczególności dla builderów produkcyjnych takim kryterium jest, sprawdzenie czy zlecenie zostało wykonane poprawnie na wszystkich binary-builderach
- dla każdego chroota na którym były budowane pakiety uruchamia proces ściągający pakiety źródłowe lub binarne, które zostały zaakceptowane,
- uruchamia proces który dla wszystkich zakończonych, zaakceptowanych i pobranych zleceń, przenosi pakiety wynikowe ze spoola do domyślnego drzewa FTPa.
Proces budowania pakietu
Ważnym elementem procesu budowania pakietów jest skrypt
database-notify. Nie jest on częścią systemu builderów, wchodzi w skład systemu repozytorium pakietów. Jego działanie polega na śledzeniu zmian w repozytorium i przechowywanie w bazie danych o epoce, wersji i rewizji pakietu na zadanym branchu. Do omówienia zasady działania builderów, wystarczy że przyjmniemy że taka baza wygląda nastepujaco.
Tabela
package_branch
Tabela
package
Tabela
branch
| id | name |
| 1 | trunk |
| 2 | rpm-4.1 |
| 3 | rpm-4.1.1 |
Część tych danych jest kopiowana później do bazy zleceń i służy do między innymi weryfikacji czy pakiet o zadanym EVR nie znajduje się już w kolecje do budowania. Docelowo ma ona również uniemożliwiać wysłanie zlecenia zbudowania pakietu o EVR mniejszym niż znajdujące się w drzewie FTP danej
rodziny builderów.
Informacja dotycząca struktury FTPa przechowywana jest tabeli
Tabela
ftp_branch
Informacje dotyczące struktury systemu builderów przechowywana są w dwóch tabelach.
Tabela
family
Tabela
builder (
w uproszczeniu)
Najistotnieszą informacją jaką niosę te tabele, jest który
source-builder odpowiada za budowanie pakietów źródłowych dla zadanego
binary-buildera. Druga istotną informacją jest nazwa gałęzi FTPa na którą trafi pakiet po zbudowaniu.
Proces budowania pakietu rozpoczyna się na życzenie użytkownika, poprzez wygenerowanie zlecenia i wysłanie do
request-handlera. Komenda wysyłająca takie zlecenie może wyglądać tak:
$ ./make-request add -b th-i386 -b th-i686 -p 1 --with neon --without python --without perl rpm:rpm-4.1.1
Polecenie to spowoduje wygenerowanie i wysłanie zlecenia zbudowania pakietu
rpm z gałęzi
rpm-4.1.1 na builderach
th-i386 i
th-i686, z priorytetem równym 1, z bcondami --with neon --without python --without perl. Po opcji -b podaje się jedynie buildery pakietów binarnych, system builderów sam znajdzie sobie source-buildery które odpowiadają za budowanie pakietów dla podanych binary-builderów. Priorytet, podawany po opcji -p, pozwala na ustalanie kolejności budowania pakietów i działa tak, że pakiety z mniejszym priorytetem budowane są jako pierwsze, natomiast jeżeli pakiety mają ten sam priorytet decyduje kolejność zleceń.
Przyjmowaniem zleceń zajmuje sie daemon
request-handler. Kiedy skrypt
make-request nawiazuje połączenie z
request-handlerem, następuje autentykacja i autoryzacja użytkownika wysyłajacego zlecenie. W przypadku powodzenia
request-handler odszukuje jakie
source-buildery są odpowiedzialne za budowanie pakietów źródłowych dla zadanych
binary-builderów. Po tym kroku nastepuje dopisanie zlecenia do bazy. W tym miejscu
request-handler kończy swoje działanie.
Baza zleceń składa się z dwóch tabel, które po przesłaniu powyższego zlecenia, mogą wygladać tak:
Tabela
request (
w uproszczeniu)
Tabela
build
Na tym etapie obsługę zlecenia przejmuje
source-builder, który ściaga pakiet z repozytorium, ściąga pliki źródłowe i buduje pakiet źródłowy i umieszcza go w spoolu, gdzie czeka na ściagniecie przez
binary-buildery i
ftp-admina. W przypadku niepowodzenia status w bazie
build jest ustawiany na '_fail_', natomiast gdy budowanie się powiedzie status builda pakietu źródłowego jest ustawiany na '_acceptwait_', co oznacza że pakiet czeka na akceptację (o czym później). Status buildów
binary-builderów dla których pakiety buduje ten
source-builder jest ustawiany na '_srcwait_', co oznacza że
binary-builder może ściągać pakiety źródłowe z
source-builderów. Dodatkowo plik wynikowy jest dopisywany do tabeli
ftp_queue.
Tabela
build
Tabela
ftp_queue (
w uproszczeniu)
Zadaniem tej ostatniej tabeli jest przechowywanie informacji o plikach oczekujacych na przesłanie do
binary-builderów i
ftp-admina.
Teraz obsługa zlecenia zajmują się
binary-buildery, a ściślej ich część odpowiedzialna za ściaganie pakietów źródłowych z
source-builderów, ten element
binary-buildera jest niezależny od pozostałych i pracuje jako osobny proces, jego zadaniem jest pobranie wszystkich aktualnie dostępnych pakietów źródłowych. Po pomyślnym zakończeniu tego etapu status buildu dla zadanego
binary-buildera jest ustawiany na '_source_', co oznacza że pakiet źródłowy został pobrany i pakiet jest gotowy do zbudowania. Tabela
build na tym etapie może wyglądać tak:
Z powyższej tabeli wynika, że
binary-builder dla
th-i386 ściagnął już plik źródłowy, a
binary-builder dla
th-i686 jeszcze nie.
Kolejnym etapem, obsługiwanym przez
binary-builder jest budowanie pakietów binarnych z pakietu źródłowego. W przypadku niepowodzenia status w bazie
build jest ustawiany na '_fail_'. W przypadku powodzenia pakiety binarne umieszczane sa w spoolu, gdzie czekają na ściągnięcie przez
ftp-admina, a status builda jest ustawiany na '_acceptwait_', co oznacza że pakiet czeka na akceptację przez
ftp-admina. Dodatkowo pliki wynikowe dopisywane są do tabeli
ftp_queue.
Tabela
build
Tabela
ftp_queue (
w uproszczeniu)
| id | id_build | file | status |
| 1 | 1 | rpm-4.1.1-0.40.src.rpm | none |
| 1 | 2 | rpm-4.1.1-0.40.i386.rpm | none |
| 1 | 2 | rpm-build-4.1.1-0.40.i386.rpm | none |
| 1 | 3 | rpm-4.1.1-0.40.i686.rpm | none |
| 1 | 3 | rpm-build-4.1.1-0.40.i686.rpm | none |
W powyższym przykładzie pakiet zbudował się na wszystkich
binary-builderach i czeka na akceptację.
Kolejny etap budowania, czyli akceptacja zleceń, odbywa się na
ftp-adminie. W chwili obecnej proces ten polega na weryfikacji czy zlecenie zostało wykonane poprawnie na wszystkich
binary-builderach. Jeżeli, nie status buildów danego zlecenia jest zmieniany z '_acceptwait_' na '_ok_', a status plików w tabeli ftp_queue - ustawiany na '_completed_', co owocuje zaprzestaniem dalszego przetwarzania zlecenia. Jeżeli zlecenie zostanie zaakceptowane, status buildów jest ustawiany na '_ftpwait_', co oznacza że czekają na ściagnięcie przez
ftp-admina.
Po tym etapie tabela
build może wyglądać tak.
W tym miejscu zlecenie nadal jest obsługiwane przez
ftp-admina, ale przez trzy (w tym przypadku) procesy zajmujące się ściąganiem pakietów z poszczególnych builderów (źródłowych i binarnych). Rozbicie tego na osobne procesy ściagające pakiety z poszczególnych builderów, ma zapobiegać zablokowaniu sie ściągania pakietów w przypadki czasowej niedostepności jakiegoś buildera. Po ściagnieciu pakietu jego status w tabeli
ftp_queue jest zmieniany na '_transferred_'.
Następny etap odbywa się również na
ftp-adminie, jeżeli dla danego zaakceptowanego zlecenia ściagnięte zostały wszystkie pakiety ich status w tabeli
ftp_queue jest ustawiany na '_completed_', pakiety zostaja przeniesione ze spoola do domyślnej gałęzi FTPa, indeksy poldka przeregenerowane, a status buildów ustawiony na '_ok_'. Informacje o pakietach na FTPie przechowywane są w tabeli
ftp.
Na koniec obsługa zlecenia jest ponownie przekazywana do builderów (źródłowych i binarnych), na których wszystkie pakiety z tabeli
ftp_queue ze statusem '_completed_' są usuwane ze spoola, a ich rekordy usuwane z tabeli.
--
TomaszTrojanowski - 05 Mar 2007