Kapitel 11. Pakke-formater

De fleste har nok lidt svært ved, at forstå og bruge Linux' tekstopsætningsfiler når de lige er startet med at bruge Linux. Dette kan - som oftest - volde problemer, da mange mennesker jo netop installerer Linux for at bruge de medfølgende funktioner til fil- og printer-deling; eksempelvis på et kollegie, eller i en virksomhed.

Det kan imidlertid godt være svært, da funktionerne til brugerstyring, netværksopsætning, indstilling af tiden osv. ofte ikke er lige nemme at gå til. Men fortvivl ikke - der er flere grafiske programmer, som kan hjælpe hvis du ikke vil gøre det tekstbaseret.

I dette kapitel ser vi først nærmere på de pakkeformater, som mange programmer distribueres i.

11.1. Pakker af data

Linux har glimrende muligheder for at pakke programmer og datafiler sammen svarende til zip-formatet kendt fra Windows-verdenen. Faktisk kan du med unzip udpakke zip-filer. Du skal blot installere unzip-pakken først - se Afsnit 11.1.3. Tilsvarende kan du have brug for at kunne udpakke en selvudpakkende zip-fil (som kommer som en exe-fil fra Windows). Til det kan du bruge unzipsfx.

Du kan teoretisk set stadig komme ud for programpakker i Z-format. De skal udpakkes med uncompress (og de laves med compress). På grund af bedre pakke-effektivitet anvendes kombinationen af tar og gzip eller bzip2. Dette er nærmere omtalt i Afsnit 11.1.1. Et andet alternativ som efterhånden er en stærk standard for udbredelse af Linux-programmer i binær form er RPM, som er omtalt i Afsnit 11.1.3.

Det kan nævnes, at tar historisk set er et program, man bruger til at lime datafiler sammen, så de kan lægges ud på bånd - deraf navnet tar som står for Tape ARchive.

11.1.1. Pakning af data med tar og gzip/bzip2

I Linux/Unix-verdenen anvendes oftest tar-formatet til at samle mange filer i én pakkefil. Denne er ikke komprimeret, men alene en samling af filerne i én pakkefil. Har du filerne oversigt.txt, tekstA.txt op til tekstD.txt, som du vil pakke sammen i filen tekster.tar, så gøres dette med:

[tyge@hven ~]$ tar cvf tekster.tar oversigt.txt tekst[A-D].txt
oversigt.txt
tekstA.txt
tekstB.txt
tekstC.txt
tekstD.txt
[tyge@hven ~]$ ls -l oversigt.txt tekst[A-Z].txt tekster.tar
-rw-r--r-- 1 tyge tyge  400   mar  3 17:41 oversigt.txt
-rw-r--r-- 1 tyge tyge  1024  mar  3 17:41 tekstA.txt
-rw-r--r-- 1 tyge tyge  1024  mar  3 17:41 tekstB.txt
-rw-r--r-- 1 tyge tyge  1024  mar  3 17:41 tekstC.txt
-rw-r--r-- 1 tyge tyge  1024  mar  3 17:41 tekstD.txt
-rw-r--r-- 1 tyge tyge  10240 mar  3 17:41 tekster.tar

Du kan således give alle de filnavne, der skal pakkes som det sidste argument, og giver du et katalognavn i listen vil dette katalog - med alle underkataloger - også blive pakket med. Som det ses af eksemplet vil programmet tar vise filnavne på de filer, der pakkes. Ønsker du ikke at se dette, skal du blot udelade option v, dvs. brug tar cf TARFILNAVN.tar LISTE_AF_FILER i stedet.

Hvis de filer du ville gemme er almindelige tekstfiler vil du i tekster.tar direkte kunne læse dig til de enkelte filer, som skulle lægges i pakken. Derfor vil tar-filen fylde lidt mere end summen af de filer, der skulle gemmes. For små filer vil der være en del ekstra fyld.

Ofte ønsker man nu at komprimere tar-filen, så den fylder mindre. Oftest vinder man en faktor 2, men både langt mere eller noget mindre er set i praksis. Der er flere muligheder for at komprimere, hvor gzip er langt det mest udbredte.

[tyge@hven ~]$ gzip tekster.tar
tekster.tar:               93.3% -- replaced with tekster.tar.gz     
[tyge@hven ~]$ ls -l tekster.tar.gz
-rw-r--r-- 1 tyge tyge  706 mar  3 17:41 tekster.tar.gz

Programmet gzip fortæller at filen tekster.tar.gz er komprimeret med 93.3% og vi ser at filen nu kun fylder 706 bytes. Ofte vil man se at gzippede tar-filer ikke hedder .tar.gz men den kortere form .tgz, og de to fil-endelser betyder det samme.

