Możliwa droga do zostania szeregowym developerem PLD

Każdego użytkownika Linuxa pracującego na swojej maszynie nachodziła refleksja na tematy filozoficzne - kto to wymyślił? kto to zrobił? i jak to zrobił? Pytania ciekawe - odpowiedzi również. 

Piszący ten tekst z niejednego, linuxowego pieca jadł chleb i w końcu wybrał ten właśnie gatunek - bo w końcu który chlebek na świecie smakuje najlepiej? Niestety - żeby był dobry chlebek musi też się wykształcić dobrych piekarzy - bo tak to będzie robiło się zakalce i wtedy już niestety trzeba chodzić głodnym...

Aby piekarz mógł dobrze pracować musi sobie zorganizować miejsce pracy i piec. Naszym miejscem pracy będzie samo PLD i dodatki które poniżej spróbuje opisać. Od razu zaznaczam, że sam jestem początkującym ''piekarzem'' - i sam musiałem zabrać się za receptury i sposób wypieku, gdyż doświadczeni ''piekarze'' leżą po nocach pijani i nie mają czasu na pisanie dla swoich czeladników ;-)

Jak już wspomniałem wcześniej do naszej ciężkiej pracy potrzebne jest PLD. Ja wybrałem wersje oficjalną (czyli w chwili pisania tego tekstu 1.0 ''Ra''). Później jest już z górki - instalujemy parę pakietów - sam proces instalacji w większości pominę, gdyż użytkownicy już powinni wiedzieć co to jest poldek i jak się go używa.

[root@ciesiel1 /root]# rpm -qa |grep rpm
rpm-4.0.2-106
rpm-build-tools-4.0.2-106
rpm-utils-4.0.2-106
rpm-perlprov-4.0.2-106
rpm-build-4.0.2-106
rpm-devel-4.0.2-106
rpm-pythonprov-4.0.2-106

[root@ciesiel1 /root]# rpm -qa |grep cvs
cvs-1.11.5-2

[root@ciesiel1 /root]# rpm -qa |grep mc
mc-4.5.55-10

Zwrócę uwagę tylko na CVS. Sposób instalacji środowiska bardzo dobrze opisuje Baseciq - ten krok należy wykonać ze szczególną starannością

Innym ważnym pakietem jest rpm plus dodatki. Głównym zajęciem szeregowego developera jest tworzenie lub modyfikacja plików .spec, które są głównym czynnikiem budowania pakietów RPM. Są jeszcze potrzebne różne inne pakiety i źródła  - ale to już w zależności od tego co będziemy budować.

Największą skarbnicą wiedzy o RPMie i budowaniu pakietów możemy znaleźć w publikacji Maximum RPM - opis jest w języku angielskim i nie jest mi znane tłumaczenie na nasz język. Na szczęście są jeszcze inne źródełka, a także i niniejszy opis - więc powinno nam być lżej przyswajać wiedzę. Szczególnie polecam stronę Grzegorza Niewęgłowskiego (lub lokalną kopie) gdzie dużo teorii i praktycznych rad może nam rozjaśnić w naszych głowach czym jest praca ze "specami".
Jest dostępny także opis stworzony przez Developera PLD lecz z tego co się dowiedziałem jest już trochę leciwy i niektóre dane mogą być nieścisłe.

Bo tej bombie teorii jaką niestety musimy przejść, czeka nas przestudiowanie jeszcze jednego dokumentu, którego najnowszą wersje możemy ściągnąć z CVS PLD. Będzie to nasze pierwsze ćwiczenie.

Uruchamiamy terminal (czy to zwykły, czy też np. przez SSH) i wykonujemy kroki:

[marekc@ciesiel1 marekc]$ cd rpm
[marekc@ciesiel1 rpm]$ cvs get PLD-doc/devel-hints-pl.txt
U PLD-doc/devel-hints-pl.txt
[marekc@ciesiel1 rpm]$

Jak widać kroki wykonujemy jako zwykły użytkownik (nie root) i tej zasady będziemy się konsekwentnie trzymali.
Do katalogu ~/rpm/PLD-doc/ ściągneliśmy z repozytorium PLD dokument tekstowy devel-hints-pl.txt. W tym dokumencie zawarte są zalecenia i ustalenia jakich powinniśmy się trzymać aby tworzyć właściwe dla PLD pakiety RPM.

