本文共 6676 字,大约阅读时间需要 22 分钟。
git clone https://github.com/duanjigang1983/multipkg.gitcd multipkggit checkout duanjigang1983即可。 另外,examples/tskeeper 是我新加到其中的一个例子,tskeeper 的index.yaml详细展示了multipkg的配置方法,读者可以参考其写法(源代码是大概10年前 写的,如果有丑陋的地方,请包涵,因为我们的目的是为了展示multipkg的用法,并不是例子代码本身)。 下面,我们结合几个用法展开本文的内容:
%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,进行查看验证。
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.confdocfiles 为:
/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 文件中添加。
-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 等字段)
%description%summary%看到,所以,你通过 multipkg 制作的rpm,在 -qpi 查看时,总能看到 summary 和 description 是相同的。 虽然 Desc 不是 rpm 的核心,但是总是影响雅观的,所以,我在multipkg中增加了 setdesc 函数,使得用户在index.yaml中 既可以配置其为一个 字符串,也可以配置其值为一个命令的执行结果(不知道这个功能会不会被人诟病)。 具体说明是:
description:"this is a description"你通过
rpm -qpi xxx.rpm看到的 description 就是 "this is a description"这个内容。
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/tskeepertskeepr 的 description 为:description: 'cmd:cat source/desc.txt;hostname'build rpm包时,
"cat source/desc.txt"会在
/root/multipkg/examples/tskeeper目录下去找
"source/desc.txt"文件。
转载地址:http://hkpuo.baihongyu.com/