Bemærk, at originalfilen tekster.tar nu er væk. Kun den pakkede fil er tilbage efter gzip.

Ofte laver man ikke tar-filen, men springer direkte til .tgz-formatet ved at danne pakkefilen med z (for zip) tilføjet optionerne.

[tyge@hven ~]$ tar cvzf tekster.tgz oversigt.txt tekst[A-D].txt
oversigt.txt
tekstA.txt
tekstB.txt
tekstC.txt
tekstD.txt
93.3%
[tyge@hven ~]$ ls -l tekster.tgz
-rw-r--r-- 1 tyge tyge  706 mar  3 17:41 tekster.tgz

Vi skal nu se på hvordan du udpakker dine filer igen fra pakkefilen. Først ser vi hvad der er inde i pakken (t-option), og når vi er sikre på hvad der vil ske, bliver filerne udpakket (x-option). Antag at vi har placeret pakkefilen i et katalog, hvor der ikke er andre filer end pakkefilen.

[tyge@hven ~]$ tar tzvf tekster.tgz
-rw-r--r-- 1 tyge tyge  400   mar  3 17:41 oversigt.txt
-rw-r--r-- 1 tyge tyge  1024  mar  3 17:41 tekstA.txt
-rw-r--r-- 1 tyge tyge  1024  mar  3 17:41 tekstB.txt
-rw-r--r-- 1 tyge tyge  1024  mar  3 17:41 tekstC.txt
-rw-r--r-- 1 tyge tyge  1024  mar  3 17:41 tekstD.txt
[tyge@hven ~]$ tar xzvf tekster.tgz
oversigt.txt
tekstA.txt
tekstB.txt
tekstC.txt
tekstD.txt

Igen kan v-option udelades, hvis du ikke vil have helt så meget information præsenteret på skærmen. Det skal nævnes, at tar har en stor mængde options, som kan læres lidt efter lidt. Brug man tar til at komme videre. En option du måske allerede nu kan lære er -C DIR, som bruges til at pakke pakkefilen ud, svarende til at du står i kataloget DIR og pakker ud.

Du kan også komme ud for at folk bruger bzip2 til at komprimere data med i stedet for gzip. En fil der ender på .bz2 kan du udpakke med bunzip FILNAVN.bz2. Er det en tar-fil som er pakket med bzip2, kan du med en nyere version af tar udpakke direkte med tar xjvf FILNAVN.tar.bz2, mens man med en ældre version af tar må tage den i to omgange: bunzip2 FILNAVN.tar.bz2 og derefter tar xvf FILNAVN.tar.

11.1.2. Flytning af data til større disk

Tip: Lad os lige tage et avanceret eksempel. Det kan jo ske, at du løber tør for plads på din harddisk og køber en ekstra disk. Du beslutter nu, at du vil flytte /home over på den nye disk (/dev/hdb1) og vil køre videre med Linux-systemet på den gamle disk. Lad os antage, at du har partitioneret /dev/hdb med fdisk /dev/hdb og kørt /sbin/mke2fs /dev/hdb1 for at formatere disken.

[root@linus /root]# mkdir /mnt/nydisk
[root@linus /root]# mount /dev/hdb1 /mnt/nydisk
[root@linus /root]# cd /home
[root@linus /root]# tar cvf - . | (cd /mnt/nydisk; tar xpf -)

De to første linjer er blot forberedelse, så vi har den nye disk til rådighed på /mnt/nydisk. Dernæst stiller vi os der hvor sikkerhedskopieringen skal startes fra (gør at dette er "."). I den sidste kommando laver vi en sikkerhedskopi til "-" dvs. til stdout, som kanaliseres videre til en modtage-tar-kommando, der startes under /mnt/nydisk. Denne gang tilføjes p-option for at de udpakkede filer får samme rettigheder og ejerforhold som de oprindelige.

Det kan bemærkes at den sidste linje af ovenstående kommandolinje kunne også være skrevet om følgende, hvor stdin/stdout er implicit.

[root@linus /root]# tar cv . | (cd /mnt/nydisk; tar xp)

Først når du har tjekket at alle dine filer er genskabt under /mnt/nydisk kan du slette dine filer og skabe kontakt med den nye disk med /home-filerne. Redigér /etc/fstab så den nye disk er med:

/dev/hdb1  /home   ext2    defaults        1 1

Bruger du en anden partition end /dev/hdb1 til den nye disk, så skal du naturligvis erstatte dette i /etc/fstab

