前言
前一篇文章中介绍了 multipkg 的安装和基本用法,这两天又结合之前的例子,整理了一篇类似于“实战系列”的文档,
详细说明了 rpm 中的一些细节配置在multipkg中怎么写,以便读者能通过multipkg实现rpm/spec的高阶功能;另外,
晚上总结了最近和以前的几个思路,给multipkg加了一些功能,还未合并到作者的master分支,需要使用的同学可以直接从我
的仓库来获取:
git clone https://github.com/duanjigang1983/multipkg.git
cd multipkg
git checkout duanjigang1983
即可。
另外,examples/tskeeper 是我新加到其中的一个例子,tskeeper 的index.yaml详细展示了multipkg的配置方法,读者可以参考其写法(源代码是大概10年前
写的,如果有丑陋的地方,请包涵,因为我们的目的是为了展示multipkg的用法,并不是例子代码本身)。
下面,我们结合几个用法展开本文的内容:
rpm 安装空目录
为了能在 rpm 包中自带一个空目录,你需要在 spec 文件中通过这样的语法:
%dir dirname
告知 rpmbuild 这个目录需要保留在rpm文件中,而在multipkg中,spec 文件被封装起来了,如果要在rpm中自带空目录, 该怎么办呢?
查看源代码可以知道,在 multipkg 中,是通过每个目录中的 “.keep”文件来实现空目录保留的。比如:
root/
├── etc
│ ├── pkgaudit.conf
│ └── test.conf
├── usr
│ └── local
│ └── pkgaudit
│ ├── data
│ │ └── readme.txt
│ └── log
│ └── readme
└── var
目录 var 是一个空目录,直接:
multipkg .
编译得到的 rpm 文件通过
rpm -qpl xxx.rpm
命令看到的输出列表中,不包含 "/var"这个目录,如果 :
touch root/var/.keep
后,再次 multipkg 生成 rpm后,就能看到这个目录。
这个功能在multipkg的源码在文件 multipkg/source/lib/Seco/Multipkg.pm 中:
921 if ( -d _ ) {
922 print $f $rpmattr . "\%dir /$_\n" if ( -e "$path/.keep" );
923 }
924 else {
925 print $f $rpmattr . "/$_\n";
926 }
927 }
928
如果是一个目录,并且其中包含了 ".keep "文件,就增加 “%dir” 语法到 spec 文件中。
读者可以参考我的git fork出来multipkg的例子(branch:duanjigang1983):
ls examples/tskeeper/root/usr/local/tskeeper/ -a
. .. .keep
首先,你可以删除 .keep 文件后生成 rpm 包,然后 rpm -qpl xxx.rpm 查看,rpm 包中是否有该目录,应该是没有的。
然后再touch 上.keep文件,编译rpm,进行查看验证。
requires 依赖等
依赖包的问题,直接在 index.yaml中编写就行,比如:
arch: noarch
provides:
- Seco::Multipkg
- perl-seco-class
- perl-seco-cpan
requires:
- perl-YAML-Syck
- subversion-perl
- perl-Git
- perl-Error
这样的写法,当然 conflicts,provides,requires 和 obsoletes 都支持如此写法。
configfiles 和 docfiles
configfiles 在 multipkg 中已经有支持,只不过原作者并未提供例子,在对代码进行分析后,我们得到了配置文件的书写语法。
如果在index.yaml中不添加files:这一项的话,所有安装的文件,multipkg都会把其添加到files列表中,默认属性是 :
%default(-,root,root)
比如,一个工程中,multipkg生成的 spec 文件如下:
%files
%defattr(-,root,root)
/usr/local/pkgaudit/log/readme
/usr/local/pkgaudit/data/readme.txt
/etc/pkgaudit.conf
/etc/test.conf
/etc/service/pkgaudit/run
/etc/service/pkgaudit/log/run
%dir /var
这时,/etc/test.conf 和 /etc/pkgaudit.conf 并不是conf 文件,因此通过:
rpm -qp xxx.rpm --configfiles
并不能看到任何配置文件输出。
这时,如果要把 某个文件加入到配置文件列表中,就需要在 index.yaml 中增加 files: 项了,格式如下( 仍以 tskeeper 为例):
requires: ## tskeeper requires 'procps' and daemontools to be installed firstly
- procps
- daemontools
provides: ### The package 'tskeeper' will provide something named as 'tskeeper-examples' and 'cmesoft-tskeeper'
- tskeeper-examples
- cmesoft-tskeeper
conflicts: ### sorry, i am conflicted with some rpms such as 'other-task-keeper' and 'all-task-keeper',
- other-task-keeper
- all-task-keeper
obsoletes: ## when u want to install old-tskeeper with 'yum install old-tskeeper', you will get me -'tkeeper' ^_^
- old-tskeeper
- taskeeper
files:
- "/etc/test_conf1.conf": ##just set attributes of this file, but not a configfile
group: "root"
perm: "0666"
owner: "root"
- "/etc/test_conf2.conf":
group: "root"
perm: "0777"
owner: "nobody"
config: "no" ## no matter what this value will be, 'config' tells multipkg 'please set me as a config file'
- "/etc/proclist.ini":
group: "root"
perm: "0666"
owner: "root"
config: "yes" ## no matter what this value will be, 'config' tells multipkg 'please set me as a config file'
- "/var/doc/tskeeper":
group: "root"
perm: "0444"
owner: "root"
doc: "xxoo" ## yes, 'doc' is a newlly-added feature for multipkg
生成 rpm 文件后,可以看到 configfiles 为:
/etc/proclist.ini
/etc/test_conf2.conf
docfiles 为:
/var/doc/tskeeper
说明: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 文件中添加。
configfiles 更新原则
配置文件更新的原则是:
(1) 升级/安装一个package 时,如果老的配置文件不存在或者无修改,则生成新的配置文件,或者替换老的配置文件。
(2) 升级时,如果老的配置文件有改动,而新包中的配置文件和老包中自带的配置一样的话,使用老的修改了的配置文件,不安装新包中的配置文件,
而且 rpm -qf 查询时,老的配置文件属于新版本的rpm包。
(3) 升级时,如果配置文件有更新,而老的配置文件又被修改了,那么老的修改的配置文件会被更名为 “配置文件名称.save”以做保存。
(4)卸载时,配置文件保存为 “配置文件名.save”,不做删除。
输出或者定制 spec 文件
multipkg 生成 rpm 并不需要使用者编写spec文件,但是其自身还是依赖spec文件的,所以,在build rpm 的过程中,必然有 spec文件生成。
我们可以看下 multipkg 的帮助:
-f, --force Force build on sanity-check failure
-h, --help Display this help
-k, --keep-files Keep files after build
-p, --platform Include this platform
-s, --set List of variables to set
-t, --testbuild When building from a work dir, not source control
-v, --verbose Be verbose
其中 -v -k 就能看到spec文件,比如:
# multipkg -v -k examples/tskeeper
可以看到:
INFO: RUNNING: INSTALLROOT=/tmp/vCfqjg2WVR/install rpmbuild -bb --define '_topdir /tmp/vCfqjg2WVR/rpm/rpmtop' --buildroot /tmp/vCfqjg2WVR/install /tmp/vCfqjg2WVR/spec
然后自己打开:
/tmp/vCfqjg2WVR/spec
这个文件,你一定会恍然大悟的。注意这个路径是随机的,应该参考命令行输出去获取。
另外,multipkg 在build 时,其实是基于一个spec模版文件来生成每个package的spec文件的,这个模版在
源码中的路径为:
root/usr/share/multipkg/templates/spec.template
看了之后,你一定会对 multipkg的原理又有更深的了解了。
请留意本版本中本人对spec.template的修改(description, group, packager 等字段)
关于rpm文件的description属性(新增加功能)
在rpm中,读者可以通过大量文本内容来描述他的rpm包,但是在 multipkg中始终还未支持这个属性的配置,反而采取了较为简单的
作法,配置 description的内容为summary的内容,这个通过spec.template中的:
%description
%summary%
看到,所以,你通过 multipkg 制作的rpm,在 -qpi 查看时,总能看到 summary 和 description 是相同的。
虽然 Desc 不是 rpm 的核心,但是总是影响雅观的,所以,我在multipkg中增加了 setdesc 函数,使得用户在index.yaml中
既可以配置其为一个 字符串,也可以配置其值为一个命令的执行结果(不知道这个功能会不会被人诟病)。
具体说明是:
A: 字符串
配置
description:"this is a description"
你通过
rpm -qpi xxx.rpm
看到的 description 就是 "this is a description"这个内容。
B: 配置为命令
配置为命令时,rpm -qpi xx.rpm 看到的 desc 的内容就是命令执行的结果,一般建议配置为打印desc文件的内容,比如你可以写:
description:"cmd:cat /source/desc.txt"
注意格式为:
[description:"命令关键字(cmd):命令内容"]
如果没有"cmd:"开头,multipkg 就会认为是情况A(字符串)。
建议:在实际中不要配置description为乱七八糟的内容,比如:
description:"cmd:hostname,ps aux;"
并没啥意思,因为 multipkg 会把 build 机器的 hostname 和 ps aux 命令的结果作为desc 的内容。
另外,如果有文件操作,参数如果是相对目录,那么 默认 当前目录是你的工程的根目录,这个一定要注意。
比如:
# multipkg /root/multipkg/examples/tskeeper
tskeepr 的 description 为:
description: 'cmd:cat source/desc.txt;hostname'
build rpm包时,
"cat source/desc.txt"
会在
/root/multipkg/examples/tskeeper
目录下去找
"source/desc.txt"
文件。
后记
关于 multipkg 的使用配置和一些功能细节就介绍到这里,如果您还有更好的建议或者使用,开发的问题,欢迎与我联系: cmesoft@126.com。关于rpm/yum的基础知识,以及rpm管理平台的建设等问题和专业知识可以参考《Linux 软件管理平台设计与实现》一书。