一、前言
在linux上安裝軟件和模塊很多都是通過rpm包安裝的,非常的方便。如果多個主機安裝文件和腳本也能用rpm包的方式就好了,節省時間和精力,正好看到了一篇文章,本地構建rpm包,試着學了下,所以寫下這篇博客記錄構建過程,該博客使用到的主機為Centos7。
二、准備
1.首先,打開一個終端會話,使用root用戶創建可用於此項目的普通用戶 “student”,並為該用戶設置密碼。
[root@localhost ~]# useradd student [root@localhost ~]# passwd student Changing password for user student. New password: Retype new password: passwd: all authentication tokens updated successfully.
2.構建 rpm 包需要 rpm-build
包
[root@localhost ~]# yum install rpm-build -y
3.使用student用戶打開另一個終端會話並使用。下載教程用的tar包,
https://pan.baidu.com/s/1b_G5hEi61BNAD9vcOpSykw
提取碼:5w9y
此 tar 包包含將由最終 rpm
程序安裝的所有文件和 Bash 腳本。 還有一個完整的 spec 文件,你可以使用它來構建 rpm。使用rz命令或者其他工具上傳到home目錄下,解壓縮 tar 包。
[student@localhost ~]$ cd ; tar -xvf utils.tar ./ ./development/ ./development/scripts/ ./development/scripts/create_motd ./development/scripts/die ./development/scripts/mymotd ./development/scripts/sysdata ./development/spec/ ./development/spec/utils.spec ./development/license/ ./development/license/Copyright.and.GPL.Notice.txt ./development/license/GPL_LICENSE.txt
使用 tree
命令驗證 ~/development
的目錄結構和包含的文件,如下所示:
[student@localhost ~]$ tree development/ development/ ├── license │ ├── Copyright.and.GPL.Notice.txt │ └── GPL_LICENSE.txt ├── scripts │ ├── create_motd │ ├── die │ ├── mymotd │ └── sysdata └── spec └── utils.spec
mymotd
腳本創建一個發送到標准輸出的“當日消息”數據流。 create_motd
腳本運行 mymotd
腳本並將輸出重定向到 /etc/motd
文件。 此文件用於向使用 SSH 遠程登錄的用戶顯示每日消息。
die
腳本將 kill
命令包裝在一些代碼中,這些代碼可以找到與指定字符串匹配的運行程序並將其終止。 它使用 kill -9
來確保 kill
命令一定會執行。
sysdata
腳本可以顯示有關計算機硬件,還有已安裝的 Linux 版本,所有已安裝的軟件包以及硬盤驅動器元數據等數萬行數據。
三、創建構建目錄結構
rpmbuild
命令需要非常特定的目錄結構。 所以需要手動創建目錄
[student@localhost ~]$ tree rpmbuild/ rpmbuild/ ├── RPMS │ └── noarch ├── SOURCES ├── SPECS └── SRPMS
四、檢查 spec 文件
每個 spec 文件都有許多部分,其中一些部分可能會被忽視或省略,取決於 rpm 構建的具體情況。 這個特定的 spec 文件不是工作所需的最小文件的示例,但它是一個包含不需要編譯的文件的中等復雜 spec 文件的很好例子。 如果需要編譯,它將在 %build
部分中執行,該部分在此 spec 文件中省略掉了,因為它不是必需的。
1.前言
這是 spec 文件中唯一沒有標簽的部分。 它包含運行命令 rpm -qi [Package Name]
時看到的大部分信息。 每個數據都是一行,由標簽和標簽值的文本數據組成。
############################################################################### # Spec file for utils ################################################################################ # Configured to be built by user student or other non-root user ################################################################################ # Summary: Utility scripts for testing RPM creation Name: utils Version: 1.0.0 Release: 1 License: GPL URL: http://www.both.org Group: System Packager: David Both Requires: bash Requires: screen Requires: mc Requires: dmidecode BuildRoot: ~/rpmbuild/ # Build with the following syntax: # rpmbuild --target noarch -bb utils.spec
Summary
標簽是包的簡短描述。
Name
、Version
和 Release
標簽用於創建 rpm 文件的名稱,如 utils-1.00-1.rpm
。通過增加發行版號碼和版本號,你可以創建 rpm 包去更新舊版本的。
License
標簽定義了發布包的許可證。我總是使用 GPL 的一個變體。指定許可證對於澄清包中包含的軟件是開源的這一事實非常重要。這也是我將 License
和 GPL
語句包含在將要安裝的文件中的原因。
URL
通常是項目或項目所有者的網頁。
Group
標簽很有趣,通常用於 GUI 應用程序。 Group
標簽的值決定了應用程序菜單中的哪一組圖標將包含此包中可執行文件的圖標。與 Icon
標簽(我們此處未使用)一起使用時,Group
標簽允許在應用程序菜單結構中添加用於啟動程序的圖標和所需信息。
Packager
標簽用於指定負責維護和創建包的人員或組織。
Requires
語句定義此 rpm 包的依賴項。每個都是包名。如果其中一個指定的軟件包不存在,將嘗試在 /etc/yum.repos.d
中定義的某個已定義的存儲庫中找到它,如果存在則安裝它。如果 DNF 找不到一個或多個所需的包,它將拋出一個錯誤,指出哪些包丟失並終止。
BuildRoot
行指定頂級目錄,rpmbuild
工具將在其中找到 spec 文件,並在構建包時在其中創建臨時目錄。完成的包將存儲在我們之前指定的 noarch
子目錄中。
注釋顯示了構建此程序包的命令語法,包括定義了目標體系結構的 –target noarch
選項。因為這些是 Bash 腳本,所以它們與特定的 CPU 架構無關。如果省略此選項,則構建將選用正在執行構建的 CPU 的體系結構。
rpmbuild
程序可以針對許多不同的體系結構,並且使用 --target
選項允許我們在不同的體系結構主機上構建特定體系結構的包,其具有與執行構建的體系結構不同的體系結構。所以我可以在 x86_64 主機上構建一個用於 i686 架構的軟件包,反之亦然。
如果你有自己的網站,請將打包者的名稱更改為你自己的網站。
2.描述部分(%description
)
spec 文件的 %description
部分包含 rpm 包的描述。 它可以很短,也可以包含許多信息。 我們的 %description
部分相當簡潔。
%description A collection of utility scripts for testing RPM creation.
3.准備部分(%prep
)
%prep
部分是在構建過程中執行的第一個腳本。 在安裝程序包期間不會執行此腳本。
這個腳本只是一個 Bash shell 腳本。 它准備構建目錄,根據需要創建用於構建的目錄,並將相應的文件復制到各自的目錄中。 這將包括作為構建的一部分的完整編譯所需的源代碼。
$RPM_BUILD_ROOT
目錄表示已安裝系統的根目錄。 在 $RPM_BUILD_ROOT
目錄中創建的目錄是真實文件系統中的絕對路徑,例如 /user/local/share/utils
、/usr/local/bin
等。
對於我們的包,我們沒有預編譯源,因為我們的所有程序都是 Bash 腳本。 因此,我們只需將這些腳本和其他文件復制到已安裝系統的目錄中。
請注意,本節末尾的 exit
語句是必需的。
4.文件部分(%files
)
spec 文件的 %files
這一部分定義了要安裝的文件及其在目錄樹中的位置。 它還指定了要安裝的每個文件的文件屬性(%attr
)以及所有者和組所有者。 文件權限和所有權是可選的,但我建議明確設置它們以消除這些屬性在安裝時不正確或不明確的任何可能性。 如果目錄尚不存在,則會在安裝期間根據需要創建目錄。
%files
%attr(0744, root, root) /usr/local/bin/*
%attr(0644, root, root) /usr/local/share/utils/*
4.1 安裝前(%pre
)
在我們測試項目的 spec 文件中,此部分為空。 這應該放置那些需要 rpm 中的文件安裝前執行的腳本。
4.2 安裝后(%post
)
spec 文件的這一部分是另一個 Bash 腳本。 這個在文件安裝后運行。 此部分幾乎可以是你需要或想要的任何內容,包括創建文件、運行系統命令以及重新啟動服務以在進行配置更改后重新初始化它們。 我們的 rpm 包的 %post
腳本執行其中一些任務。
%post ################################################################################ # Set up MOTD scripts # ################################################################################ cd /etc # Save the old MOTD if it exists if [ -e motd ] then cp motd motd.orig fi # If not there already, Add link to create_motd to cron.daily cd /etc/cron.daily if [ ! -e create_motd ] then ln -s /usr/local/bin/create_motd fi # create the MOTD for the first time /usr/local/bin/mymotd > /etc/motd
4.3 卸載后(%postun
)
此部分包含將在卸載 rpm 軟件包后運行的腳本。 使用 rpm
或 dnf
刪除包會刪除文件部分中列出的所有文件,但它不會刪除安裝后部分創建的文件或鏈接,因此我們需要在本節中處理。
此腳本通常由清理任務組成,只是清除以前由 rpm
安裝的文件,但 rpm 本身無法完成清除。 對於我們的包,它包括刪除 %post
腳本創建的鏈接並恢復 motd 文件的已保存原件。
%postun # remove installed files and links rm /etc/cron.daily/create_motd # Restore the original MOTD if it was backed up if [ -e /etc/motd.orig ] then mv -f /etc/motd.orig /etc/motd fi
4.4 清理(%clean
)
這個 Bash 腳本在 rpm 構建過程之后開始清理。 下面 %clean
部分中的兩行刪除了 rpm-build
命令創建的構建目錄。 在許多情況下,可能還需要額外的清理。
%clean rm -rf $RPM_BUILD_ROOT/usr/local/bin rm -rf $RPM_BUILD_ROOT/usr/local/share/utils
4.5 變更日志(%changelog
)
此可選的文本部分包含 rpm 及其包含的文件的變更列表。最新的變更記錄在本部分頂部。使用你自己的姓名和電子郵件地址替換標題行中的數據。
%changelog * Wed Aug 29 2018 Your Name <Youremail@yourdomain.com> - The original package includes several useful scripts. it is primarily intended to be used to illustrate the process of building an RPM.
五、構建RPM
spec 文件必須位於 rpmbuild
目錄樹的 SPECS
目錄中。 我發現最簡單的方法是創建一個指向該目錄中實際 spec 文件的鏈接,以便可以在開發目錄中對其進行編輯,而無需將其復制到 SPECS
目錄。 將 SPECS
目錄設為當前工作目錄,然后創建鏈接。
cd ~/rpmbuild/SPECS/
ln -s ~/development/spec/utils.spec
運行以下命令以構建 rpm。 如果沒有錯誤發生,只需要花一點時間來創建 rpm。
rpmbuild --target noarch -bb utils.spec
檢查 ~/rpmbuild/RPMS/noarch
目錄以驗證新的 rpm 是否存在。
[student@localhost ~]$ cd rpmbuild/RPMS/noarch/ [student@localhost noarch]$ ll total 20 -rw-rw-r--. 1 student student 19848 Feb 20 10:21 utils-1.0.0-1.noarch.rpm [student@localhost noarch]$
五、測試RPM
以 root 用戶身份安裝 rpm 以驗證它是否正確安裝並且文件是否安裝在正確的目錄中。 rpm 的確切名稱將取決於你在前言部分中標簽的值,但如果你使用了示例中的值,則 rpm 名稱將如下面的示例命令所示:.
[root@localhost noarch]# rpm -ivh utils-1.0.0-1.noarch.rpm Preparing... ################################# [100%] Updating / installing... 1:utils-1.0.0-1 ################################# [100%] [root@localhost noarch]#
檢查 /usr/local/bin
以確保新文件存在。 你還應驗證是否已創建 /etc/cron.daily
中的 create_motd
鏈接。
使用 rpm -q --changelog utils
命令查看更改日志。 使用 rpm -ql utils
命令(在 ql
中為小寫 L
)查看程序包安裝的文件。
[root@localhost bin]# rpm -q --changelog utils * Wed Aug 29 2018 <Youremail@yourdomain.com> - The original package includes several useful scripts. it is primarily intended to be used to illustrate the process of building an RPM. [root@localhost bin]# rpm -ql utils /usr/local/bin/create_motd /usr/local/bin/die /usr/local/bin/mymotd /usr/local/bin/sysdata /usr/local/share/utils/Copyright.and.GPL.Notice.txt /usr/local/share/utils/GPL_LICENSE.txt /usr/local/share/utils/utils.spec
用ssh工具ssh虛擬機,效果如下。
刪除包
rpm -e utils