[root@linus /root]# mv /home /oldhome
[root@linus /root]# umount /mnt/nydisk
[root@linus /root]# mount /home

Hvis du kan se at alt fungerer, kan du slette den gamle /home som nu endte på /oldhome. Brug rm -rf /oldhome, når du er helt sikker.

Det der kan gå galt her er, at man har links, som ikke peger på de rigtige steder efter flytningen. Med /home er dette normalt ikke tilfældet, men er det /usr du flytter, så skal du være meget forsigtig og altid lave disse operationer i enkeltbrugermodus (dvs. brug init 1).

En guide til at opgrade harddiske kan findes på http://www.ibiblio.org/pub/Linux/docs/HOWTO/mini/other-formats/html_single/Hard-Disk-Upgrade.html.

11.1.3. Installation af RPM-programpakker

Gennem mange år har Unix-systemadministratoren skullet hente nye programmer hjem med kildetekst og derefter oversætte og installere. Det gik oftest nemt, men kunne fra tid til anden være meget svært. Hvad værre var, man kunne typisk ikke afinstallere programmer uden at have 100 pct. styr på installationsfasen og styr på at andre programmer ikke anvendte samme biblioteker. Alt i alt ganske problematisk og uden reel mulighed for at kunne opgradere systemet løbende.

Firmaet Red Hat og andre er i de senere år gået over til at oversætte programmer én gang for alle og så distribuere programpakker, som indeholder binær kode, biblioteker, manualsider og andet. Fordelen ved disse programpakker er, at systemet kan holde styr på præcis hvad der er installeret. Alle pakker undersøges for afhængigheder og du kan afinstallere pakker igen, hvis andre pakker ikke påvirkes af det. Red Hats format for programpakker kaldes RPM, som er en forkortelse for "Red Hat Package Management", hvilket vil sige Red Hats pakkehåndtering.

Tabel 11-1. Miniguide i at anvende rpm-programmet.

Kommando Forklaring
rpm -i pakke_version.rpm Installér pakken
rpm -ivh pakke_version.rpm Installér pakken med status vist. Tilføj option --nodeps hvis pakken skal installere uden at tjekke for manglende støttepakker.
rpm -Uvh pakke_version.rpm Opgrader pakken med status vist. Hvis pakken ikke er installeret i forvejen vil den blive installeret. Tilføj option --nodeps hvis pakken skal installere uden at tjekke for manglende støttepakker.
rpm -Fvh pakke_version.rpm Opgrader pakken med status vist. Hvis pakken ikke er installeret i forvejen vil den ikke blive installeret. Tilføj option --nodeps hvis pakken skal installere uden at tjekke for manglende støttepakker.
rpm -qip pakke_version.rpm Viser information om den pakke, som kan installeres.
rpm -e pakke Afinstallér den installerede pakke.
rpm -q PAKKE Viser version af den installerede pakke.
rpm -qi PAKKE Viser information om den installerede pakke.
rpm -qf filnavn Viser hvilken RPM-pakke filnavnet kom fra.
rpm -ql PAKKE Viser hvilke filer der blev installeret med RPM-pakken.
rpm -qlp PAKKE.rpm Viser hvilke filer der er med i RPM-pakken.
rpm -qa Viser alle installerede RPM-pakker.
rpm -ql PAKKE Viser alle filnavne indeholdt i pakken.
rpm -Va Tjek alle RPM-installerede filer for ændringer siden installation af pakkerne.

Lad os illustrere styrken i RPM-programmet: Du sidder på en maskine som systemadministrator og opdaterer alle Linux-maskinerne i dit netværk med én kommando - og endda med krypteret transmission, så ingen kan lytte med. Det er simpelthen administratorens drøm af et system. Nemt, sikkert og stabilt. Hvis alle maskiner, der skal opgraderes, er nævnt i filen /etc/serverlist, vil nedenstående magiske linje (ja, det er avanceret - men sejt, ikke sandt?) opgradere vim-pakken, som hentes fra ftp-serveren SERVER. Alle maskiner bliver lige opgraderet i ét hug!

[root@linux /root]# cat /etc/serverlist | \
    xargs -l1 -i= -r ssh = rpm -U ftp://SERVER/vim-4.6-4.i386.rpm

Tip: Under installationen eller opgraderingen af en RPM-pakke sker det at den klager over at man mangler nogle filer. Det skyldes at RPM-pakken, som man er ved at installere, afhænger af andre RPM-pakker for at fungere, dvs. RPM-pakker som man enten mangler eller som man har, men af for gammel version. Et godt trick er at gå ind på http://www.rpmfind.net/linux/RPM/. Her kan du søge efter RPM-pakker, men også efter filnavne og derved oftest finde hvilke RPM-pakker du mangler.

