天天看點

rpm 神器第二篇-multipkg 高階用法介紹與實戰前言rpm 安裝空目錄requires 依賴等configfiles 更新原則輸出或者定制 spec 檔案關于rpm檔案的description屬性(新增加功能)後記

前一篇文章中介紹了 multipkg 的安裝和基本用法,這兩天又結合之前的例子,整理了一篇類似于“實戰系列”的文檔,

詳細說明了 rpm 中的一些細節配置在multipkg中怎麼寫,以便讀者能通過multipkg實作rpm/spec的高階功能;另外,

晚上總結了最近和以前的幾個思路,給multipkg加了一些功能,還未合并到作者的master分支,需要使用的同學可以直接從我

的倉庫來擷取:

即可。

另外,examples/tskeeper 是我新加到其中的一個例子,tskeeper 的index.yaml詳細展示了multipkg的配置方法,讀者可以參考其寫法(源代碼是大概10年前

寫的,如果有醜陋的地方,請包涵,因為我們的目的是為了展示multipkg的用法,并不是例子代碼本身)。

下面,我們結合幾個用法展開本文的内容:

為了能在 rpm 包中自帶一個空目錄,你需要在 spec 檔案中通過這樣的文法:

告知 rpmbuild 這個目錄需要保留在rpm檔案中,而在multipkg中,spec 檔案被封裝起來了,如果要在rpm中自帶空目錄, 該怎麼辦呢?

檢視源代碼可以知道,在 multipkg 中,是通過每個目錄中的 “.keep”檔案來實作空目錄保留的。比如:

目錄 var 是一個空目錄,直接:

編譯得到的 rpm 檔案通過

指令看到的輸出清單中,不包含 "/var"這個目錄,如果 :

後,再次 multipkg 生成 rpm後,就能看到這個目錄。

這個功能在multipkg的源碼在檔案 multipkg/source/lib/seco/multipkg.pm 中:

如果是一個目錄,并且其中包含了 ".keep "檔案,就增加 “%dir” 文法到 spec 檔案中。

讀者可以參考我的git fork出來multipkg的例子(branch:duanjigang1983):

首先,你可以删除 .keep 檔案後生成 rpm 包,然後 rpm -qpl xxx.rpm 檢視,rpm 包中是否有該目錄,應該是沒有的。

然後再touch 上.keep檔案,編譯rpm,進行檢視驗證。

依賴包的問題,直接在 index.yaml中編寫就行,比如:

這樣的寫法,當然 conflicts,provides,requires 和 obsoletes 都支援如此寫法。

configfiles 和 docfiles

configfiles 在 multipkg 中已經有支援,隻不過原作者并未提供例子,在對代碼進行分析後,我們得到了配置檔案的書寫文法。

如果在index.yaml中不添加files:這一項的話,所有安裝的檔案,multipkg都會把其添加到files清單中,預設屬性是 :

比如,一個工程中,multipkg生成的 spec 檔案如下:

這時,/etc/test.conf 和 /etc/pkgaudit.conf 并不是conf 檔案,是以通過:

并不能看到任何配置檔案輸出。

這時,如果要把 某個檔案加入到配置檔案清單中,就需要在 index.yaml 中增加 files: 項了,格式如下( 仍以 tskeeper 為例):

生成 rpm 檔案後,可以看到 configfiles 為:

docfiles 為:

說明:docfiles這個屬性支援屬于新增加到multipkg中的功能,作者master分支中尚不支援。

接着,配置檔案的 perm, owner 和 group 在安裝後會如配置中填寫的一樣,如果你隻是想設定某個檔案的屬性,而不想将其配置為config(也就是說在

包更新或者解除安裝時老的配置檔案會保留),你可以删除 config: "yes"這項(注意 config:"xx",xx可以是任何值,他隻是個标志,并無特殊意義),

比如,去除 /etc/test_conf2.conf 的 config: "yes"項後,

再次通過 --configfiles 檢視rpm包時,就看不到 /etc/test_conf2.conf這個配置檔案了。但是,有一點要注意,attributes 還會繼續生效。

另外,config 類型的檔案已經預設有了 noreplace 屬性了,不需要再在spec中或者 index.yaml 檔案中添加。

配置檔案更新的原則是:

(1) 更新/安裝一個package 時,如果老的配置檔案不存在或者無修改,則生成新的配置檔案,或者替換老的配置檔案。

(2) 更新時,如果老的配置檔案有改動,而新包中的配置檔案和老包中自帶的配置一樣的話,使用老的修改了的配置檔案,不安裝新包中的配置檔案,

而且 rpm -qf  查詢時,老的配置檔案屬于新版本的rpm包。

(3) 更新時,如果配置檔案有更新,而老的配置檔案又被修改了,那麼老的修改的配置檔案會被更名為 “配置檔案名稱.save”以做儲存。

(4)解除安裝時,配置檔案儲存為 “配置檔案名.save”,不做删除。

 multipkg 生成 rpm 并不需要使用者編寫spec檔案,但是其自身還是依賴spec檔案的,是以,在build rpm 的過程中,必然有 spec檔案生成。

我們可以看下 multipkg 的幫助:

其中 -v -k 就能看到spec檔案,比如:

可以看到:

然後自己打開:

這個檔案,你一定會恍然大悟的。注意這個路徑是随機的,應該參考指令行輸出去擷取。

另外,multipkg 在build 時,其實是基于一個spec模版檔案來生成每個package的spec檔案的,這個模版在

源碼中的路徑為:

看了之後,你一定會對 multipkg的原理又有更深的了解了。

請留意本版本中本人對spec.template的修改(description, group, packager 等字段)

在rpm中,讀者可以通過大量文本内容來描述他的rpm包,但是在 multipkg中始終還未支援這個屬性的配置,反而采取了較為簡單的

作法,配置 description的内容為summary的内容,這個通過spec.template中的:

看到,是以,你通過 multipkg 制作的rpm,在 -qpi 檢視時,總能看到 summary 和 description 是相同的。

雖然 desc 不是 rpm 的核心,但是總是影響雅觀的,是以,我在multipkg中增加了 setdesc 函數,使得使用者在index.yaml中

既可以配置其為一個 字元串,也可以配置其值為一個指令的執行結果(不知道這個功能會不會被人诟病)。

具體說明是:

 配置

你通過

看到的 description 就是 "this is a description"這個内容。

配置為指令時,rpm -qpi xx.rpm 看到的 desc 的内容就是指令執行的結果,一般建議配置為列印desc檔案的内容,比如你可以寫:

注意格式為:

[description:"指令關鍵字(cmd):指令内容"]

如果沒有"cmd:"開頭,multipkg 就會認為是情況a(字元串)。

建議:在實際中不要配置description為亂七八糟的内容,比如:

description:"cmd:hostname,ps aux;"

并沒啥意思,因為 multipkg 會把 build 機器的 hostname 和 ps aux 指令的結果作為desc 的内容。

另外,如果有檔案操作,參數如果是相對目錄,那麼 預設 目前目錄是你的工程的根目錄,這個一定要注意。

比如:

build rpm包時,

會在

目錄下去找

檔案。

關于 multipkg 的使用配置和一些功能細節就介紹到這裡,如果您還有更好的建議或者使用,開發的問題,歡迎與我聯系: [email protected]。關于rpm/yum的基礎知識,以及rpm管理平台的建設等問題和專業知識可以參考《linux 軟體管理平台設計與實作》一書。