Se usi Red Hat Enterprise Linux (RHEL) o Fedora, ti ritroverai presto a usare dnf
(o yum
) per installare i pacchetti software. Red Hat Package Manager (RPM) è lo strumento di gestione del software più importante su queste distribuzioni Linux. Questo articolo mostra come sfruttare questo framework per distribuire le tue applicazioni.
Si spera che tu abbia avuto la possibilità di leggere l'articolo di Valentin Bajrami sullo stesso argomento. Ripeterò alcuni degli stessi concetti qui e illustrerò alcuni problemi che potresti incontrare lungo il percorso. Userò anche due esempi più complessi e identificherò alcuni problemi che potresti riscontrare durante il confezionamento di applicazioni native.
In questo articolo viene illustrato come determinare come compilare e creare un pacchetto della propria applicazione nativa per la distribuzione. In un articolo successivo, spiegherò come creare un pacchetto di applicazioni di terze parti che non dispongono di un pacchetto RPM o, se lo hanno, vuoi personalizzarlo.
I prerequisiti includono:
- Hai una conoscenza di base su come utilizzare RPM per interrogare i pacchetti e installare o eliminare i pacchetti. In caso contrario, prima familiarizza con questi concetti e poi torna qui per divertirti.
- Hai installato Make, Git, GCC e Java, poiché ti serviranno per completare gli esercizi qui inclusi. Non è obbligatorio, ma sarebbe bello se ti eserciti mentre vado avanti.
Per installare Make, GCC, Java 11 e Git utilizzando il gestore di pacchetti DNF, esegui:
$ sudo dnf install \
make gcc-10 java-11-openjdk-headless git
Imballa il tuo software utilizzando RPM
Questo articolo utilizza un piccolo progetto open source chiamato jdumpertools per questo passaggio.
Sul tuo terminale Linux, clona jdumpertools
e poi compilalo (hai installato Make e il compilatore GCC, giusto?):
$ git clone [email protected]:josevnz/jdumpertools.git
$ cd jdumpertools
$ make all
$ ls -l jdu jutmp *.so
-rwxrwxr-x 1 josevnz josevnz 32728 Oct 3 16:40 jdu
-rwxrwxr-x 1 josevnz josevnz 32752 Oct 3 16:40 jutmp
-rwxrwxr-x 1 josevnz josevnz 29024 Oct 3 16:40 libjdumpertools.so
Quindi puoi eseguire uno qualsiasi dei programmi generati. Ad esempio, prova jdu
(una versione più semplice del du
comando che stampa i risultati in formato JSON):
$ LD_LIBRARY_PATH=$PWD $PWD/jdu /
[{"partition": "/", "free_space": 462140129280.000000, "total_space": 510405902336.000000}]
Fin qui tutto bene.
Il file jdumpertools.spec in questa directory è il file delle specifiche RPM che controlla come compilare e impacchettare jdumpertools
utilizzando RPM.
Quindi, installa alcuni strumenti di supporto prima di passare alla creazione del file RPM.
Installa blocchi predefiniti RPM
Ottieni gli rpmdevtools
necessari utilità eseguendo:
$ sudo dnf install rpm-build rpmdevtools
Quindi prepara la sandbox per creare RPM utilizzando rpmdevtools
. Non usare mai root per questo passaggio, ma piuttosto il tuo account Linux personale o sviluppatore (passerà il -d
flag di debug):
$ rpmdev-setuptree -d
josevnz /home/josevnz /home/josevnz/.rpmmacros
/home/josevnz/rpmbuild/RPMS /home/josevnz/rpmbuild/SOURCES /home/josevnz/rpmbuild/SPECS
/home/josevnz/rpmbuild/SRPMS /home/josevnz/rpmbuild/BUILD
Ecco una vista migliore:
$ tree ~/rpmbuild
/home/josevnz/rpmbuild
├── BUILD
├── RPMS
├── SOURCES
├── SPECS
└── SRPMS
5 directories, 0 files
In questo momento, devi prestare attenzione solo a due directory:SOURCES
e SPECS
. Spiegherò gli altri più tardi.
C'è anche un nuovo file chiamato ~/.rpmmacros
. Puoi inserire o ignorare alcune macro speciali per evitare attività ripetitive durante la creazione di pacchetti RPM. Questo file è importante perché fissa il rpmbuild
ambiente con la tua home directory.
Imballa la tua applicazione
Per prima cosa, crea un tar
file del codice sorgente in ~/rpmbuild/SOURCES
directory:
VERSION=v0.1
NAME=jdumpertools
TARFILE=$(NAME)-$(VERSION).tar.gz
/usr/bin/tar --exclude-vcs --directory ../ --create --verbose --gzip --file $(HOME)/rpmbuild/SOURCES/$(TARFILE) $(NAME)
Normalmente il tar
contiene script e codice sorgente che compilerai durante il processo di confezionamento.
Quindi, crea una spec
RPM file. Di nuovo, rpmdevtools
fornisce un vantaggio, come questo:
$ rpmdev-newspec ~/rpmbuild/jose-package.spec
/home/josevnz/rpmbuild/jose-package.spec created; type minimal, rpm version >= 4.16.
$ cat ~/rpmbuild/jose-package.spec
Name: jose-package
Version:
Release: 1%{?dist}
Summary:
License:
URL:
Source0:
BuildRequires:
Requires:
%description
%prep
%autosetup
%build
%configure
%make_build
%install
rm -rf $RPM_BUILD_ROOT
%make_install
%files
%license add-license-file-here
%doc add-docs-here
%changelog
* Sun Oct 03 2021 Jose Vicente Nunez <[email protected]>
-
Non preoccuparti se non riesci a dare un senso a questo file ora. Copia il jdumpertools.spec
nel ~/rpmbuild/SPECS
directory:
$ cp -pv jdumpertools.spec ~/rpmbuild/SPECS
E crea un file RPM sorgente e binario:
$ rpmbuild -ba rpmbuild/SPECS/jdumpertools.spec
setting SOURCE_DATE_EPOCH=1609718400
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.kBlIwO
+ umask 022
+ cd /home/josevnz/rpmbuild/BUILD
+ cd /home/josevnz/rpmbuild/BUILD
+ rm -rf jdumpertools
+ /usr/bin/gzip -dc /home/josevnz/rpmbuild/SOURCES/jdumpertools-v0.1.tar.gz
+ /usr/bin/tar -xof -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd jdumpertools
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ RPM_EC=0
[...]
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64
Wrote: /home/josevnz/rpmbuild/SRPMS/jdumpertools-v0.1-1.fc33.src.rpm
Wrote: /home/josevnz/rpmbuild/RPMS/x86_64/jdumpertools-v0.1-1.fc33.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.uEyCyL
+ umask 022
+ cd /home/josevnz/rpmbuild/BUILD
+ cd jdumpertools
+ rm -rf /home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.1-1.fc33.x86_64
+ RPM_EC=0
++ jobs -p
+ exit 0
Il risultato finale sono due file:un RPM sorgente e un RPM binario.
Wrote: /home/josevnz/rpmbuild/SRPMS/jdumpertools-v0.1-1.fc33.src.rpm
Wrote: /home/josevnz/rpmbuild/RPMS/x86_64/jdumpertools-v0.1-1.fc33.x86_64.rpm
Cosa succede durante un'installazione RPM
Quindi cosa succede quando installi ciascuno dei tuoi RPM personalizzati?
- L'installazione dell'RPM sorgente crea il
tar
file e lespec
nel tuorpmbuild
directory. Ciò ti consente di ricompilare l'applicazione, apportare correzioni allespec
RPM file, ecc.$ ls rpmbuild/{SPECS,SOURCES} rpmbuild/SOURCES: jdumpertools-v0.1.tar.gz rpmbuild/SPECS: jdumpertools.spec
- Se installi l'RPM binario, stai effettivamente installando l'applicazione:
$ sudo rpm -ihv ~/rpmbuild/RPMS/x86_64/jdumpertools-v0.1-1.fc33.x86_64.rpm Verifying... ################ [100%] Preparing... ################ [100%] Updating / installing... 1:jdumpertools-v0.1-1.fc33 ################ [100%]
- Conferma che il pacchetto installato sia presente:
$ rpm -qi jdumpertools Name : jdumpertools Version : v0.1 Release : 1.fc33 Architecture: x86_64 Install Date: Sun 03 Oct 2021 06:32:50 PM EDT Group : Unspecified Size : 95002 License : Apache License 2.0 Signature : (none) Source RPM : jdumpertools-v0.1-1.fc33.src.rpm Build Date : Sun 03 Oct 2021 06:27:11 PM EDT Build Host : dmaf5.home URL : https://github.com/josevnz/jdumpertools Summary : Programs that can be used to dump Linux usage data in JSON format. Description : Jdumpertools is a collection of programs used to dump Linux usage data in JSON format to be ingested by other tools. * jdu: Similar to UNIX 'du' command. * jutmp: UTMP database dumper
Nota :I lettori curiosi probabilmente hanno aperto il Makefile
e ho visto un target chiamato rpm
:
rpm: all
test -x /usr/bin/rpmdev-setuptree && /usr/bin/rpmdev-setuptree|| /bin/mkdir -p -v ${HOME}/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
/usr/bin/tar --exclude-vcs --directory ../ --create --verbose --gzip --file $(HOME)/rpmbuild/SOURCES/$(TARFILE) $(NAME)
/usr/bin/rpmbuild -ba jdumpertools.spec
Questa è una comoda scorciatoia per preparare un rpmbuild
sandbox, tar
file dopo che sono stati compilati con make
, e impacchettali usando rpmbuild
comando. Sentiti libero di chiamare make rpm
e guarda cosa succede.
[ Ottieni altri suggerimenti scaricando il foglio cheat per gli script della shell di Bash. ]
Ti ho mostrato i comandi e gli strumenti usati per generare i file RPM, ma ora è il momento di scrivere la spec
RPM file.
Crea un file delle specifiche per gli strumenti jdumper
Lavorare con i file delle specifiche richiede il riempimento di diversi tag di metadati e la descrizione di come compilerai o impacchettarai l'applicazione. Jdumpertools
è una semplice applicazione ANSI C, quindi spacchetta i sorgenti, compilali, copiali in un'area intermedia (~/rpmbuild/BUILDROOT
), quindi impacchettali per la distribuzione.
Per prima cosa, dai un'occhiata al file delle specifiche RPM:
Name: jdumpertools
# TODO: Figure out a better way to update version here and on Makefile
Version: v0.1
Release: 1%{?dist}
Summary: Programs that can be used to dump Linux usage data in JSON format.
License: Apache License 2.0
URL: https://github.com/josevnz/jdumpertools
Source0: %{name}-%{version}.tar.gz
BuildRequires: bash,tar,gzip,rpmdevtools,rpmlint,make,gcc >= 10.2.1
Requires: bash
%global debug_package %{nil}
%description
Jdumpertools is a collection of programs you can use to dump Linux usage data in JSON format to be ingested by other tools.
* jdu: Similar to UNIX 'du' command.
* jutmp: UTMP database dumper
%prep
%setup -q -n jdumpertools
%build
make all
%install
rm -rf %{buildroot}
/usr/bin/mkdir -p %{buildroot}/%{_bindir}
/usr/bin/cp -v -p jdu jutmp %{buildroot}/%{_bindir}
/usr/bin/mkdir -p %{buildroot}/%{_libdir}
/usr/bin/cp -v -p libjdumpertools.so %{buildroot}/%{_libdir}
%clean
rm -rf %{buildroot}
%files
%{_bindir}/jdu
%{_bindir}/jutmp
%{_libdir}/libjdumpertools.so
%license LICENSE
%doc README.md
%changelog
* Mon Jan 4 2021 Jose Vicente Nunez <[email protected]> - 0.1
- First version being packaged
Rivedi cosa è importante qui:
- I metadati, inclusi versione, nome e Source0; puoi usare variabili o macro
- Decomprimi i sorgenti nel
%prep
sezione utilizzando il%setup
macro (la guida RPM contiene molti dettagli sui flag) - Richiede build :Devi elencare le dipendenze necessarie per compilare il pacchetto. Questi non possono essere rilevati dinamicamente.
- % build sezione:Compila con
make
- % installazione sezione:Copia ciò che ti serve per il funzionamento del programma (programma, librerie, ecc.)
- %file sezione:dove puoi specificare se un file è un documento (%doc ), file di licenza (% licenza ), o un file normale
Importante anche:
- Ho disabilitato la creazione del codice di debug durante il confezionamento con
%global debug_package %{nil}
. - Il
changelog
documenta cosa è cambiato con questa nuova versione del pacchetto.
Verifica la presenza di errori nel file delle specifiche con rpmlint
Non vuoi scoprire nel modo più duro che il tuo RPM non è perfetto. Pertanto, è bene verificare la presenza di errori evidenti o modi per migliorare i tuoi RPM:
$ sudo dnf install rpmlint
Ora controlla le spec
RPM file:
$ rpmlint /home/josevnz/rpmbuild/SPECS/jdumpertools.spec
/home/josevnz/rpmbuild/SPECS/jdumpertools.spec: W: invalid-url Source0: jdumpertools-v0.1.tar.gz
0 packages and 1 specfiles checked; 0 errors, 1 warnings.
La documentazione di rpmlint dice che Source0 deve essere un URL ben definito (il valore deve essere un URL HTTP, HTTPS o FTP pubblico valido). Non preoccuparti di questo avviso.
E l'RPM stesso?
$ make rpm
...
$ rpmlint --info ~/rpmbuild/RPMS/x86_64/jdumpertools-v0.2-1.fc33.x86_64.rpm
jdumpertools.x86_64: W: summary-ended-with-dot C Programs that can be used to dump Linux usage data in JSON format.
jdumpertools.x86_64: W: spelling-error %description -l en_US du -> dew, doe, Du
jdumpertools.x86_64: E: description-line-too-long C Jdumpertools is a collection of programs that can be used to dump linux usage data in JSON format, so it can be ingested by other tools.
jdumpertools.x86_64: W: incoherent-version-in-changelog 0.1 ['v0.1-1.fc33', 'v0.1-1']
jdumpertools.x86_64: W: invalid-license Apache License 2.0
jdumpertools.x86_64: W: unstripped-binary-or-object /usr/bin/jdu
jdumpertools.x86_64: W: unstripped-binary-or-object /usr/bin/jutmp
jdumpertools.x86_64: W: unstripped-binary-or-object /usr/lib64/libjdumpertools.so
jdumpertools.x86_64: W: no-soname /usr/lib64/libjdumpertools.so
jdumpertools.x86_64: W: no-manual-page-for-binary jdu
jdumpertools.x86_64: W: no-manual-page-for-binary jutmp
1 packages and 0 specfiles checked; 1 errors, 10 warnings.
Dieci avvisi e un errore. Alcuni sono facili da risolvere:
- La licenza deve essere di un formato specifico
- Le pagine man sono necessarie per i programmi, quindi ne ho scritta una molto semplice con troff
- Includi il soname nella libreria
Dopo le correzioni, rimane un solo avviso:
$ make rpm
...
$ rpmlint --info ~/rpmbuild/RPMS/x86_64/jdumpertools-v0.2-1.fc33.x86_64.rpm
jdumpertools.x86_64: W: spelling-error %description -l en_US du -> dew, doe, Du
The value of this tag appears to be misspelled. Please double-check.
Questo avviso ti avverte che la parola du
sembra essere scritto male. Tuttavia, è solo un riferimento a un comando valido, quindi puoi ignorare l'avviso.
Ora aggiorna l'RPM con la versione migliorata:
$ sudo rpm -Uhv ~/rpmbuild/RPMS/x86_64/jdumpertools-v0.2-1.fc33.x86_64.rpm
Uso il rpm
comando per rendere più ovvio che ho aggiornato il pacchetto da una versione del disco locale anziché da una nuova versione da un repository. Se preferisci, puoi fare la stessa cosa con dnf
:
$ sudo dnf install --upgrade \
~/rpmbuild/RPMS/x86_64/jdumpertools-v0.2-1.fc33.x86_64.rpm
Cosa hai imparato e cosa ti aspetta
All'inizio il software di packaging con RPM sembra intimidatorio, ma con un po' di pazienza ci arriverai in men che non si dica. Quando riscontri problemi, troverai anche i modi adeguati per migliorare il tuo codice. Di seguito sono riportate alcune risorse e consigli finali:
- Fatti un grande favore e ricevi una copia della Guida all'imballaggio RPM scritta da Adam Miller, Maxim Svistunov e Marie Doleželová. È molto completo e ben organizzato. Seriamente, fallo ora; è così buono.
- Anche la guida ufficiale all'imballaggio RPM e la guida RPM Fedora sono piene di dettagli; tienili un segnalibro lontano.
- Usa rpmlint. Rimarrai sorpreso da quante piccole cose puoi prendere e riparare prima di spedire i tuoi pacchi RPM.
- Non abbastanza? Fedora ha un elenco di trucchi che puoi usare per creare pacchetti di software.
- Ancora curioso? Dovresti assolutamente dare un'occhiata alle linee guida per l'imballaggio di RPM.