11.1.4. RPM for programmøren

RPM-filer opstår selvfølgelig ikke "af sig selv". Der skal bruges et værktøj til at lave dem - nemlig det samme rpm-program, som man bruger til alle de andre RPM-funktioner.

rpm-programmet har en build-funktion, som bruges når man skal lave sine egne rpm-filer. En 'build' består af flere faser

  • prep - udpakning af kildetekstenfiler

  • setup - installation af patches og opsætning af softwaren

  • build - oversættelse (bygning) af softwaren

  • install - installation af program-, dokumentations- og opsætningsfiler i de korrekte kataloger.

  • packaging - sammenpakning af kildetekst- og binære RPM-filer

  • clean - oprydning

Hver af disse faser kan kontrolleres fuldt ud gennem en opsætningsfil, som rpm-programmet bruger til hele build-processen. Denne opsætningsfil kaldes en spec-fil, og er den vigtigste fil at forstå, når man skal lave sine rpm-pakker.

11.1.4.1. Katalogstruktur

Normalt bruger rpm-programmet en katalogstruktur under /usr/src/redhat til at generere rpm-filer. Man kan bruge et andet toplevel-katalog, men /usr/src/redhat er default.

Herunder er der et antal underkataloger:

  • SOURCES  - indeholder alle de kildefiler og patches, der bruges til build af en rpm-pakke

  • SPECS - her ligger spec-filen

  • BUILD - er et 'arbejdskatalog' hvor kildefilerne pakkes ud, og selve oversættelsen finder sted

  • RPMS - er der hvor de færdige binære rpm-filer placeres. Dette katalog har mindst to underkataloger: i386 til rpm-filer, der er rettet mod i386-platformen og noarch til rpm-filer, der ikke er platformsafhængige.

  • SRPMS - er der hvor de færdige source rpm-filer placeres.

Inden man går i gang med at lave en rpm-fil, skal man sørge for at have source-filerne lagt ned i kataloget SOURCES og en spec-fil i kataloget SPECS. Det kan man f.eks. gøre ved at installere en source rpm-fil.

11.1.4.2. En spec-fil til ssh (Secure Shell)

Der har været en del skriveri om ssh på sslug mailing-listen, og for nylig er der skrevet en god webside om hvordan man bruger dette program. ssh findes ikke i rpm-format, så det kunne være nyttigt at bruge det som eksempel på, hvordan man laver en spec-fil og bruger den til at lave rpm-pakker.

Hele spec-filen ssh.spec ligger i underkataloget rpm til bogens eksempler på www.linuxbog.dk, men lad os kigge på den i nogle mindre bidder.

Summary: Secure Shell - secure network communications
Name: ssh
Version: 1.2.25
Release: 2
Copyright: GPL
Group: Utilities/Networking
Source: ftp://sunsite.auc.dk/pub/security/ssh/ssh-1.2.25.tar.gz
Patch: ssh-1.2.25-Makefile.patch
URL: http://www.cs.hut.fi/ssh/
BuildRoot: /tmp/ssh-build

%description
Secure Shell enables you to communicate securely across on unsafe
network such as the Internet. Communication is transparently 
encrypted, and thus secured against eavesdropping. The package 
includes drop-in replacements for telnet, rlogin, rsh, rcp and
other standard networking tools.

Starten på sådan en spec-fil er ret standardiseret. Der er en stribe tags som man skal angive - det er bl.a. al den information om pakken, som rpm -i kommandoen skal levere.

Rækkefølgen af de enkelte tags er ligegyldig, bare de er der.

  • Name: Pakkens navn

  • Summary: En kort beskrivelse (under en linje) af, hvad pakken indeholder

  • Version: Programmets versionsnummer.

  • Release: RPM-pakkens 'build-nummer' - det er uafhængigt af selve programmets versionsnummer og bruges blot til at holde rede på forskellige versioner af denne rpm-pakke med samme udgave af programmet i.

  • Copyright: Hvilken copyright programmet er underlagt. Det er naturligvis vigtigt at skrive, hvis programmet ikke kan distribueres frit.

  • URL: Hvis der er en webside om pakken, kan man skrive dens URL her.

  • Group: Red Hat bruger dette felt til at gruppere pakkerne - f.eks. "Games", "Development tools" o.lign.

  • Description: Det er den lange beskrivelse af softwaren, og strækker sig derfor over flere linjer - faktisk så mange man har lyst til, indtil der kommer en linje som begynder med et procenttegn.

