- 論壇徽章:
- 0
|
本帖最后由 duanjigang 于 2012-12-18 20:05 編輯
tag的說明就到此結(jié)束,下來看看spec中的
scripts 腳本
spec 中的腳本,也稱為 hook 腳本,因?yàn)樗麄兙拖?netfilter 中的 hook 函數(shù),就像 yum 的 plugin,在一個(gè)流程的不同點(diǎn)去執(zhí)行,控制流程的行為,豐富流程的功能。
spec 中的腳本可以分為三大類,根據(jù)執(zhí)行的場景劃分:
(1): build 時(shí)腳本:在 RPM 的編譯過程中執(zhí)行
(2): 安裝/卸載時(shí)腳本:在RPM的安裝/升級(jí)/卸載時(shí)執(zhí)行
(3): 校驗(yàn)時(shí)腳本: 在 RPM 命令校驗(yàn)已安裝 RPM 時(shí)執(zhí)行。
(4): 另外,還會(huì)再補(bǔ)充下 觸發(fā)器(Trigger)腳本
build 時(shí)腳本:
作為開發(fā)人員可能都知道。源代碼編譯成二進(jìn)制包,基本上分為以下不可缺少的四步:
- 1): 解壓縮源碼
- 2): 編譯源碼
- 3): 安裝二進(jìn)制程序/軟件
- 4):清除編譯環(huán)境
復(fù)制代碼 對應(yīng)于這四個(gè)不同的點(diǎn),SPEC 提供了四個(gè)腳本hook點(diǎn),每個(gè)hook點(diǎn)的聲明:
- %hook_name #比如 %pre, %build, %install, %clean
- hook點(diǎn)的腳本內(nèi)容
復(fù)制代碼 每個(gè)hook點(diǎn)的腳本都會(huì)最終被存儲(chǔ)到一個(gè)腳本文件中去解釋,因此,在這些hook點(diǎn),你就當(dāng)是在寫你的腳本文件。
在 %pre 這個(gè)hook點(diǎn)一般做的事情都是編譯前環(huán)境準(zhǔn)備,大致有:
- (1):創(chuàng)建工作的頂級(jí)目錄
- (2): 把源代碼解壓縮到 build 目錄。
- (3): 如果有patch定義的話,patch所有代碼。
- (4): 其它事情,為代碼build做好準(zhǔn)備。
復(fù)制代碼 %build hook點(diǎn)的腳本一般就是configure和build源碼,比如 wget 的SPEC中的 %build 段是這么寫的:
- %build
- ./configure --with-ssl=openssl
- make
復(fù)制代碼 %install 是包build過程中安裝到buid_root時(shí)執(zhí)行的腳本。
最常見的執(zhí)行腳本就是:
- %install
- make install prefix=$RPM_BUILD_ROOT/usr
- mkdir -p $RPM_BUILD_ROOT/usr/xxoo
- install binname $RPM_BUILD_ROOT/usr/xxoo/bin
復(fù)制代碼 等。
%clean 這個(gè)hook點(diǎn)腳本是rpm build完成后執(zhí)行的腳本,大多數(shù)內(nèi)容是直接刪除build 目錄:
- %clean
- [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
復(fù)制代碼 RPM 的 安裝/升級(jí)/卸載 hook 腳本
在一個(gè)機(jī)器上第一次安裝一個(gè)RPM,那是很容易而且簡單的事情,但是,一旦目標(biāo)機(jī)器已經(jīng)安裝了某個(gè)包,軟件升級(jí)和卸載就不像
初次安裝那么容易了。
我們很容易能想到的事情有:
第一:軟件自帶的默認(rèn)配置文件,你可能在使用一段時(shí)間后,已經(jīng)做了很多修改,當(dāng)然不希望升級(jí)時(shí)默認(rèn)的配置將其覆蓋或者
軟件卸載時(shí)將其刪除。
第二:軟件產(chǎn)生的數(shù)據(jù)和日志文件,有時(shí)我們希望都保留下來或者刪除日志,保留數(shù)據(jù)等等。
要完成這些任務(wù),僅僅靠RPM的文件安裝功能是不能做到的,必須得在一些執(zhí)行點(diǎn)執(zhí)行某些命令來配合完成。
因此,RPM提供了四個(gè)安裝/卸載時(shí)執(zhí)行的hook函數(shù)可以潛入在RPM中,兩個(gè)給安裝用,兩個(gè)給卸載用。
這種在一些列操作流程中注入hook操作點(diǎn)的方法,在軟件中已經(jīng)很常見了,比如 yum 的 branch插件,netfilter的hook模塊等,都是
典型的范例。
%pre 段的命令會(huì)在 rpm 安裝前執(zhí)行
%post 段的命令會(huì)在 rpm 安裝后執(zhí)行。
%preun 段的命令會(huì)在 rpm 卸載前執(zhí)行。
%postun 段的命令會(huì)在 rpm 卸載后執(zhí)行。
然后看下 rpm 升級(jí)時(shí) rpm 命令的流程。
RPM升級(jí)流程
(1): 執(zhí)行 新版rpm 的 pre 段命令
(2): 安裝新版RPM的文件列表
(3): 執(zhí)行新版RPM的post 段命令
(4): 執(zhí)行老版本rpm 的 preun 段命令
(5): 刪除老版本RPM中沒有被新版本RPM覆蓋的文件(也就是說不再被新版本RPM使用的文件),這個(gè)過程是自動(dòng)的。
(6): 執(zhí)行老版本RPM的 postun 段命令。
關(guān)于以上這個(gè)順序,一定要牢記和理解,因?yàn),如果理解不對的話,?rpm 升級(jí)時(shí)很可能就造成很大的差錯(cuò)。
舉一個(gè)最常見的例子,好多人不知道老版本的rpm的文件在升級(jí)時(shí)會(huì)被自動(dòng)刪除掉,就認(rèn)為需要人為來刪除這些文件。
于是他會(huì)在rpm的 postun 中寫入腳本去 rm -fr /安裝目錄。
這樣會(huì)出現(xiàn)什么問題呢?
我們可以看到,卸載的話,是沒問題的,先 preun, 再postun.
但是如果是升級(jí)呢?
最后一步執(zhí)行的老版本的postun,這樣的話,新安裝的文件都會(huì)被干掉,導(dǎo)致不僅升級(jí)失敗,而且原來的文件也丟失了。
為了保證 rpm 的制作者或者開發(fā)人員能夠靈活的使用這四個(gè)hook,rpm 為 四個(gè)hook點(diǎn)的執(zhí)行命令提供了一個(gè)參數(shù),來區(qū)分是安裝,還是升級(jí)
還是卸載操作,如下:
(1): %pre 如果參數(shù)是1,說明是初次安裝,如果是2,說明是版本升級(jí)
(2): %post 參數(shù)1表示首次安裝,2表示升級(jí)
(3): %preun 和 %postun 的參數(shù)如果是1,表示是升級(jí)
(4): %preun 和 %postun 的參數(shù)是0,表示是卸載。
hook點(diǎn)的命令默認(rèn)是用shell解釋期來解釋執(zhí)行的,當(dāng)然你也可以自己定義解釋器,比如:
- %pre -p /usr/bin/perl
- if ( $ARGV[0] == 1 ) {
- print "Preparing for initial install...\n"
- }
- elsif ( $ARGV[0] == 2 ) {
- print "Preparing to upgrade software...\n"
- }
復(fù)制代碼 |
|