Teraz spróbujemy ściągnąć jakiś .spec z CVS PLD i zbudujemy sobie jakąś paczkę - np. pakiet tar (przykład budowania 'ekg' mogliśmy obejrzeć także podczas instalacji CVS na stronie Baseciq):

[marekc@ciesiel1 marekc]$ cd rpm
[marekc@ciesiel1 rpm]$ cvs get SPECS/tar.spec
U SPECS/tar.spec
[marekc@ciesiel1 rpm]$ cd SPECS/
[marekc@ciesiel1 SPECS]$ rpmbuild -ba tar.spec
błąd: File /home/users/marekc/rpm/SOURCES/tar-1.13.25.tar.gz: Nie ma takiego pliku ani katalogu
[marekc@ciesiel1 SPECS]$ ./getsrc tar.spec
Trying to download sources for tar-1.13.25-7
Searching for file: tar-1.13.25.tar.gz
Trying CVS... OK
Searching for file: tar-non-english-man-pages.tar.bz2
Trying CVS... OK
Searching for file: tar-man_from_debian_tar_1.13.25-2.patch
Trying CVS... OK
Searching for file: tar-info.patch
Trying CVS... OK
Searching for file: tar-pipe.patch
Trying CVS... OK
Searching for file: tar-namecache.patch
Trying CVS... OK
Searching for file: tar-error.patch
Trying CVS... OK
Searching for file: tar-sock.patch
Trying CVS... OK
Searching for file: tar-nolibrt.patch
Trying CVS... OK
Searching for file: tar-man.patch
Trying CVS... OK
Searching for file: tar-ac25x.patch
Trying CVS... OK
Searching for file: tar-dots.patch
Trying CVS... OK
Searching for file: tar-pl.po-fix.patch
Trying CVS... OK
Download opreation completed: all files retrieved successfully

W przykładzie, za szybko chciałem zbudować pakiet - zaraz po ściągnięciu ''tar.spec''. 
Sam .spec bez źródeł jest jak karabin bez amunicji... Można wykorzystać skrypt 'builder' (i później nawet zalecam go używać) w katalogu SPECS, który to sam przeanalizuje potrzeby i ściągnie odpowiedniego .speca (oczywiście jeżeli tylko zawiera go repozytorium CVS), źródła i wykona paczki rpm i srpms - ale my nie będziemy tutaj sobie za bardzo ułatwiać pracy :-)

Po ściągnięciu plików dobrze jest obejrzeć danego .speca aby zobaczyć, co jest jeszcze potrzebne do zbudowania - można to zrobić zwykłym edytorem tekstowym lub wykonać:

[marekc@ciesiel1 SPECS]$ cat tar.spec |grep BuildReq
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: bison
BuildRequires: gettext-devel

Wiemy już co nam jest potrzebne - Teraz sprawdzimy czy mamy te pakiety w naszym PLD:

[marekc@ciesiel1 SPECS]$ rpm -q autoconf
autoconf-2.53a-1
[marekc@ciesiel1 SPECS]$ rpm -q automake
automake-1.6.3-1
[marekc@ciesiel1 SPECS]$ rpm -q bison
pakiet bison nie jest zainstalowany
[marekc@ciesiel1 SPECS]$ rpm -q gettext-devel
pakiet gettext-devel nie jest zainstalowany
[marekc@ciesiel1 SPECS]$

Czyli dwóch, potrzebnych pakietów brak. A więc 'poldek' rusza do boju (tutaj już lepiej użyć konta 'root' - chyba że mamy poldka skonfigurowanego do pracy 'sudo'):

[root@ciesiel1 log]# poldek
Wczytywanie ftp://ftp.pld-linux.org/dists/ra/PLD/i686/PLD/RPMS/packages.dir.gz...
Wczytywanie ftp://ftp.pld-linux.org/dists/ra/[...]/packages.dir.gz...
Wczytywanie ftp://ftp.pld-linux.org/dists/ra/[...]/packages.dir.gz...
Wczytywanie ftp://ep09.kernel.pl/pub/People/[...]/packages.dir.gz...
Wczytywanie ftp://ftp.pld-linux.org/dists/ra/supported/i686/packages.dir.gz...
Wczytywanie http://pld.mysza.eu.org/Ra/i686/packages.dir.gz...
Przeczytano 6814 pakietów