Source-tag'en er vigtig - her fortæller man, hvor man har fundet den oprindelige source-fil til programmet, gerne med en URL. Det er en dårlig idé kun at skrive filnavnet - så ved man ikke, hvor man skal gå hen for at finde eventuelle nyere versioner af programmet. Bemærk: Filnavnet der står her, skal matche det filnavn, der ligger i SOURCES-kataloget. Så med eksemplet, skal SOURCES-kataloget indeholde filen ssh-1.2.25.tar.gz.

Patch-tag'en er også vigtig - det er ændringer til de oprindelige sources (i form af patches) som skal installeres inden programmet kan oversættes. Disse skal også ligge i SOURCES-kataloget. I eksemplet er der kun én patch; hvis man har flere, skal de nummereres, og så lister man dem en ad gangen (en patch uden nummer er automatisk nummer nul):

 Patch: foo-Makefile.patch
 Patch1: foo-glibc.patch
 Patch2: foo-wtmpfix.patch

BuildRoot-tag'en er ikke krævet, men anbefales. Det er ikke det katalog, hvori programmerne bliver oversat, men derimod det toplevel-katalog, hvori de oversatte programmer og øvrige filer placeres i installationsfasen, inden de pakkes sammen i rpm-filerne. Hvis ikke man bruger en BuildRoot-tag er default at filerne placeres i de "rigtige" kataloger - /usr/bin, /etc, /usr/lib osv. Det gør måske ikke noget, men hvis der er opsætningsfiler involveret er det en rigtig god idé at bruge BuildRoot-tag'en; ellers kan man nemt risikere at komme til at overskrive sine egne omhyggeligt tilpassede opsætningsfiler undervejs i build-processen, eller (måske endnu værre) komme til at inkludere sine egne opsætningsfiler i rpm-pakken, som hentes af tusindvis af brugere. (F.eks. havde jeg en overgang password-filerne til min ISP liggende på ftp.sslug.dk, i en ppp-RPM-pakke). BuildRoot-tag'en er dog ofte lidt besværlig, da man næsten altid skal rette i programmets 'Makefile' eller installationsscript, for at de kan finde ud af at installere pakkerne et andet sted end det normale. Men det er ulejligheden værd.

11.1.4.3. prep-fasen

prep (prepare) fasen består almindeligvis blot i udpakning af source-filerne til et underkatalog under BUILD. rpm's build-funktion kan automatisk håndtere tar-arkiver (også komprimerede), så normalt kan man blot nøjes med at skrive:

 %prep

i spec-filen, og så går det af sig selv.

11.1.4.4. setup-fasen

setup-fasen er der hvor der begynder at ske noget.

 %setup 
 %patch -p1 
 ./configure --prefix=/usr 

Denne fase skal gøre programmet klart til at blive oversat. Typisk skal der først installeres de forskellige patches som man har listet, og dernæst skal programmet måske konfigureres.

De linjer der står efter %setup er i virkeligheden almindelige /bin/sh-kommandoer. Dog er der defineret nogle makroer, som rpm's build-funktion håndterer, inden de overgives til kommandofortolkeren - en af makroerne er %patch. Denne makro kører patch-programmet, med patch nummer nul som input. For at apply'e patch nummer 1 skriver man %patch1, patch nummer 2 er %patch2 osv. Rækkefølgen af de forskellige patches er ligegyldig, så længe patch-programmet kan finde ud af det. Man kan også sagtens springe patches over, f.eks. hvis de ikke er relevante for den platform man builder til.

Inden kommandoerne i setup-fasen afvikles, sættes default-kataloget til /usr/src/redhat/BUILD/pakkenavn-version, dvs. /usr/src/redhat/BUILD/ssh-1.2.25 i eksemplet. Hvis source-arkivet ikke er blevet pakket ud til det katalognavn (f.eks. bruger nogle source-arkiver en underscore i stedet for en bindestreg), så angiver man det rigtige katalognavn på %setup-linjen, f.eks.:

 
 %setup -n foobar_1.17

hvis source-filerne er havnet i /usr/src/redhat/BUILD/foobar_1.17

Default-kataloget er også vigtigt at kende, når man vælger hvilke options man giver til patch-programmet. I eksemplet kaldes patch med -p1-option, fordi patch-filen indeholder ssh_1.2.25 som første element i filnavnet. Men da default-kataloget allerede er nede i ssh-1.2.25, bruges -p1-option for at fjerne det første katalog-element fra filnavnet, inden patch leder efter de filer den skal ændre.

