一、RPM包介紹
對RPM包有五種基本的操作功能:安裝、卸載、升級、查詢和驗證。
linux軟體包分為兩大類:
1. 二進位類包:包括rpm安裝包(一般分為i386和x86_64這幾種)
2. 源碼類包:源碼包和開發包(.src.rpm)都是屬於此類
有時候為了方便源碼包的安裝,和我們自己訂製軟體包的需求,我們會把一些源碼包按照我們的需求來做成rpm包,當有源碼包就可以直接編譯得到二進位安裝和其他任意包,另外,我們也可以使用rpm包來打包一些檔案或者自己開發的一套軟體,使用rpm有資料庫協助軟體升級、檔案檢驗,對於使用者,提供rpm包還是最值的方法。spec檔案是製作rpm包最核心的部分,rpm包的製作就是根據spec檔案來實現的。在制定rpm包的時候最好不要使用管理員進行,因為管理員權限過大,如果一個命令寫錯了,結果可能就是災難性的,而製作一個rpm包普通使用者完全可以實現。製作rpm包需要使用rpmbuild工具來操作,如果沒有安裝rpmbuild命令的話,使用yum install rpm-build進行安裝
二、RPM打包環境介紹及配置
1. 環境介紹及配置
使用rpmbuild工具打包,需要有一個”工作車間”,”工作車間“需要以下六個目錄,如下表:
目錄 作用
BUIILD 原始碼解壓以後存放的位置,在這個目錄進行編譯操作。
RPMS 製作完成後的rpm包存放位置,rpm包會放在對應平台類型的子目錄下。
SOURCES 製作rpm包的源材料檔案,包括源碼包,其它的各種
SPECS 存放spec檔案的位置,尾碼名一般寫為.spec
SRPMS 存放src格式的rpm包位置
BUILDROOT 假根,使用install臨時安裝到這個目錄,把這個目錄當成根來使用。
如果是使用redhat系統的話,這幾個目錄可以在/usr/local/src目錄下,但是在centos上是沒有這幾個目錄的,所以需要自己建立,一般使用普通使用者目錄,對這幾個目錄進行建立,而這幾個目錄的位置,則由宏來控制。
rpmbulid –showrc 顯示所有的宏,以底線開頭,一個底線:定義環境的使用方式;二個底線:通常定義的是命令。為什麼要定義宏呢,因為不同的系統,命令的存放位置可能不同,所以通過宏的定義找到命令的真正存放位置。
查看預設的工作車間,只要我們修改了這個宏,我們就可以自訂工作車間了。
[zhanghong@localhost ~]$ rpmbuild --showrc | grep topdir
-14: _builddir %{_topdir}/BUILD
-14: _buildrootdir %{_topdir}/BUILDROOT
-14: _rpmdir %{_topdir}/RPMS
-14: _sourcedir %{_topdir}/SOURCES
-14: _specdir %{_topdir}/SPECS
-14: _srcrpmdir %{_topdir}/SRPMS
-14: _topdir /home/zhanghong/rpmbuild/
可以發現,這幾個工作車間目錄都是在%{_topdir}這個巨集目錄下的,我自訂_topdir目錄為/home/zhanghong/rpmbuild這個目錄,然後我使用zhanghong這個使用者,在家目錄建立以下幾個目錄就可以了。如下命令:
[zhanghong@localhost ~]$ mkdir -pv rpmbuild/{RPMS,SRPMS,SOURCES,SPECS,BUILD,BUILDROOT}
我們需要自訂宏的話,需要在目前使用者家目錄下建立.rpmmacros檔案,然後寫上宏變數及對應值就行了,如下圖:
[zhanghong@localhost ~]$ cat .rpmmacros
%_topdir /home/zhanghong/rpmbuild/
%_gpg_name ZhangHong
%_signature gpg
寫完之後,進行儲存,然後使用rpmbuild –showrc命令查看值有沒有生效。
2. rpm製作過程:
在sources目錄下,我們放好所有的源碼包,在specs目錄裡面,我們寫好spec檔案,然後我們使用rpmbuild命令去製作。首先會先讀取SOURCES目錄,將SOURCES目錄下面的檔案解壓到BUILD目錄當中,解壓完成之後,會在BUILD產生軟體包的子目錄,然後就會跳到軟體包的目錄裡面去執行編譯過程,configure make。 make完成之後,就要進行安裝,不會安裝到系統中,會安裝到一個臨時目錄,會安裝到BUILDROOT這個目錄裡面去,把BUILDROOT目錄當成系統的根目錄。當檔案產生完成後。將檔案打包好,就要進行clean段,會將BUILDROOT和BUILD解壓的檔案夾也會刪除。
3. rpm包製作原理圖
三、spec檔案介紹(最重要)
1. 基本介紹
spec檔案中包含以下資訊:
1) 軟體的基礎資訊,就是我們使用rpm -qi 軟體包看到的資訊。
2) pre準備階段,其實這個操作就是把檔案解壓到BUILD目錄下
3) 編譯階段,根據我們設定好的編譯參數,對源碼包進行編譯
4) 安裝階段,將編譯好的檔案進行安裝
5) 清理階段,完成包的建立工作之後,將編譯產生的檔案進行清理。
6) 檔案清單, 指定構成包的檔案清單,檔案不能多,也不能少,會報錯的。
7) 修改日誌, 就是軟體的改動日誌。
2. spec檔案樣本與講解
說明:以下spec檔案是製作nginx-1.9.3的spec檔案
%define nginx_user nginx //使用%define命令,定義nginx_user值為nginx,下面就可以使用%{nginx_user}對這個值進行調用了。
Name: nginx //軟體包的名稱,不能使用"-"這個符號
Version: 1.9.3 //軟體包的版本
Release: 2%{?dist} //軟體發行號,預設為1,修改一次加1,標明第幾次打包。
Summary: A free, open-source, high-performance HTTP server and reverse proxy //軟體包的簡介
Group: Applications/Internet //軟體包的分類,這個分類不是亂寫的,需要是在 /usr/share/doc/rpm-4.8.0/GROUPS 這個檔案中存在的組
License: BSD //授權協議,這個授權協議一般看軟體包的介紹,不能亂寫。
URL: http://nginx.org/download/%{name}-%{version}.tar.gz //軟體包的首頁地址
Source0: %{name}-%{version}.tar.gz //製作rpm包的源碼檔案,多個檔案的話,從0開始,如Source0, Source1..這樣。
Source1: nginx.sysinit //同上。nginx的啟動指令碼
BuildRoot: %{_topdir}/BUILDROOT //安裝的假根,打包時,編譯後安裝的檔案會放在這個目錄下。
Vendor: http://www.lookingss.org //發行商或打包組織的標識
Packager: zhanghong <1259001226@qq.com> //製作這個軟體包的作者及郵箱,格式不能錯了
BuildRequires: pcre-devel,openssl-devel,openssl //編譯軟體時要求的軟體包,寫不全也沒關係
Requires: gcc //運行需要的軟體包
Provides: webserver //提供的功能。
%description //對軟體包的描述
nginx [engine x] is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP proxy server, originally written by Igor Sysoev. For a long time, it has been running on many heavily loaded Russian sites including Yandex, Mail.Ru, VK, and Rambler. According to Netcraft, nginx served or proxied 22.27% busiest sites in July 2015. Here are some of the success stories: Netflix, WordPress.com, FastMail.FM.
說明:以下部分就是軟體的基礎資訊部分,Name Version Release Group這四個是必須
%prep //準備編譯階段
%setup -q //這步操作其實就是解壓檔案到BUILD目錄。
說明:
%setup -n %{name}-%{version} 把源碼包解壓並放好,一般使用%setup -c就可以了,但有兩種情況:一就是同時編譯多個源碼包;二就是源碼的tar包的名稱與解壓出來的目錄不一致,此時,就需要使用-n參數指定一下。
附:
%build //編譯階段
export DESTDIR=%{buildroot} 指定安裝目錄為buildroot
./configure \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx/nginx.pid \
--user=%{nginx_user} \
--group=%{nginx_user} \
--with-poll_module \
--with-http_sub_module \
--with-http_flv_module \
--with-http_gzip_static_module \
--http-fastcgi-temp-path=/var/tmp/nginx/fastcgi \
--http-client-body-temp-path=/var/tmp/nginx/client //以上是編譯參數,預設會有一個%configure的,建議把預設的%configure刪除掉,自己寫編譯參數
make %{?_smp_mflags} //進行編譯,後面的%{?_smp_mflags}是表示,如果支援_smp_mflags這個宏就開啟,不支援就不開啟,smp_mflags這個是多處理編譯,如果在多核心cpu的機器上會開啟的
%install //安裝階段
rm -rf %{buildroot}
make install DESTDIR=%{buildroot}
%{__install} -p -d -m 0755 %{buildroot}/var/tmp/nginx/fastcgi
%{__install} -p -d -m 0755 %{buildroot}/var/tmp/nginx/client
%{__install} -p -d -m 0755 %{buildroot}/usr/local/nginx/proxy_temp
%{__install} -p -d -m 0755 %{buildroot}/usr/local/nginx/scgi_temp
%{__install} -p -d -m 0755 %{buildroot}/usr/local/nginx/uwsgi_temp
%{__install} -p -d -m 0755 %{buildroot}/var/log/nginx
%{__install} -p -d -m 0755 %{buildroot}/var/run/nginx
%{__install} -p -D -m 0755 %{SOURCE1} %{buildroot}/etc/rc.d/init.d/nginx
說明:以上是在操作目錄及拷貝檔案,如果不明白參數,具體可以看install命令,其實也可以通過rpmbuild --showrc這個命令獲知%{__install}這個宏就是指install命令的。
%clean //清理階段
rm -rf %{buildroot} //將buildroot目錄刪除
%pre //安裝前操作
if [ $1 == 1 ];
then
/usr/sbin/useradd -s /sbin/false -M %{nginx_user} > /dev/null 2>&1 || :
fi
%post //安裝後操作
if [ $1 == 1 ];
then
/sbin/chkconfig --add %{name}
fi
%preun //卸載前操作
if [ $1 == 0 ];
then
/sbin/service %{name} stop
/sbin/chkconfig --del %{name}
fi
說明:$1一共有三個值,1表示安裝 0表示卸載 2表示升級
%files //檔案清單段,這個階段是把前面已經編譯好的內容打包檔案。
%defattr(-,root,root,-) //指定預設許可權
%doc CHANGES LICENSE README
%{_sbindir}/%{name}
%dir /var/run/nginx
%dir /var/log/nginx
/var/tmp/nginx/
/usr/local/nginx/
/usr/local/nginx/html/50x.html
/usr/local/nginx/html/index.html
%config(noreplace) /etc/nginx/%{name}.conf
%config(noreplace) /etc/nginx/mime.types
%config(noreplace) /etc/nginx/fastcgi.conf
%config(noreplace) /etc/nginx/fastcgi_params
%config(noreplace) /etc/nginx/koi-utf
%config(noreplace) /etc/nginx/koi-win
%config(noreplace) /etc/nginx/scgi_params
%config(noreplace) /etc/nginx/uwsgi_params
%config(noreplace) /etc/nginx/win-utf
%config(noreplace) /etc/nginx/fastcgi.conf.default
%config(noreplace) /etc/nginx/fastcgi_params.default
%config(noreplace) /etc/nginx/mime.types.default
%config(noreplace) /etc/nginx/nginx.conf.default
%config(noreplace) /etc/nginx/scgi_params.default
%config(noreplace) /etc/nginx/uwsgi_params.default
%attr(0755,root,root) /etc/rc.d/init.d/%{name}
%attr(0755,%{nginx_user},%{nginx_user}) /var/tmp/nginx
%attr(0755,%{nginx_user},%{nginx_user}) /usr/local/nginx
說明:
1.%config 表示該檔案為設定檔,noreplace是表示不替換,比如說,安裝好一個軟體包之好,然後進行升級,如果發現設定檔沒有修改,就會直接替換,如果發現修改,就會把原來的新的配置改名成.new
2. %{buildroot}裡的所有檔案要明確被指定是否要被打包到rpm裡面。什麼意思呢?假如,%{buildroot}目錄下有4個目錄a、b、c和d,在%files裡僅指定a和b要打包到rpm裡,如果不把c和d用exclude聲明是要報錯的;
3. 如果聲明了%{buildroot}裡不存在的檔案或者目錄也會報錯。
%changelog
* Tue Aug 2 2015 zhanghong <1259001226@qq.com> - 1.9.3-2
- Add temp directory
* Sat Aug 1 2015 zhanghong <1259001226@qq.com> - 1.9.3-1
- Initial version
說明:
1. 修改日誌,標準格式為
* date +"%a %b %d %Y" 修改人 郵箱 本次版本x.y.z-p (* 英文簡寫星期 英文簡寫月份 日 年 修改者姓名 修改者郵箱 版本號碼)
-本次變更的內容。
3. rpm打包
寫好了spec檔案,就需要使用rpmbuild命令進行打包。
基本格式:rpmbuild [options] [spec文檔]
選項:
-bp #只執行spec的%pre段(解於源碼包關打補丁,即只做準備)
-bc #執行spec的%pre和build段(準備並編譯)
-bi #執行spec中的%pre,%build與%install(準備,編譯並安裝)
-bl #檢查spec中的%file段(查看檔案是否齊全)
-ba #建立源碼包和二進位包(常用)
-bb #只建立二進位包(常用)
-bs #只建立源碼包
一般製作出源碼包和二進位包
[zhanghong@localhost ~]$ rpmbuild -ba nginx-1.9.3.spec
執行成功後,就可以在RPMS目錄看到產生的二進位包(.src.rpm)和SRPMS產生的源碼包(.src.rpm)
說明:建議剛開始打包,可以先一個階段一個階段來測試,先使用bp 後使用bc 這樣確保各個階段流程沒有問題,最後使用ba進行全部打包。
四、RPM包簽署密鑰
1. 介紹
RPM是在Redhat和SUSE上安裝和管理軟體的標準。像Yum和Zypper這樣的中繼資料套件處理軟體可以很容易的安裝軟體包。但是RPM可能有風險,因為其在安裝過程中以root許可權自動執行指令碼。因此要確保你使用的RPM包值得信任。如果是自己建立的RPM包,可以用GPG密鑰來簽署它們。
2. 操作
1) 安裝
[zhanghong@localhost ~]$ yum install gnupg -y
#系統基本都安裝了。所以一般不需要手動進行yum安裝
2) 產生密鑰
[zhanghong@localhost ~]$ gpg --gen-key
斷行符號以後,會跳出一大段文字:
gpg (GnuPG) 2.0.14; Copyright (C) 2009 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
#著作權聲明
Please select what kind of key you want:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
Your selection?
#請你選擇加密方式,一般是預設
斷行符號,預設選擇第一個選項,表示加密和簽名都使用RSA演算法
然後,系統就會問你密鑰的長度
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
# 預設2048位,密鑰越長越安全,同時計算產生時間也長
斷行符號,預設選擇2048位。
接著,設定密鑰的有效期間。
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0)
# 選項預設是0,0表示永不到期,n表示在n後到期,nw表示在n周后到期,依次就是n月,n年了。
一般選項永不到期。
回答完上面三個問題後,系統讓你確認
Is this correct? (y/N)
輸入y,系統就要求你提供個人資訊
GnuPG needs to construct a user ID to identify your key.
Real name:
# 真實姓名
輸入一下,輸入完之後,會讓你輸入電子郵件。
GnuPG needs to construct a user ID to identify your key.
Real name: Zhang Hong
Email address:
# 輸入電子郵件
輸入完之後,會讓你輸入注釋
Real name: Zhang Hong
Email address: 1259001226@qq.com
Comment:
# 輸入注釋,也可以空著
輸入完之後,系統會讓你確認。
GnuPG needs to construct a user ID to identify your key.
Real name: Zhang Hong
Email address: 1259001226@qq.com
Comment: Test Key
You selected this USER-ID:
"Zhang Hong (Test Key) <1259001226@qq.com>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?
#輸入O表示Okay 確認,輸入其它的,是修改對應的值。
輸入O表示確定。然後就等待產生密鑰。
3) 匯出密鑰
[zhanghong@localhost ~]$ gpg --list-key #列出密鑰
/home/zhanghong/.gnupg/pubring.gpg
----------------------------------
pub 1024R/3AB354FD 2015-08-11
uid Zhang Hong (soft of du-game.com) <1259001226@qq.com>
sub 1024R/D9CC5C71 2015-08-11
#可以看到剛剛產生的密鑰
[zhanghong@localhost ~]$ gpg --export -a 'Zhang Hong' > RPM-GPG-KEY-DUGAME
4) 給rpm包簽署密鑰
需要添加兩個rpm宏變數的值,編輯~./rpmmacros檔案
[zhanghong@localhost ~]$ vim ~/.rpmmacros
%_gpg_name Zhang Hong
%_signature gpg
#gpg_name是對應前面的Real Name
添加好之後,簽署密鑰
[zhanghong@localhost ~]$ rpm --addsign zabbix-server-2.4.6-3.el6.x86_64.rpm
Enter pass phrase:
Pass phrase is good.
zabbix-server-2.4.6-3.el6.x86_64.rpm:
然後在需要安裝包的機器上匯入公開金鑰
[root@localhost RPMS]# rpm --import RPM-GPG-KEY-DUGAME
查看包的狀態
校正包是否正常
[root@localhost RPMS]# rpm --checksig wxWidgets-3.0.2-1.el6.x86_64.rpm
wxWidgets-3.0.2-1.el6.x86_64.rpm: rsa sha1 (md5) pgp md5 OK
自此,RPM包簽署密鑰完成。
五、後續添加
1. spec檔案其它選項
Build Arch: 指編譯的目標處理器架構,noarch標識不指定,但是通常以/usr/lib/rpm/marcros中的內容為預設值。