Usunięto 16 zdublowanych pakietów z listy dostępnych
Wczytywanie /root/.poldek-cache/packages.dir.dbcache.var.lib.rpm.gz...
Przeczytano 559 pakietów

Witaj w poldekowym trybie interaktywnym. Wpisz "help" aby otrzymać pomoc.

poldek> install bison gettext-devel
Przetwarzanie zależności...
Zaznaczono 1 pakiet do instalacji:
I bison-1.35-5
Pobieranie ftp://ftp.pld-linux.org/dists/[...]/bison-1.35-5.i686.rpm...
.................................................. 100.0% [196.5K]
Uruchamianie rpm --upgrade -vh --root / --noorder...
Preparing... ########################################### [100%]
1:bison ########################################### [100%]
Installing set #2
Przetwarzanie zależności...
Zaznaczono 1 pakiet do instalacji:
I gettext-devel-0.10.40-4
Pobieranie ftp://[...]/gettext-devel-0.10.40-4.i686.rpm...
.................................................. 100.0% [295.6K]
Uruchamianie rpm --upgrade -vh --root / --noorder...
Preparing... ########################################### [100%]
1:gettext-devel ########################################### [100%]
poldek>

I jak tu nie kochać Poldka? :-)

Mamy już teoretycznie wszystko aby zbudować pakiet 'tar'. Wracamy więc do naszego zwykłego konta i:

[marekc@ciesiel1 SPECS]$ rpmbuild -ba tar.spec
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.22007
Patch #0 (tar-man_from_debian_tar_1.13.25-2.patch):
Patch #1 (tar-info.patch):
Patch #2 (tar-pipe.patch):
Patch #3 (tar-namecache.patch):
Patch #4 (tar-error.patch):
Patch #5 (tar-sock.patch):
Patch #6 (tar-nolibrt.patch):
Patch #7 (tar-man.patch):
Patch #8 (tar-ac25x.patch):
Patch #9 (tar-dots.patch):
Patch #10 (tar-pl.po-fix.patch):
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.97619

[...]

Zapisano: /home/users/marekc/rpm/SRPMS/tar-1.13.25-7.src.rpm
Zapisano: /home/users/marekc/rpm/RPMS/tar-1.13.25-7.i686.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.54009
+ umask 022
+ cd /home/users/marekc/rpm/BUILD
+ _autoreqprov=n
+ [ n = y ]
+ cd tar-1.13.25
+ rm -rf /home/users/marekc/tmp/tar-1.13.25-root-marekc
+ exit 0
[marekc@ciesiel1 SPECS]$

[...] oznacza, wycięte przeze mnie komunikaty jakie generuje kompilowany 'tar'.
Polecenie 'rpmbuild -ba ' każe nam zbudować ze speca kompletny pakiet - ale to już wiemy z teoretycznych szkoleń ;-)
Wszelkie komunikaty w razie jakiegoś błędu podczas budowania możemy odnaleźć w pliku: '/var/tmp/rpm-tmp.22007'

Widzimy, że gotowe pakiety mamy w określonych katalogach i możemy je spokojnie zainstalować. A komunikat 'exit 0' oznacza brak błędów podczas budowania.

Nasz pierwszy pakiet został zbudowany. 
Pozostaje jednak niedosyt - ciągle czujemy, że jak na razie korzystamy z czyjeś pracy, a w końcu pragniemy także coś zrobić dla potomności i sami chcemy stworzyć plik .spec

No to zaczynamy. Naszym pierwszym (a właściwie moim) wykonanym specem będzie Mantis czyli system kontroli błędów oparty o stronę WWW (PHP) i bazę SQL Mysql. 
Tutaj mała dygresja - większość pakietów powstaje dlatego, że danemu Developerowi był on akurat potrzebny; oznacza to że nie ma sensu pisanie na listę dyskusyjną z prośbą o stworzenie określonego pakietu bo można otrzymać parę przykrych komentarzy (w najlepszym razie).

