一、RPM包的分類
RPM有五種基本的操作功能:安裝、卸載、升級、查詢和驗證。
linux軟件包分為兩大類:
(1)二進制類包,包括rpm安裝包(一般分為i386和x86等幾種)
(2)源碼類包,源碼包和開發包應該歸位此類(.src.rpm)。
有時候為了方便源碼包的安裝,和我們自己訂制軟件包的需求,我們會把一些源碼包按照我們的需求來做成rpm包,當有了源碼包就可以直接編譯得到二進制安裝包和其他任意包。spec file是制作rpm包最核心的部分,rpm包的制作就是根據spec file來實現的。在制作自定義rpm包的時候最好不要使用管理員進行,因為管理員權限過大,如果一個命令寫錯了,結果可能是災難性的,而制件一個rpm包普通用戶完全可以實現
二、修改宏及自定義車間位置
在redhat下,rpm包的默認制作路徑在/usr/src/redhat下,這其中包含了6個目錄(要求全部大寫)
Directory Usage
BUILD 源代碼解壓以后放的位置,只需提供BUILD目錄,具體里面放什么,不用我們管,所以真正的制作車間是BUILD目錄
RPMS 制作完成后的rpm包存放目錄,為特定平台指定子目錄(i386,i686,ppc)
SOURCES 收集的源文件,源材料,補丁文件等存放位置
SPECS 存放spec文件,作為制作rpm包的領崗文件,以 rpm名.spec
SRPMS src格式的rpm包位置 ,既然是src格式的包,就沒有平台的概念了
BuiltRoot 假根,使用
install
臨時安裝到這個目錄,把這個目錄當作根來用的,所以在這個目錄下的目錄文件,才是真正的目錄文件。當打包完成后,在清理階段,這個目錄將被刪除
|
但centos並沒有該目錄,因此,我們不得不自定義工作車間,即使在redhat下有該目錄,一般也是自定義到普通用戶的家目錄下的
rpmbuild --showrc 顯示所有的宏,以下划線開頭,一個下划線:定義環境的使用情況,二個下划線:通常定義的是命令,為什么要定義宏,因為不同的系統,命令的存放位置可能不同,所以通過宏的定義找到命令的真正存放位置
查看默認工作車間,所以只要改變了這個宏,我們就可以自定義工作車間了
[root@localhost /]
# rpmbuild --showrc | grep topdir
-14: _builddir %{_topdir}
/BUILD
-14: _buildrootdir %{_topdir}
/BUILDROOT
-14: _desktopdir %{_datadir}
/applications
-14: _rpmdir %{_topdir}
/RPMS
-14: _sourcedir %{_topdir}
/SOURCES
-14: _specdir %{_topdir}
/SPECS
-14: _srcrpmdir %{_topdir}
/SRPMS
-14: _topdir %{getenv:HOME}
/rpmbuild
|
三、rpm包制作原理圖

