前一篇文章中介紹了 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 軟體管理平台設計與實作》一書。