Pierwszą czynnością jest zainstalowanie pakietu ze źródeł. Potem notujemy sobie co należy zrobić aby dany pakiet zaczął działać - wszystko po to aby przewidzieć co dany .spec powinien zrobić aby pakiet pracował w miarę bezproblemowo po instalacji RPMa - Można to zanotować np. na kartce papieru - ale od czego mamy komputery?

Moje notatki wyglądały tak:

// MANTIS

// Mysql init
# cd /etc/rc.d/init.d
# ./mysql init
# /usr/bin/mysqladmin -u mysql password 'password'

// Tworzenie bazy w mysql
# mysqladmin -umysql -p create bugtracker
# cd /mantis/sql
# mysql -umysql -p bugtracker < db_generate.sql

// Plik config_inc.php

// Sprawdzenie i poprawka
http:/mantis/admin/check.php

// Pierwsze logowanie
u: administrator
p: root
Dodać nowe i skasować stare :-)

// co potrzebne do uruchomienia
- mysql
- mysql-client
- php
- php-common
- php-pcre
- php-mysql
- apache

// do rpma (zmiany w związku z językiem)
plik: config_defaults_inc.php
$g_default_language = 'english';
$g_default_language = 'polish';
// Zamiana łańcucha w config_defaults_inc.php
sed -e s/$g_default_language = 'english';/$g_default_language = 'polish';/g
config_defaults_inc.php

// Zamiana usera z root na mysql
w config_inc.php

Do każdego pakietu należy podchodzić indywidualnie - dlatego parę słów o samym mantisie. System jest oparty o gotowe pliki składające się na stronę WWW, dokumentacje i plik potrzebny do stworzenia odpowiedniej bazy Mysql. Nie będziemy dokonywali żadnych kompilacji - więc uprości to nasz proces budowania i testowania pakietu.
Łącząc informacje zawarte w dostarczonej dokumentacji i własnych notatek wiemy już że głównym zadaniem naszego RPMa będzie takie zaprojektowanie go, aby odpowiednie pliki PHP zostały przekopiowane w odpowiednie miejsce, dokonać niezbędnych poprawek w plikach konfiguracyjnych lub innych poprawek, które naszym zdaniem mogą ułatwić pracę przyszłym użytkownikom. Pamiętajmy jednak żeby nie przedobrzyć.
Niestety nie wszystko uda nam się zautomatyzować - dlatego stworzymy dwa pliki tekstowe (w dwóch wersjach językowych PL i EN) z krótkim opisem, co należy wykonać aby system zadziałał.

Wydaje mi się także, że dobrym zwyczajem jest po zainstalowaniu źródeł przewidzieć właściwe zależności, aby nasz pakiet działał bez problemu na innym komputerze. Na przykład w instrukcji do instalacji mantisa w wymaganiach jest wymieniony m.in. pakiet PHP - W PLD po instalacji samego PHP, mantis będzie wyświetlał błędy. Okazuje się że pakiety w PLD są maksymalnie ''rozdrobnione'' i do działania potrzebny jest jeszcze pakiet 'php-pcre' - a do tego, żeby strony PHP odpowiednio komunikowały się z bazą 'mysql' jest potrzeba zainstalowania 'php-mysql'. Zależności może być wiele i moim skromnym zdaniem lepiej żebyśmy umieścili jakiś nadmiarowy pakiet w zależnościach niż żeby jakiegoś brakowało.

W naszym przypadku po zainstalowaniu i uruchomieniu pakietu Mantis ze źródeł, wystarczy wykonać np. 'rpm -qa |grep php' aby wybrać odpowiednie pliki. To samo robimy z 'mysql' i 'apache'.

Zaczynamy od stworzenia pliku (możemy użyć polecenia 'touch') lub korzystamy z innego pliku .spec w celu modyfikacji do naszych potrzeb (np. 'cvs get SPECS/template.spec' spowoduje ściągnięcie szkieletu z CVS PLD). Otwieramy go w naszym ulubionym edytorze tekstowym (vim, emacs, pico, mcedit itp.)