Opsætning af programmet kan ske på mange måder - her er det et configure-script, som kaldes med en option om, at filerne skal bruge /usr som præfiks (default er ofte /usr/local, som jeg foretrækker at reservere til ikke-rpm-styrede programmer). Andre programpakker konfigureres via en headerfil eller ved at ændre i Makefile - så må man lave en patch mellem den oprindelige fil og den rettede, og installere den som en patch i patch-listen.

Kommandoen rpm -bp specfile vil afvikle prep- og setup-fasen, og kan bruges til at "teste" om alle ens patches nu også kan installeres uden problemer.

11.1.4.5. build-fasen

build-fasen er der, hvor programmerne oversættes, og ofte er det blot at køre make. Ligesom ved setup-fasen, er default-kataloget sat til der hvor source-filerne blev pakket ud - hvis man brugte -n-optionen til setup-fasen, så bliver det "husket" så man ikke skal skrive den igen.

 %build 
 make cflags="$RPM_OPT_FLAGS" ldflags="-s" 

Her er der dog givet nogle parametre til make-kommandoen. CFLAGS bliver sat til $RPM_OPT_FLAGS - det er en miljøvariabel som rpm's build-funktion giver med til alle kommandoerne i build-fasen og som indeholder standard "optimizer"-indstillingerne for programmer, som oversættes med rpm. Default er det -O2 -m486 -fno-strength-reduce på i386-platformen.

Kommandoen rpm -bc specfile vil først afvikle prep- og setup-faserne og dernæst build-fasen. Hvis man har travlt og allerede har brugt rpm -bp til at afvikle prep og setup, kan man bruge rpm -bc --short-circuit specfile for bare at køre build-fasen.

Det er typisk under build-fasen, at man ramler ind i de fleste problemer. Her kan det være nyttigt at glemme rpm et øjeblik og i stedet gå ned i build-kataloget og køre build-kommandoerne manuelt, indtil man har fået rettet det hele og programmet kan oversættes. Så laver man en patch-fil med sine ændringer, tilføjer den til spec-filen (husk at få den med i %setup-fasen!), og går så tilbage til at builde med rpm.

11.1.4.6. install fasen

install-fasen sørger for at installere de nu oversatte programmer på de rigtige steder i katalogstrukturen. Oftest sker det med kommandoen 'make install', da de fleste pakker heldigvis selv kan finde ud af at installere sig selv. Men ellers må man selv skrive de kommandoer der skal til - enten cp, install eller hvad man nu foretrækker.

Det er også vigtigt, at man sørger for at de installerede filer får korrekt ejer/gruppe-attributter og permissions.

ssh spec-filen er lidt mere kompliceret end normalt:

 %install 
 rm -rf $RPM_BUILD_ROOT 
 mkdir -p $RPM_BUILD_ROOT 
 make install 

 %post 
 if [ ! -f /etc/ssh_host_key ]; then 
    echo "Generating ssh host key" 
    umask 022 
    /usr/bin/ssh-keygen -b 1024 -f /etc/ssh_host_key -N '' 
 fi 

En del af kompleksiteten skyldes brugen af BuildRoot-tag'en - inden filerne kan installeres, skal det sikres at det katalog vi installerer i er tomt. Derfor slettes det først, og oprettes så bagefter igen, hvorefter make install klarer resten. Det er dog ikke sket uden at jeg måtte ændre i Makefile - men det blev gjort med den patch, der blev installeret helt tilbage i setup-fasen.

Normalt vil make install til ssh sørge for at generere filen /etc/ssh_host_key, som er en del af ssh's krypteringsnøglesæt. Men det vil jo ikke være smart at inkludere den fil i rpm-pakken; så ville alle som brugte rpm-pakken jo have denne nøgle til fælles. Derfor er denne del af installationen fjernet fra Makefile'n, og i stedet lagt ud som et post-install script - det står under %post.

Disse kommandoer vil blive afviklet når brugeren installerer den færdige rpm-pakke, dvs. hver eneste gang ssh-pakken bliver installeret på en pc. Derved får hver enkelt pc sin egen nøgle-fil.

%post bruges også til andre ting - hvis man laver en rpm-pakke med et shared library i, er det en god idé at køre /sbin/ldconfig i et post-install script; derved opdaterer man den dynamiske linkers tabel over hvilke biblioteker der er installeret, og det kan så bruges med det samme (uden at man skal reboote systemet).

Der er andre af sådanne scripts, som man kan definere: %post-un afvikles når man afinstallerer en rpm-pakke, og der er også pre-install (%pre) og pre-uninstall (%pre-un) scripts.  De kan selvfølgelig kombineres.

