FPM یک wrapper قدرتمند است که به شما امکان می دهد بسته هایی را برای چندین برنامه در چندین سیستم عامل ایجاد کنید.

در این آموزش به شما نشان خواهم داد که چگونه می توانید برخی از بسته بندی های خسته کننده برنامه های شخص ثالث را جایگزین کنید.

آنچه برای تکمیل این آموزش نیاز دارید

  • یک توزیع لینوکس (من از فدورا استفاده کردم اما با هر چیزی کار می کند)
  • امتیازات بالا (اگر می خواهید بسته های خود را نصب کنید)

وقتی مدیر بسته شما به اندازه کافی ساده نیست

اغلب اوقات، شما می خواهید کنترل نهایی را بر روش بسته بندی یک برنامه داشته باشید. اما چند مورد وجود دارد که ممکن است بیش از حد انجام شود:

  1. برنامه شخص ثالث به اندازه کافی ساده یا کوچک است که یک تار برای نصب آن کافی است. با این حال، می‌خواهید از مزایای ارتقاء و بازگشت، مانند مواردی که توسط RPM ارائه می‌شود، لذت ببرید.
  2. شما نیاز دارید یا می خواهید یک برنامه را از یک فرمت (مثلاً .tar.gz) به Debian ‘.deb’ یا RPM بسته بندی کنید.
  3. شما باید چندین برنامه را بسته بندی کنید که فقط در آن ارائه می شود Source فرمت یا باینری های از پیش بسته بندی شده، مانند هنگام ارتقاء سیستم عامل. و شما نمی خواهید یک ابد را صرف بسته بندی مجدد برنامه های شخص ثالث کنید.

چگونه یک برنامه موجود را به روش قدیمی بسته بندی کنیم

من یک برنامه نمایشی کوچک نوشتم که حقایق سیستم (مانند استفاده از دیسک) را با فرمت JSON حذف می کند، به نام jdumpertools. برنامه بسیار ساده است، به زبان C نوشته شده است و دارای یک فایل مشخصات RPM است که می توانید از آن برای بسته بندی نرم افزار استفاده کنید.

برای ایجاد RPM چند مرحله دستی لازم است:

  1. دانلود توزیع منبع (یا باینری): کلون git https://github.com/josevnz/jdumpertools.git
  2. فایل مشخصات RPM را آماده کنید، که باید از کامپایل (یا فقط بسته بندی) نرم افزار و همچنین مکان نصب مراقبت کند.
  3. فایل مشخصات را پر کنید، خطاهای رایج را برطرف کنید

پس بیایید ببینیم چگونه jdumbertoolsفایل مشخصات RPM کار می کند.

ابتدا به فایل مشخصات نگاهی بیندازید:

Name:           jdumpertools
# TODO: Figure out a better way to update version here and روی Makefile
%global major 0
Version:        v%{major}.2
Release:        1%{?dist}
Summary:        Programs that can be used to dump Linux usage data in JSON format

License:        ASL 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 that can be used to dump
linux usage data in JSON format, so it can be ingested by other tools.

* jdu: Similar to UNIX '/bin/du' command.
* jutmp: UTMP database dumper

%prep
%setup -q -n jdumpertools

%build
make all

%install