Summary: The Mantis Bug Tracker
Summary(pl): Mantis - System Kontroli Błędów
Name: mantis
Version: 0.18.0a4
# define _alpha a4
Release: 1
License: GPL
Group: Development/Tools

[...]

Zaczynamy wypełniać tzw. preambułę, czyli wstęp w którym opisujemy nasz pakiet - myślę, że wyjaśnianie powyższego nie jest specjalnie potrzebne. Zwrócę tylko uwagę na linię 'Version' i 'Ralease' - zgodnie z devel-hints-pl.txt powinno ono raczej wyglądać tak (ponieważ ta wersja mantis'a jest określona jako alpha):

Version: 0.18.0
%define alpha a4
Release: 0.%{_alpha}.1

ale u mnie powodowało to błąd przy budowaniu, gdyż jak dalej zobaczymy nazwa źródeł korzysta z pola 'Version' i każda manipulacja na nim powoduje potrzebę przebudowania .speca lub zmianę nazwy archiwum w którym są źródła (co jest bardzo złym nawykiem i karygodnym błędem!). Tak więc w końcu zostawiłem tak jak jest i nikt specjalnie nie zwrócił mi na to uwagi :-)
(przyp. autora: jednak późniejsza praktyka pokaże nam, że zmiany takie są jednak chlebem powszednim więc nie bójmy się ich dokonywać)

[...]

Source0: http://dl.sourceforge.net/mantisbt/%{name}-%{version}.tar.gz
# Source0-md5: 4c730c1ecf7a2449ef915387d85c1952
Source1: %{name}-doc-PLD.tar.gz
URL: http://mantisbt.sourceforge.net/

[...]