四、制作rpm包
1、安裝rpm-build
# yum -y install rpm-build
|
2、增加普通用戶並修改工作車間目錄
# useradd hero
# su - hero
$ vim ~/.rpmmacros
%_topdir
/home/hero/rpmbuild
# mkdir -pv ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
# rpmbuild --showrc | grep _topdir #會發現,工作車間已然改變:_topdir /home/hero/rpmbuild
|
3、收集源碼文件
(1)文件列表
[root@localhost SOURCES]
# pwd
/home/hero/rpmbuild/SOURCES
[root@localhost SOURCES]
# ls
fastcgi_params init.nginx nginx-1.7.7.
tar
.gz nginx.conf
|
(2)nginx-1.7.7.tar.gz 源碼包
$
cp
/opt/src/nginx-1
.7.7.
tar
.gz
/home/hero/rpmbuild/SOURCES/
|
(3)init.nginx 腳本文件
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig: - 85 15
# description: Nginx is an HTTP(S) server, HTTP(S) reverse \
# proxy and IMAP/POP3 proxy server
# processname: nginx
## config: /etc/nginx/nginx.conf
# config: /usr/local/nginx/conf/nginx.conf
# config: /etc/sysconfig/nginx
## pidfile: /var/run/nginx/nginx.pid
# pidfile: /usr/local/nginx/logs/nginx.pid
# Source function library.
.
/etc/rc
.d
/init
.d
/functions
# Source networking configuration.
.
/etc/sysconfig/network
# Check that networking is up.
[
"$NETWORKING"
=
"no"
] &&
exit
0
nginx=
"/usr/local/nginx/sbin/nginx"
prog=$(
basename
$nginx)
#NGINX_CONF_FILE="/etc/nginx/nginx.conf"
NGINX_CONF_FILE=
"/usr/local/nginx/conf/nginx.conf"
[ -f
/etc/sysconfig/nginx
] && .
/etc/sysconfig/nginx
lockfile=
/var/lock/subsys/nginx
make_dirs() {
# make required directories
user=`nginx -V 2>&1 |
grep
"configure arguments:"
|
sed
's/[^*]*--user=\([^ ]*\).*/\1/g'
-`
options=`$nginx -V 2>&1 |
grep
'configure arguments:'
`
for
opt
in
$options;
do
if
[ `
echo
$opt |
grep
'.*-temp-path'
` ];
then
value=`
echo
$opt |
cut
-d
"="
-f 2`
if
[ ! -d
"$value"
];
then
# echo "creating" $value
mkdir
-p $value &&
chown
-R $user $value
fi
fi
done
}
start() {
[ -x $nginx ] ||
exit
5
[ -f $NGINX_CONF_FILE ] ||
exit
6
make_dirs
echo
-n $
"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -
eq
0 ] &&
touch
$lockfile
return
$retval
}
stop() {
echo
-n $
"Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval -
eq
0 ] &&
rm
-f $lockfile
return
$retval
}
restart() {
configtest ||
return
$?
stop
sleep
1
start
}
reload() {
configtest ||
return
$?
echo
-n $
"Reloading $prog: "
killproc $nginx -HUP
RETVAL=$?
echo
}
force_reload() {
restart
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >
/dev/null
2>&1
}
case
"$1"
in
start)
rh_status_q &&
exit
0
$1
;;
stop)
rh_status_q ||
exit
0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q ||
exit
7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q ||
exit
0
;;
*)
echo
$
"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
exit
2
esac
|
(4)fastcgi_params 參數
fastcgi_param GATEWAY_INTERFACE CGI
/1
.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
|
4、在 SPECS 目錄下創建 nginx.spec
$
cd
rpmbuild
/SPECS/
$ vim nginx.spec
#此時,里面就是一個模板,直接填就可以了
### 1.The introduction section
Name: nginx
# 軟件包名稱
Version: 1.7.7
# 版本號,(不能使用-)
Release: 3%{?dist}
# release號,對應下面的changelog,如 nginx-1.7.7-3.el6.x86_64.rpm
Summary: nginx-1.7.7.
tar
.gz to nginx-1.7.7.rpm
# 簡要描述信息,最好不要超過50個字符,如要詳述,使用下面的%description
Group: Applications
/Archiving
# 要全用這里面的一個組:less /usr/share/doc/rpm-version/GROUPS
License: GPLv2
# 一定帶上(最好是對方源碼包的License)BSD,GPL,GPLv2
URL: http:
//nmshuishui
.blog.51cto.com/
Packager: nmshuishui <353025240@qq.com>
Vendor: nmshuishui
Source0: %{name}-%{version}.
tar
.gz
# source主要是引用一下自己定義好的腳本,配置文件之類的內容。
Source1: init.nginx
# nginx在主配置文件里面做了很多優化,包括cpu搶占,各種緩存策略,tcp,進程數等。
Source2: nginx.conf
# 每增加一個 Source ,都需要在 %install 段和 %files 段做相應配置,如果是啟動腳本的話,最好在腳本段配置一下
Source3: fastcgi_params
BuildRoot: %_topdir
/BUILDROOT
BuildRequires: gcc
Requires: openssl,openssl-devel,pcre-devel,pcre
# 定義nginx依賴的包,需要yum安裝
%description
# 軟件包詳述
Custom a rpm by yourself!Build nginx-1.7.7.
tar
.gz to nginx-1.7.7.rpm
### 2.The Prep section 准備階段,主要就是把源碼包解壓到build目錄下,設置一下環境變量,並cd進去
%prep
%setup -q
# 這個宏的作用靜默模式解壓並cd
### 3.The Build Section 編譯制作階段,這一節主要用於編譯源碼
%build
%configure
#在 RMP 創建時候, 由於 nginx 不按照常規定義, 不可以定義 %{_prefix} 之類參數, 也不可以使用 %configure 這個參數進行 rpm 編譯
#一旦定義該參數, 會導致編譯自動增加下面參數, 導致報錯
# + ./configure --build=x86_64-redhat-linux-gnu --host=x86_64-redhat-linux-gnu --target=x86_64-redhat-linux-gnu --program-prefix=
#因此,這里需要 ./configure,且需把%configure刪掉
#而且這里需要安裝 pcre-devel包,如果沒有的話,會提示關於pcre的錯誤,直接安裝此包就可以了
.
/configure
\
--prefix=
/usr/local/nginx
\
--user=www \
--group=www \
--with-http_ssl_module \
--with-http_flv_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--http-client-body-temp-path=
/var/tmp/nginx/client/
\
--http-proxy-temp-path=
/var/tmp/nginx/proxy/
\
--http-fastcgi-temp-path=
/var/tmp/nginx/fcgi/
\
--http-uwsgi-temp-path=
/var/tmp/nginx/uwsgi
\
--http-scgi-temp-path=
/var/tmp/nginx/scgi
\
--with-pcre
make
%{?_smp_mflags}
# make后面的意思是:如果就多處理器的話make時並行編譯
### 4.Install section 這一節主要用於完成實際安裝軟件必須執行的命令,可包含4種類型腳本
%
install
rm
-rf %{buildroot}
make
install
DESTDIR=%{buildroot}
%{__install} -p -D -m 0755 %{SOURCE1} %{buildroot}
/etc/rc
.d
/init
.d
/nginx
%{__install} -p -D %{SOURCE2} %{buildroot}
/usr/local/nginx/conf/nginx
.conf
%{__install} -p -D %{SOURCE3} %{buildroot}
/usr/local/nginx/conf/fastcgi_params
%pre
if
[ $1 == 1 ];
then
# $1有3個值,代表動作,安裝類型,處理類型
/usr/sbin/useradd
-r www -s
/sbin/nologin
2>
/dev/null
# 1:表示安裝
fi
# 2:表示升級
# 0:表示卸載
%post
if
[ $1 == 1 ];
then
/sbin/chkconfig
--add %{name}
/sbin/chkconfig
%{name} on
echo
'
# Add #下面主要是內核參數的優化,包括tcp的快速釋放和重利用等。
net.ipv4.tcp_max_syn_backlog = 65536
net.core.netdev_max_backlog = 32768
net.core.somaxconn = 32768
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000927000000
net.ipv4.tcp_max_orphans = 3276800
#net.ipv4.tcp_fin_timeout = 30
#net.ipv4.tcp_keepalive_time = 120
net.ipv4.ip_local_port_range = 1024 65535' >>
/etc/sysctl
.conf
sysctl -p 2>&1
/dev/null
fi
%preun
if
[ $1 == 0 ];
then
/usr/sbin/userdel
-r www 2>
/dev/null
/etc/init
.d
/nginx
stop >
/dev/null
2>&1
fi
%postun
### 5.clean section 清理段,clean的主要作用就是刪除BUILD
%clean
rm
-rf %{buildroot}
### 6.file section 文件列表段,這個階段是把前面已經編譯好的內容要打包了,其中exclude是指要排除什么不打包進來。
%files
%defattr(-,root,root,0755)
/usr/local/nginx/
%attr(0755,root,root)
/etc/rc
.d
/init
.d
/nginx
%config(noreplace)
/usr/local/nginx/conf/nginx
.conf
%config(noreplace)
/usr/local/nginx/conf/fastcgi_params
### 7.chagelog section 日志改變段, 這一段主要描述軟件的開發記錄
%changelog
* Thu Wed 26 2014 nmshuishui <353025240@qq.com> - 1.7.7-3
- Initial version
|
5、制作rpm包
rpmbuild -bp nginx.spec 制作到%prep段
rpmbuild -
bc
nginx.spec 制作到%build段
rpmbuild -bi nginx.spec 執行 spec 文件的
"%install"
階段 (在執行了 %prep 和 %build 階段之后)。這通常等價於執行了一次
"make install"
rpmbuild -bb nginx.spec 制作二進制包
rpmbuild -ba nginx.spec 表示既制作二進制包又制作src格式包
|
五、rpm包的簽名
1、查詢軟件包信息
[root@localhost ~]
# rpm -qi nginx
Name : nginx Relocations: (not relocatable)
Version : 1.7.7 Vendor: nmshuishui
Release : 3.el6 Build Date: Wed 26 Nov 2014 06:39:00 PM CST
Install Date: Wed 26 Nov 2014 06:42:19 PM CST Build Host: localhost
Group : Applications
/Archiving
Source RPM: nginx-1.7.7-3.el6.src.rpm
Size : 793593 License: GPLv2
Signature : (none)
# rpm包未簽名狀態
Packager : nmshuishui <353025240@qq.com>
URL : http:
//nmshuishui
.blog.51cto.com/
Summary : nginx-1.7.7.
tar
.gz to nginx-1.7.7.rpm
Description :
Custom a rpm by yourself!Build nginx-1.7.7.
tar
.gz to nginx-1.7.7.rpm
|
2、使用gpg方式生成簽名密鑰
[root@localhost ~]
# gpg --gen-key
Your selection?1<Enter>
#默認即可
What keysize
do
you want? (2048) 1024<Enter>
#選擇密鑰長度
Key is valid
for
? (0) 1y<Enter>
#有效期
Is this correct? (y
/N
) y<Enter>
#確認
Real name: nmshuishui<Enter>
#密鑰名稱
Email address: 353025240@qq.com<Enter>
#郵件
Comment: GPG-RPM-KEY<Enter>
#備注
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O<ENTER>
#okay確認
Enter passphrase OK <Enter>
#按Enter輸入密碼
<Take this one anyway> <Enter>
#確認使用此密碼
#####
在生成密鑰的時候,會報這么一個信息:can
't connect to `/root/.gnupg/S.gpg-agent'
: No such
file
or directory,可以不用理會它。
接下來就是一些隨機數的說明了:We need to generate a lot of random bytes. It is a good idea to perform
some other action (
type
on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
就狂敲鍵盤和移動鼠標吧,也可以鏈接一個偽隨機數(不過不安全),接下來的活兒就是等了
生成密鑰后會是這樣的:
gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
pub 2048R
/DF63EDFB
2014-11-26
Key fingerprint = 338D 476F 29C9 E2D6 6604 1D96 6F73 1E81 DF63 EDFB
uid nmshuishui (gen-key) <353025240@qq.com>
sub 2048R
/263FB359
2014-11-26
|
3、查看生成的密鑰
[root@localhost ~]
# gpg --list-keys
/root/
.gnupg
/pubring
.gpg
------------------------
pub 2048R
/DF63EDFB
2014-11-26
uid nmshuishui (gen-key) <353025240@qq.com>
sub 2048R
/263FB359
2014-11-26
|
4、導出公鑰以供驗證
[root@localhost ~]
# gpg --export -a "nmshuishui" > RPM-GPG-KEY-nmshuishui
|
5、在~/.rpmmacros宏中定義加密密鑰
[root@localhost ~]
# vim ~/.rpmmacros
%_gpg_name nmshuishui
|
6、為rpm包簽名
[root@localhost ~]
# rpm --addsign /home/hero/rpmbuild/RPMS/x86_64/nginx-1.7.7-3.el6.x86_64.rpm
Enter pass phrase:
Pass phrase is good.
/home/hero/rpmbuild/RPMS/x86_64/nginx-1
.7.7-3.el6.x86_64.rpm:
|
7、將公鑰導入rpm包
[root@localhost ~]
# rpm --import RPM-GPG-KEY-nmshuishui
|
8、驗證
[root@localhost ~]
# rpm --checksig /home/hero/rpmbuild/RPMS/x86_64/nginx-1.7.7-3.el6.x86_64.rpm
/home/hero/rpmbuild/RPMS/x86_64/nginx-1
.7.7-3.el6.x86_64.rpm: rsa sha1 (md5) pgp md5 OK
|
9、重新安裝nginx,驗證安裝包的簽名信息
[root@localhost ~]
# rpm -ivh /home/hero/rpmbuild/RPMS/x86_64/nginx-1.7.7-3.el6.x86_64.rpm
Preparing...
########################################### [100%]
1:nginx
########################################### [100%]
[root@localhost ~]
#
[root@localhost ~]
# rpm -qi nginx
Name : nginx Relocations: (not relocatable)
Version : 1.7.7 Vendor: nmshuishui
Release : 3.el6 Build Date: Wed 26 Nov 2014 06:39:00 PM CST
Install Date: Thu 27 Nov 2014 10:58:44 AM CST Build Host: localhost
Group : Applications
/Archiving
Source RPM: nginx-1.7.7-3.el6.src.rpm
Size : 793593 License: GPLv2
Signature : RSA
/SHA1
, Thu 27 Nov 2014 10:40:02 AM CST, Key ID 6f731e81df63edfb
# 與 1 比起來,多了簽名信息
Packager : nmshuishui <353025240@qq.com>
URL : http:
//nmshuishui
.blog.51cto.com/
Summary : nginx-1.7.7.
tar
.gz to nginx-1.7.7.rpm
Description :
Custom a rpm by yourself!Build nginx-1.7.7.
tar
.gz to nginx-1.7.7.rpm
|
到這里,一個完整的 rpm 包就制作完成了!