/usr/bin/mkdir -p %{buildroot}/%{_bindir}
/usr/bin/mkdir -p %{buildroot}/%{_mandir}/man8
/usr/bin/cp -v -p jdu jutmp %{buildroot}/%{_bindir}
/usr/bin/cp -v -p jdu.1 jutmp.1 %{buildroot}/%{_mandir}/man8/
/usr/bin/gzip %{buildroot}/%{_mandir}/man8/*
/usr/bin/mkdir -p %{buildroot}/%{_libdir}
/usr/bin/cp -v -p libjdumpertools.so.%{major} %{buildroot}/%{_libdir}
/usr/bin/strip %{buildroot}/%{_bindir}/{jdu,jutmp}
/usr/bin/strip %{buildroot}/%{_libdir}/*

%clean
rm -rf %{buildroot}

%files
%{_bindir}/jdu
%{_bindir}/jutmp
%{_libdir}/libjdumpertools.so.%{major}
%{_libdir}/libjdumpertools.so
%license LICENSE
%doc README.md
%doc %{_mandir}/man8/jdu.1.gz
%doc %{_mandir}/man8/jutmp.1.gz


%changelog
* Sun Oct  3 2021 Jose Vicente Nunez <kodegeek.com@protonmail.com> - v0.2-1
- Applied fixes from rpmlint: man page, typos روی spec file, striped binaries, etc.
* Mon Jan  4 2021 Jose Vicente Nunez <kodegeek.com@protonmail.com> - v0.1-1
- First version being packaged

و حالا بیایید آن را بسازیم:

[josevnz@dmaf5 jdumpertools]$ sudo dnf install -y rpmdevtools rpmlint
...
[josevnz@dmaf5 test]$ git clone https://github.com/josevnz/jdumpertools.git
Cloning into 'jdumpertools'...
remote: Enumerating objects: 228, done.
remote: Counting objects: 100% (228/228), done.
remote: Compressing objects: 100% (137/137), done.
remote: Total 228 (delta 132), reused 157 (delta 79), pack-reused 0
Receiving objects: 100% (228/228), 3.15 MiB | 9.67 MiB/s, done.
Resolving deltas: 100% (132/132), done.

[josevnz@dmaf5 test]$ cd jdumpertools/
[josevnz@dmaf5 jdumpertools]$ rpmbuild -ba jdumpertools.spec
...
+ exit 0
Provides: jdumpertools = v0.2-1.fc37 jdumpertools(x86-64) = v0.2-1.fc37 libjdumpertools.so()(64bit)
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Requires: libc.so.6()(64bit) libc.so.6(GLIBC_2.2.5)(64bit) libc.so.6(GLIBC_2.3)(64bit) libjdumpertools.so()(64bit) rtld(GNU_HASH)
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.2-1.fc37.x86_64
Wrote: /home/josevnz/rpmbuild/SRPMS/jdumpertools-v0.2-1.fc37.src.rpm
Wrote: /home/josevnz/rpmbuild/RPMS/x86_64/jdumpertools-v0.2-1.fc37.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.42keBq
+ umask 022
+ cd /home/josevnz/rpmbuild/BUILD
+ cd jdumpertools
+ rm -rf /home/josevnz/rpmbuild/BUILDROOT/jdumpertools-v0.2-1.fc37.x86_64
+ RPM_EC=0
++ jobs -p
+ exit 0
Executing(rmbuild): /bin/sh -e /var/tmp/rpm-tmp.aZjb6s
+ umask 022
+ cd /home/josevnz/rpmbuild/BUILD
+ rm -rf jdumpertools jdumpertools.gemspec
+ RPM_EC=0
++ jobs -p
+ exit 0
...
[josevnz@dmaf5 jdumpertools]$ ls -l $HOME/rpmbuild/RPMS/x86_64/jdumpertools-v0.2-1.fc37.x86_64.rpm
-rw-r--r--. 1 josevnz josevnz 22118 Jun  2 14:03 /home/josevnz/rpmbuild/RPMS/x86_64/jdumpertools-v0.2-1.fc37.x86_64.rpm

پیشنهاد می‌کنیم بخوانید:  چگونه یک محیط توسعه جنگو راه اندازی کنیم

سپس RPM را مانند سایر RPM نصب می کنید:

[josevnz@dmaf5 jdumpertools]$ sudo dnf install -y $HOME/rpmbuild/RPMS/x86_64/jdumpertools-v0.2-1.fc37.x86_64.rpm
Last metadata expiration check: 1:36:46 ago روی Fri 02 Jun 1402 12:30:31 PM EDT.
Dependencies resolved.
=================================================================================================================================
 Package                         Architecture              Version                         Repository                       Size
=================================================================================================================================
Installing:
 jdumpertools                    x86_64                    v0.2-1.fc37                     @commandline                     22 k

Transaction Summary
=================================================================================================================================
Install  1 Package

Total size: 22 k
Installed size: 57 k
Downloading Packages:
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                         1/1 
  Installing       : jdumpertools-v0.2-1.fc37.x86_64                                                                         1/1 
  Running scriptlet: jdumpertools-v0.2-1.fc37.x86_64                                                                         1/1 
  Verifying        : jdumpertools-v0.2-1.fc37.x86_64                                                                         1/1 

Installed:
  jdumpertools-v0.2-1.fc37.x86_64                                                                                                

Complete!

این وحشتناک نیست، به خصوص اگر قصد دارید به روز رسانی کنید – اما آیا می توانیم این کار را به روشی ساده تر انجام دهیم؟

روش نصب FPM

سند شروع ساده ترین مرجعی است که می توانید برای راه اندازی FPM به آن مراجعه کنید.

ابتدا برخی از وابستگی ها را نصب می کنید، به عنوان مثال در فدورا:

[josevnz@dmaf5 jdumpertools]$ sudo dnf install -y gem
[josevnz@dmaf5 jdumpertools]$ sudo dnf install -y rpm-build squashfs-tools

و سپس خود FPM را نصب خواهید کرد:

[josevnz@dmaf5 jdumpertools]$ gem install --user-install fpm
Fetching insist-1.0.0.gem
Fetching clamp-1.0.1.gem
Fetching stud-0.0.23.gem
Fetching rexml-3.2.5.gem
Fetching mustache-0.99.8.gem
Fetching dotenv-2.8.1.gem
Fetching cabin-0.9.0.gem
Fetching pleaserun-0.0.32.gem
Fetching fpm-1.15.1.gem
Fetching backports-3.24.1.gem
...
Done installing documentation for stud, rexml, mustache, insist, dotenv, clamp, cabin, pleaserun, backports, arr-pm, fpm after 5 seconds
11 gems installed

روش بسته بندی jdumpertools به عنوان یک RPM، بدون فایل مشخصات

خوب، ما به چند فایل برای بسته بندی نیاز داریم. این توزیع همراه با الف است Makefile، به آسانی مانند پای ما انجام می دهیم:

[josevnz@dmaf5 jdumpertools]$ make
gcc -Wall -g -Og -Wextra -Werror -Werror=format-security -std=c11   -DJDUMPERTOOLS_VERSION=v0.2 -fPIC jdumpertools.h jdumpertools.c -I /home/josevnz/test/jdumpertools -shared -Wl,-soname,libjdumpertools.so -o libjdumpertools.so.0
gcc jdumpertools.h jdu.c libjdumpertools.so.0 -Wall -g -Og -Wextra -Werror -Werror=format-security -std=c11   -DJDUMPERTOOLS_VERSION=v0.2 -L /home/josevnz/test/jdumpertools -l jdumpertools -o jdu
gcc jdumpertools.h jutmp.c -Wall -g -Og -Wextra -Werror -Werror=format-security -std=c11   -DJDUMPERTOOLS_VERSION=v0.2 -L /home/josevnz/test/jdumpertools -l jdumpertools -o jutmp
...
[josevnz@dmaf5 jdumpertools]$ ls
CODE_OF_CONDUCT.md  INSTALL.md  jdu.c           jdumpertools.spec  jutmp.c               Makefile        SECURITY.md
CONTRIBUTING.md     jdu         jdumpertools.c  jutmp              libjdumpertools.so.0  mazinger-z.png
Dockerfile          jdu.1       jdumpertools.h  jutmp.1            LICENSE               README.md
[josevnz@dmaf5 jdumpertools]$ fpm -t rpm -s dir --name jdumpertools --rpm-autoreq --rpm-os linux --rpm-summary 'Programs that can be used to dump Linux usage data in JSON format' --license 'ASL 2.0' --version v0.21 --depends bash --maintainer 'Jose Vicente Nunez <kodegeek.com@protonmail.com>' --url https://github.com/josevnz/jdumpertools jdu=/usr/bin/jdu jutmp=/usr/bin/jutmp jdu.1=/usr/share/man/man1/jdu.1.gz jutmp.1=/usr/share/man/man8/jutmp.1.gz
Created package {:path=>"jdumpertools-v0.21-1.x86_64.rpm"}

بنابراین هیچ فایل مشخصاتی وجود ندارد و ما یک RPM داریم.

اگر بخواهم بسته هایی برای توزیع های دیگر ایجاد کنم چه می شود؟ فقط باید چند تغییر ایجاد کنم روی خط فرمان:

بسته دبیان:

[josevnz@dmaf5 jdumpertools]$ fpm -t deb -s dir --name jdumpertools --rpm-autoreq --rpm-os linux --rpm-summary 'Programs that can be used to dump Linux usage data in JSON format' --license 'ASL 2.0' --version v0.21 --depends bash --maintainer 'Jose Vicente Nunez <kodegeek.com@protonmail.com>' --url https://github.com/josevnz/jdumpertools jdu=/usr/bin/jdu jutmp=/usr/bin/jutmp jdu.1=/usr/share/man/man1/jdu.1.gz jutmp.1=/usr/share/man/man8/jutmp.1.gz
Debian 'Version' field needs to start with a digit. I was provided 'v0.21' which seems like it just has a 'v' prefix to an otherwise-valid Debian version, I'll remove the 'v' for you. {:level=>:warn}
Created package {:path=>"jdumpertools_0.21_amd64.deb"}

پیشنهاد می‌کنیم بخوانید:  جاوا اسکریپت: روش بدست آوردن تعداد عناصر در یک آرایه از آرایه برای ذخیره مجموعه مرتب شده از مقادیر استفاده می شود. این مقادیر می‌توانند ترکیبی از یک نوع داده یا انواع داده‌های متعدد - اعداد صحیح، شناور، رشته‌ها، بولی، اشیاء و موارد دیگر باشند. بدست آوردن تعداد عناصر در یک آرایه با جاوا اسکریپت یک عملیات رایج است...

اسکریپت خود استخراجی:

[josevnz@dmaf5 jdumpertools]$ fpm -t sh -s dir --name jdumpertools --rpm-autoreq --rpm-os linux --rpm-summary 'Programs that can be used to dump Linux usage data in JSON format' --license 'ASL 2.0' --version v0.21 --depends bash --maintainer 'Jose Vicente Nunez <kodegeek.com@protonmail.com>' --url https://github.com/josevnz/jdumpertools jdu=/usr/bin/jdu jutmp=/usr/bin/jutmp jdu.1=/usr/share/man/man1/jdu.1.gz jutmp.1=/usr/share/man/man8/jutmp.1.gz
Created package {:path=>"jdumpertools.sh"}

فایل tar:

[josevnz@dmaf5 jdumpertools]$ fpm -t tar -s dir --name jdumpertools --rpm-autoreq --rpm-os linux --rpm-summary 'Programs that can be used to dump Linux usage data in JSON format' --license 'ASL 2.0' --version v0.21 --depends bash --maintainer 'Jose Vicente Nunez <kodegeek.com@protonmail.com>' --url https://github.com/josevnz/jdumpertools jdu=/usr/bin/jdu jutmp=/usr/bin/jutmp jdu.1=/usr/share/man/man1/jdu.1.gz jutmp.1=/usr/share/man/man8/jutmp.1.gz
Created package {:path=>"jdumpertools.tar"}

این در حال حاضر بسیار راحت است. اکنون می‌خواهم مورد دیگری را برای FPM به شما نشان دهم.

روش بسته بندی مجدد نرم افزارهای موجود

بگویید که می خواهید یک ماژول CPAN را که RPM ندارد توزیع کنید. می توانید زمان با کیفیتی را صرف کنید یا می توانید از FPM برای انجام کار برای شما استفاده کنید.

ابتدا، اجازه دهید یک وابستگی جدید برای فدورا نصب کنیم:

[josevnz@dmaf5 jdumpertools]$ sudo dnf install -y perl-App-cpanminus

و سپس بیایید RPM خود را بسازیم

[josevnz@dmaf5 jdumpertools]$ fpm -t rpm -s cpan Archive::Tar
Created package {:path=>"perl-Archive-Tar-3.02-1.noarch.rpm"}

کار کرد؟

[josevnz@dmaf5 jdumpertools]$ rpm -qil perl-Archive-Tar-3.02-1.noarch.rpm
Name        : perl-Archive-Tar
Version     : 3.02
Release     : 1
Architecture: noarch
Install Date: (not installed)
Group       : default
Size        : 177677
License     : perl_5
Signature   : (none)
Source RPM  : perl-Archive-Tar-3.02-1.src.rpm
Build Date  : Fri 02 Jun 1402 04:36:45 PM EDT
Build Host  : dmaf5
Relocations : / 
Packager    : <josevnz@dmaf5>
Vendor      : Jos Boumans <kane[at]cpan.org>
URL         : http://example.com/no-uri-given
Summary     : Manipulates TAR archives
Description :
Manipulates TAR archives
/usr/local/bin/ptar
/usr/local/bin/ptardiff
/usr/local/bin/ptargrep
/usr/local/share/man/man1/ptar.1
/usr/local/share/man/man1/ptardiff.1
/usr/local/share/man/man1/ptargrep.1
/usr/local/share/man/man3/Archive::Tar.3pm
/usr/local/share/man/man3/Archive::Tar::File.3pm
/usr/local/share/perl5/5.36/Archive/Tar.pm
/usr/local/share/perl5/5.36/Archive/Tar/Constant.pm
/usr/local/share/perl5/5.36/Archive/Tar/File.pm

اکنون می خواهم به شما نشان دهم که چگونه ماژول clickhouse-driver را از PyPi بسته بندی کنید.

[josevnz@dmaf5 jdumpertools]$ fpm -t rpm -s python 'clickhouse-driver'
Created package {:path=>"python-clickhouse-driver-0.2.6-1.x86_64.rpm"}

بگویید که اکنون می خواهید یک RPM برای OpenJDK 17 ایجاد کنید. مشکلی نیست، فایل tar را دریافت کنید و با کمک کمی آن را بسته بندی کنید:

[josevnz@dmaf5 jdumpertools]$ curl --fail --location --remote-name https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.7%2B7/OpenJDK17U-jdk_x64_linux_hotspot_17.0.7_7.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  182M  100  182M    0     0  10.9M      0  0:00:16  0:00:16 --:--:-- 11.1M
[josevnz@dmaf5 jdumpertools]$ fpm -t rpm -s tar --url 'https://adoptium.net/' --description 'Eclipse Temurin is the name of the OpenJDK distribution from Adoptium' --version '17.0.7+7' --prefix /usr/local/openjdk OpenJDK17U-jdk_x64_linux_hotspot_17.0.7_7.tar.gz
[josevnz@dmaf5 jdumpertools]$ rpm -qil OpenJDK17U-jdk_x64_linux_hotspot_17-17.0.7+7-1.x86_64.rpm
Name        : OpenJDK17U-jdk_x64_linux_hotspot_17
Version     : 17.0.7+7
Release     : 1
Architecture: x86_64
Install Date: (not installed)
Group       : default
Size        : 329508762
License     : unknown
Signature   : (none)
Source RPM  : OpenJDK17U-jdk_x64_linux_hotspot_17-17.0.7+7-1.src.rpm
Build Date  : Fri 02 Jun 1402 05:05:05 PM EDT
Build Host  : dmaf5
Relocations : /usr/local/openjdk 
Packager    : <josevnz@dmaf5>
Vendor      : none
URL         : https://adoptium.net/
Summary     : Eclipse Temurin is the name of the OpenJDK distribution from Adoptium
Description :
Eclipse Temurin is the name of the OpenJDK distribution from Adoptium
/usr/local/openjdk/jdk-17.0.7+7/NOTICE
/usr/local/openjdk/jdk-17.0.7+7/bin/jar
/usr/local/openjdk/jdk-17.0.7+7/bin/jarsigner
/usr/local/openjdk/jdk-17.0.7+7/bin/java
...

من می‌توانم ادامه دهم، اما فکر می‌کنم شما این ایده را دارید که چقدر می‌توانید با FPM انجام دهید.

بعد چه می شود؟

ما چند مورد استفاده مهم را پوشش دادیم، اما این ابزار چیزهای بیشتری برای ارائه دارد:

  • FPM کاربردهای زیادی دارد، از جمله تبدیل بسته های موجود از فرمت های دیگر به فرمت مورد نظر شما.
  • FPM همچنین از فایل های پیکربندی پشتیبانی می کند. اگر اغلب از آن استفاده می کنید، باید روش استفاده از یک فایل پیکربندی برای FPM را به جای استفاده از خط فرمان طولانی بخوانید.
  • همچنین می توانید FPM را از داخل a اجرا کنید container، برای جلوگیری از نصب وابستگی ها.
  • اگر در مورد روش اجرای باینری های jumpertools کنجکاو هستید، می توانید نگاهی به README.md از مخزن بیندازید.