Dalej mamy opis źródełek - w PLD podaje się go najczęściej w formie linku plus fraza %{name}-%{version}.tar.gz i tak naprawdę ta fraza jest najważniejsza do zbudowania pakietu, ponieważ URL (w naszym przypadku http://dl.sourceforge.net/mantisbt/) jest ignorowany. Tak więc z makra %name i %version budowana jest nazwa pakietu i taka nazwa jest wyszukiwana w ~/rpm/SOURCES/
Źródeł programu może być kilka. U nas występuje jeszcze Source1 - jest to dodatkowa dokumentacja składająca się z dwóch plików tekstowych zawierająca dodatkowe wskazówki po instalacyjne. Pierwotnie próbowałem zrobić to korzystając z mechanizmu Patch i polecenia:

diff -urN katalog_z_oryginałem katalog_z_poprawionym_oryginałem > źródła-powód.patch

opisanego w devel-manual (rozdział 1.2.2), ale mechanizm ten nie pozwala tworzyć nowych plików więc pozostało tylko wykonać dodatkowe źródła.

Pamiętajmy także aby w żadnym przypadku nie modyfikować ręcznie źródeł programu. Prawidłowy .spec powinien wykorzystywać natywne źródła, a wszelkie zmiany dokonujemy w %build, %install lub za pomocą patch'ów.

Sygnatura md5 po # jest wynikiem wykorzystania tzw. distfiles i na razie to musi nam wystarczyć. Distfiles omówimy gdy będziemy zapisywać do CVS PLD - czyli nieprędko ;-)

[...]

Requires: apache >= 1.3.27-4
Requires: apache-mod_dir >= 1.3.27-4
Requires: php >= 4.0.3
Requires: php-mysql >= 4.0.3
Requires: php-pcre >= 4.3.1-4
Requires: php-common >= 4.3.1-4
Requires: mysql >= 3.23.2
Requires: mysql-client >= 3.23.56-1
Requires: sed
BuildArch: noarch
BuildRoot: %{tmpdir}/%{name}-%{version}-root-%(id -u -n)

[...]

W 'Requires' podajemy zależności, czyli co musi być zainstalowane aby dany pakiet działał lub żeby wykonały się poprawnie polecenia wykonywane przez .spec (np. sekcja %post)
W 'BuildArch' architekturę pod który przeznaczony jest RPM - u nas jest to 'noarch' czyli bez żadnej konkretnej architektury - z moich obserwacji wynika że developerzy PLD omijają to pole - chyba że jest to właśnie 'noarch'.
'BuildRoot' jest bardzo ważnym tagiem - na szczęście występuje zawsze w takiej postaci jak u nas - a oznacza katalog w którym rpm będzie budował pakiet z sekcji %install naszego .speca.

[...]

%define _mantisdir /home/services/httpd/mantis
# define _mantisdir /home/httpd/html/mantis

%description
Mantis is a web-based bugtracking system.

%description -l pl
Mantis jest systemem kontroli błędów opartym na interfejsie WWW i bazie MySQL.

[...]

W tej części wykorzystujemy przydatną właściwość RPMa czyli definiowanie stałych. W naszym przykładzie '_mantisdir' jest katalogiem w którym będą zainstalowane pliki dla serwera WEB. Tutaj mała uwaga dotycząca komentarza '#' - Gdy definiujemy makro wtedy komentarz nie działa, dlatego usunęliśmy '%' przed słowem 'define' (możemy także użyć frazy '%%') czyli gdybyśmy napisali:

%define _mantisdir /home/services/httpd/mantis
#
%define _mantisdir /home/httpd/html/mantis

To wtedy stała '_mantisdir' miała by wartość /home/httpd/html/mantis, mimo że nie taka jest nasz intencja - Nie muszę chyba wyjaśniać jakie to może spowodować problemy?
W '%description' opisujemy krótko charakterystykę pakietu, a niżej widzimy jak to zrobić dla opisu w języku polskim - później RPM wykorzystując zmienne locale wyświetla odpowiednią wersje językową 'description' gdy sobie tego od RPMa życzymy.

[...]

%prep
%setup -q -a1

[...]

Od tego momentu skończyliśmy wypełniać dane preambuły. Sekcja %prep może wykonać skrypt potrzebny przed instalacją plików. My akurat nic przed instalacją robić nie musimy dlatego sekcja ta jest pusta. 
Dalej jest '%setup -q -a1' - czyli rozpakowanie źródeł do katalogu zdefiniowanego wcześniej przez 'BuildRoot'. Dodatkowe parametry tego tagu wyłączają komunikaty przy rozpakowaniu '-q', a parametr '-a1' określa które źródła należy rozpakować. Po '%setup' możemy także korzystać z makra '%patch' który nakłada łatki na źródła. Umożliwia to taką modyfikację źródeł jakie tylko chcemy bez potrzeby zmian w samych źródłach (o czym pisaliśmy wcześniej).

[...]

%install
rm -rf $RPM_BUILD_ROOT
install -d $RPM_BUILD_ROOT%{_mantisdir}

cp -af *.php admin core css graphs images lang sql $RPM_BUILD_ROOT%{_mantisdir}

sed -e 's/root/mysql/g' config_inc.php.sample > \
$RPM_BUILD_ROOT%{_mantisdir}/config_inc.php

[...]

Tak naprawdę w większości pakietów przed '%install' wykonywane jest makro '%build', które kompiluje nam źródła, a w najprostszej postaci wygląda tak:

%build
%configure
make

U nas nie ma potrzeby wykonywania żadnych kompilacji więc od razu wykonywana jest sekcja '%install'. Na początku czyścimy sobie katalog w którym będziemy instalowali nasz program (czyli 'fake root') - mimo że prawdopodobnie jest pusty - ale lepiej dmuchać na zimne. Potem dokonujemy instalacji pakietu przekazując mu w parametrze '-d' że docelowo ma być zainstalowany w 'fake root', ale same pliki pojawią się w naszym katalogu tymczasowym (TMPDIR), dlatego później za pomocą polecenia 'cp' kopiujemy pliki, jakie są potrzebne, do właściwego 'fake root' - zauważmy że pominęliśmy np. katalog 'doc'.
Następnie jeszcze za pomocą komendy 'SED' dokonujemy drobnej poprawki w pliku konfiguracyjnym mantisa - zamieniając domyślnego użytkownika MYSQL z 'root' na 'mysql'. Taką poprawkę mogliśmy wykonać wcześniej w sekcji '%prep' i tagu '%patch' ale przy tak małych poprawkach bardziej efektywniej jest to zrobić tutaj.

[...]

%clean
rm -rf $RPM_BUILD_ROOT

[...]

Tag '%clean' jest w .specach tworzonych dla PLD obowiązkowy i określa co należy zrobić gdy cały pakiet zostanie zbudowany. Tutaj mała uwaga - ten tag w tym miejscu nie oznacza że jest w tej chwili wykonany - jeżeli by tak było, to występujący później tag '%files' miałby niejakie problemy z nieistniejącymi już plikami. Czyli po poprawnym zbudowaniu pakietu, wykonywane jest makro '%clean', a w przypadku jakiegokolwiek błędu, nie jest - czyli rozpakowane i zainstalowane źródła pozostają. Umożliwia nam to np. diagnostykę w przypadku błędów podczas budowania pakietu.

[...]

%post
if [ "$LANG" = "pl_PL" ]; then
#sed -e "s/= 'english';/= 'polish';/g" %{_mantisdir}/config_defaults_inc.php > #%{_mantisdir}/config_defaults_inc_PLD.php
#mv -f %{_mantisdir}/config_defaults_inc_PLD.php %{_mantisdir}/config_defaults_inc.php
echo
echo "Mantis zapisany..."
echo "Więcej: /usr/share/doc/mantis-%{version}/PLD_Install_PL.txt.gz"
echo
else
echo
echo "Mantis loaded..."
echo "More: /usr/share/doc/mantis-%{version}/PLD_Install_EN.txt.gz"
echo
fi

[...]

Tutaj mamy przykład co możemy zrobić z plikami, które będą instalowane po zbudowaniu pakietu. Makro '%post' wykonywane jest przez RPM podczas instalacji pakietu. Zakomentowane polecenia umożliwiają zmianę w zainstalowanym pliku 'config_defaults_inc.php' zgodnie z zawartością zmiennej locale 'LANG'. Później w zależności od tej zmiennej wyświetlany jest komunikat w języku PL lub EN.
Zadacie pytanie dlaczego część tych poleceń jest ''wyłączona" - otóż, później gdy dany .spec chcemy już udostępnić ogółowi zostanie on sprawdzony pod względem ''czystości rasowej'' :-) - W tym przypadku okazało się, że taka zmiana w plikach konfiguracyjnych, może spowodować kłopoty podczas np. zmiany użytkownika. Programy korzystające z 'locale' powinny odpowiednio reagować na zmiany 'locale' - np. po modyfikacji LANG na 'EN_en' zacząć pracować po angielsku - W naszym przypadku strona PHP nie zacznie pracować po angielsku, dlatego dodany został w/w komentarz, a w pliku 'PLD_Install_PL.txt.gz', który jest dodatkową instrukcją, co należy zrobić po instalacji pakietu RPM aby 'mantis' po uruchomieniu rozmawiał z nami po polsku.

[...]

%files
%defattr(644,root,root,755)
%doc doc/* PLD_Install_PL.txt PLD_Install_EN.txt config_inc.php.sample
%dir %{_mantisdir}
%{_mantisdir}/admin/
%{_mantisdir}/core/
%{_mantisdir}/css/
%{_mantisdir}/graphs/
%{_mantisdir}/images/
%{_mantisdir}/lang/
%{_mantisdir}/sql/
%{_mantisdir}/account*
%{_mantisdir}/bug*
%{_mantisdir}/core.*
%{_mantisdir}/csv*
%{_mantisdir}/docum*
%{_mantisdir}/file*
%{_mantisdir}/history*
%{_mantisdir}/index*
%{_mantisdir}/jump*
%{_mantisdir}/log*
%{_mantisdir}/ma*
%{_mantisdir}/me*
%{_mantisdir}/news*
%{_mantisdir}/print*
%{_mantisdir}/proj*
%{_mantisdir}/set*
%{_mantisdir}/sig*
%{_mantisdir}/sum*
%{_mantisdir}/view*

%config(noreplace) %{_mantisdir}/config_inc.php
%config(noreplace) %{_mantisdir}/config_defaults_inc.php
%exclude %{_mantisdir}/core/.cvsignore

[...]

Dochodzimy powoli do finału :-). W sekcji tej określamy co, gdzie i jak ma zostać zainstalowane u użytkownika instalującego naszego RPMa. Tag %files jest bardzo ważny gdyż błędy spowodowane tutaj mogą uniemożliwić działanie pakietu u końcowego użytkownika. W 'podtagu':

%defattr(644,root,root,755)

określamy domyślne atrybuty instalowanych plików - możemy oczywiście określać atrybuty dla każdego pliku osobno.
Następnie w:

%doc doc/* PLD_Install_PL.txt PLD_Install_EN.txt config_inc.php.sample

określamy nasze pliki, które znajdą się w dokumentacji. Czyli katalog 'doc/' z katalogu 'TMPDIR' i pliki z 'SOURCE1' oraz 'config_inc.php.sample' zostaną spakowane i przy instalacji pakietu RPM umieszczone w domyślnym katalogu dokumentacji - w PLD jest to /usr/share/doc/...
I wreszcie w:

%dir %{_mantisdir}

nakazujemy podczas instalacji RPM'a stworzenie katalogu zgodnie ze stałą '%{_mantisdir}'
i kopiujemy pliki jakie są poniżej tego tagu.
Na początku nie wypisywałem wszystkich tych katalogów i plików indywidualnie, a po prostu użyłem frazy:

%{_mantisdir}

Jednak przy takiej konstrukcji i wykorzystaniu makra %config(noreplace), pojawi się błąd podczas budowania pakietu:

[...]

RPM build errors:
File listed twice: /home/services/httpd/mantis/config_defaults_inc.php
File listed twice: /home/services/httpd/mantis/config_inc.php

Czyli dwa pliki miały podwójne znaczenie - występowały na liście do skopiowania i jako pliki konfiguracyjne. Dlatego trzeba niestety zrobić listę plików jak to my zrobiliśmy minus pliki, które znajdą się w makro '%config'. Samo makro '%config' pozwala szczególnie traktować pliki konfiguracyjnie podczas kasowania RPMa lub jego aktualizacji.
Ostatnie makro:

'%exclude %{_mantisdir}/core/.cvsignore'

nakazuje wyłączenie pliku z pakietu RPM - w tym przypadku jest to pozostałość po CVS mantisa.

I to już koniec naszej pracy. Po wykonaniu polecenia 'rpmbuild -ba mantis.spec' powinien nam zbudować się pakiet rpm i srpm. Zostaje jeszcze przetestowanie czy wszystkie pliki są tam gdzie chcieliśmy, czy mają odpowiednie prawa i czy pakiet działa tak jak powinien. Jeszcze ewentualne poprawki i musimy przepuścić naszą pracę przez zestaw adaptujący 'adapter.awk'.
Ściągamy go z CVSu:

[marekc@ciesiel1 marekc]$ cvs get SPECS/adapter.awk
U SPECS/adapter.awk
[marekc@ciesiel1 marekc]$

następnie zmieniamy nazwę pliku .speca dodając na końcu np. org i wykonujemy:

[marekc@ciesiel1 SPECS]$ ./adapter.awk mantis.spec.org > mantis.spec
[marekc@ciesiel1 SPECS]$

W wyniku tej operacji otrzymamy 'mantis.spec' który zostaje przystosowany do wymagań PLD. Zainteresowanych zmianami, zapraszam do przestudiowania 'nowego' .speca.

Teraz możemy szukać kogoś, kto umieści naszego .speca i źródła w repozytorium CVS PLD. Mamy do dyspozycji listę developerów: w mailu umieszczając załącznik z naszym .specem (oczywiście bez źródeł - lub jeżeli mamy jakieś własne źródła to umieszczamy je na jakieś stronie WWW lub innym ftp. i podajemy linka - źródła natywne powinny dać się ściągnąć z lokacji jaką umieściliśmy w naszym .specu.). Załącznik powinien być typu plain-text.
Można także spróbować na grupie IRC #PLD znaleźć ofiarę, która umieści naszą prace w repozytorium.
Dobrze też w czasie nauki robienia .speców podglądać jak to robią inni - W repozytorium CVS jest naprawdę z czego wybierać. A my nabywając umiejętność czytania plików .spec możemy skupić się już tylko na odpowiednim ich napisaniu.

W końcu otrzymamy możliwość zapisu do CVS i wtedy czytamy następną część poradnika ''W krainie CVS''