Install-fasen køres med kommandoen rpm -bi specfile - man kan også her bruge --short-circuit for kun at afvikle denne fase.

11.1.4.7. sektionen files

Når filerne er blevet installeret, så er det eneste der mangler at pakke dem sammen i en binær rpm-fil. For at kunne gøre det, er det nødvendigt at opremse alle de filer, der er en del af pakken - det sker i sektionen %files.

 %files 
 /usr/bin/make-ssh-known-hosts 
 /usr/bin/ssh 
 /usr/bin/ssh-add 
 
 %config /etc/ssh_config 
 %config /etc/sshd_config 
 
 %doc COPYING INSTALL OVERVIEW TODO 
 %doc README README.CIPHERS README.SECURERPC README.SECURID README.TIS RFC TODO

Filerne listes blot med deres fulde path-navn (man ser bort fra evt. BuildRoot her). Hvis en fil er en opsætningsfil, skal man skrive %config før filnavnet; det fortæller rpm-programmet, at denne fil ikke må slettes eller overskrives når man opdaterer pakken, men skal gemmes som en .rpmsave-fil.

Dokumentationsfiler listes med %doc - og dem behøver man ikke at bekymre sig om at skulle installere. De kopieres automatisk fra det katalog, hvor source-arkivet er blevet udpakket. Dokumentationsfiler placeres i /usr/doc/pakkenavn-version-kataloget. Hvilke filer man tager med som dokumentationsfiler er selvfølgelig et skøn, men hellere lidt for mange end for få. (Når man installerer en rpm-pakke kan man bede om ikke at få dokumentationsfilerne med - ved at bruge --excludedocs-optionen).

Bemærk, at man-pages ikke regnes under dokumentation - de betragtes som en essentiel del af pakken, på lige fod med selve programmet.

Det er selvfølgelig vigtigt, at man får alle filerne med, som hører til pakken. Det kan være nyttigt at køre make -n install for bare at se hvad pakken foretager sig under installationen, og holde øje med hvilke filer der kommer hvorhen.

Hvis en pakke indeholder så mange filer, at de har deres eget underkatalog, kan man nøjes med at specificere kataloget - så følger alle filerne deri automatisk med. Det skal dog være et katalog, der kun bruges af den pågældende pakke - ellers kan man få sig nogle overraskelser.

Det er også muligt at angive, at et tomt katalog er en del af pakken - det vil typisk være et katalog til f.eks. log-filer, som der jo ikke er nogen af når man laver rpm-filen, men som skal findes for at programmet kan køre. Det skal opremses i sektionen %files som

 %dir /var/log/foobar 

11.1.4.8. Den ultimative build-kommando

Når man har en spec-fil, som er helt på plads, kan man bruge en enkelt rpm-kommando til at køre gennem hele build-fasen og generere rpm-filerne:

[tyge@hven ssh]$ rpm -ba --clean specfile

Den kommando klarer det hele: Udpakning af sources, installation af patches, opsætning af programmet, oversættelse, installation, sammenpakning i rpm-filer og oprydning bagefter så BUILD-kataloget er pænt og ryddeligt.

11.1.4.9. Sikke et besvær!

Det er selvfølgelig lidt mere omstændeligt at lave en rpm-fil, end bare at hælde et program igennem en oversætter og ned i /usr/local. Nogle gange kan det være frustrerende små detaljer i spec-filen, som gør at en build fejler - og det er som regel først efter, at din pc har tygget et par timer på at oversætte programmet...

Men min erfaring er, at den tid man bruger på at nørkle en ordentlig spec-fil sammen, er godt givet ud. Det er meget nemmere at holde styr på sin software, når man med en enkelt kommando kan få en oversigt over, hvad der er installeret og hvilke filer hver pakke indeholder.

For nogle år siden opgraderede jeg mit system fra Red Hat 4.2 til 5.1. Det var en større opgradering, bl.a. fordi der skiftes fra de gamle libc (version 5) til det nye glibc (version 6). Red Hats installationsprogram klarede det meste af opgraderingen uden problemer, men jeg havde en del software-pakker, som jeg selv havde lavet i rpm-format. Nu var det nemt at finde dem frem - jeg kunne bruge

[tyge@hven ~]$ rpm -qia | grep -v Manhattan

til at liste alle pakker på mit system og filtrere Red Hats nye pakker fra. Det blev til en liste på 10-15 pakker, som jeg selv måtte stå for at opdatere til glibc - og fordi jeg havde installeret dem liggende som RPM-pakker, kunne jeg nemt gentage build-processen, og rette de småting der skulle til for at de kunne oversættes med glibc. Selv programmer, jeg sidst havde haft fat i for 2 år siden kunne nemt genoversættes - fordi spec-filen indeholdt alle de oplysninger, der skulle til for at lave programmet. Jeg behøvede ikke at granske hukommelsen for at komme i tanke om, hvordan det nu var jeg havde konfigureret programmet sidst.

Så bare klø på - det lønner sig.

11.1.5. Bygge RPM ud fra SRPM

I dette afsnit ser vi på hvordan man bygger en RPM-pakke ud fra kilde-RPM-filen, dvs. en .src.rpm-fil. Man behøver faktisk ikke at være root for at bygge en RPM-fil. Du skal blot gøre følgende:

[tyge@hven ~]$ cd
[tyge@hven ~]$ mkdir rpm
[tyge@hven ~]$ cd rpm
[tyge@hven rpm]$ mkdir BUILD  RPMS  SOURCES  SPECS  SRPMS
[tyge@hven rpm]$ mkdir RPMS/i386
[tyge@hven rpm]$ cd
[tyge@hven ~]$ echo "%_topdir    $HOME/rpm" > .rpmmacros

Når du så har hentet en .src.rpm-fil, f.eks. dos2unix-3.1-3.src.rpm, så kan du skrive

[tyge@hven ~]$ rpmbuild --rebuild  dos2unix-3.1-3.src.rpm
dos2unix-3.1-3.src.rpm
Installerer dos2unix-3.1-3.src.rpm
Udfører(%prep): /bin/sh -e /var/tmp/rpm-tmp.61717
+ umask 022
+ cd /home/pto/rpm/BUILD
+ cd /home/pto/rpm/BUILD
+ rm -rf dos2unix-3.1
+ /bin/gzip -dc /home/pto/rpm/SOURCES/dos2unix-3.1.tar.gz
/home/pto/rpm/SOURCES/dos2unix-3.1.tar.gz:      + tar -xvvf -
...

og en masse flere linjer.

Hvis alt går godt ender din din-nyligt-hentede.i386.rpm i $HOME/rpm/RPMS/i386/ og du kan nu installere (som root) med rpm -Uvh $HOME/rpmRPMS/i386/din-nyligt-hentede.i386.rpm. Har du en Alpha og ikke en pc, da kommer pakken ikke til at hedde i386 men alpha

11.1.6. chkconfig

chkconfig er et nyttigt lille værktøj til ændringer i services i et runlevel. Værktøjet følger med Red Hat og Mandrake.

Antag, at du har en service foo, som du ønsker at tilføje til runlevel 3. Du har installeret (måske gennem rpm) et script i kataloget /etc/rc.d/init.d, som følger de gængse retningslinjer for service-scripts (dvs. at en service startes op vha. foo start og lukkes ned vha. foo stop). Nedenfor ser du hvordan den nye service tilføjes. Bemærk, at der er to minus-tegn foran "level"

[root@linus root]# chkconfig --level 3 foo on

Bliver du træt af servicen foo kan du naturligvis fjerne den. Du udskifter blot on med off. Du kan også bruge chkconfig til at tjekke hvilke runlevels en service bliver startet op under. Nedenfor tjekker vi named. Bemærk igen, at der er to minus-tegn foran "list".

[root@linus root]# chkconfig --list named
named 0:off 1:off 2:off 3:off 4:off 5:off 6:off

11.1.7. Installation af DEB-programpakker

Skal du installere programmer på Debian eller Corel Linux, skal du være root. Med Corel Linux er det meningen at man skal anvende "Applications"->"System"->"update". Der anvendes et program der hedder get_it. Her kan man sætte cd-rom, ftp- eller http-adresser hvor updates hentes fra. Som standard er Corels ftp-update adresse medtaget. Man kan jo prøve at tilføje ftp://ftp.dk.debian.org/debian for at få adgang til alle Debian-pakkerne.

Du kan dog også være interesseret i at kunne styre installationen selv fra kommandolinjen. Nyttige kommandoer er:

  • dpkg -i PAKKE.deb - installerer pakken.

  • dpkg -r PAKKE - fjerner pakken igen.

  • dpkg -s PAKKE - viser status for pakken.

  • dpkg -L PAKKE - viser hvilke filer, der er i pakken.

  • dpkg -S FILNAVN - viser hvilke pakker, som FILNAVN stammer fra.

  • dpkg --help - viser hjælp.

For at konfigurere pakker til dit system skal du køre kommandoen dpkg --pending --configure. Det gør, at man får sat de enkelte programmer op til maskinen efter, at pakkerne er blevet installeret.