如何在Chroot环境中使用Mach构建RPM包
注意:本文使用CentOS 5.1进行了测试,但它也可以与其他基于RPM的发行版(例如Fedora,SuSE)
对问题的描述
好的,所以你想要构建一个二进制RPM包来部署在您的服务器上。 您有一个.spec文件或.src.rpm,它来自许多存储库之一,如freshrpms.net或dag.wieers.com ,或者您自己写的。
为什么不使用rpmbuild
构建它?
你可能会遇到几个问题。
- 给定一个spec文件,rpmbuild将不会下载源压缩包和/或补丁。 您必须将它们自己提取到SOURCES目录中。
- 如果缺少任何构建时间依赖关系,rpmbuild将中止,强制您停止正在进行的操作,然后再去构建和安装这些包。
- 当您的软件包自行配置时,它可能自动检测您的构建系统上可用的库,但目标系统上不可用。 例如,如果openldap-devel存在,那么openldap可能链接到您的二进制文件中,但是如果RPM没有将openldap声明为依赖关系,则它将无法在目标系统上运行。 这是一个内在的问题,我称之为“autoconf的诅咒”。
- 您只能为构建机器(例如,CentOS 4构建系统上的CentOS 4二进制程序)构建与系统相同类型的软件包
如果你想要一个例子说明问题是多么的糟糕,请尝试从其规范文件构建包perl-SOAP-Lite。 您将很快找到自己的依赖地狱,其他16个其他软件包需要安装或构建,全部按正确的顺序。
解决方案: 马赫
马赫(用于“制作chroot”)解决了所有这些问题。 它在/ var / lib / mach / roots / distro
下安装目标分发的最小子集。 当它是时候构建一个包,给定一个spec文件,它会自动下载必要的源(或者你可以先给它一个.src.rpm)将它转换成.src.rpm。
马赫然后使用chroot切换到这个洁净室环境。 它将包被监禁到这个环境中,通过yum自动地引用任何依赖关系。 完成的二进制包保留在本地的yum存储库中,以防将来的包生成需要。 最后,通过清除所有剩余包装,将环境清理到原始状态。
作为一个奖励,在chroot环境中构建确保所有的“BuildRequires:”依赖关系在规范文件中被正确地声明,因为在没有它们的情况下,该包将不会生成。
安装马赫
我将在CentOS 5.1系统上从头开始安装一个安装,但是将其设置为为CentOS 4构建软件包。
安装mach本身是一次性的自举操作。 完成此操作后,您所有未来的RPM软件包都可以在mach内建立。
在下载网站上有一些二进制包,但我更喜欢自己从源码构建它:
$ wget http://thomas.apestaart.org/download/mach/mach-0.9.3.tar.bz2
$ sudo rpmbuild -tb mach-0.9.3.tar.bz2
$ sudo yum install createrepo
$ sudo rpm -Uvh /usr/src/redhat/RPMS/i386/mach-0.9.3-1.i386.rpm
另外:如果你想避免在运行rpmbuild时是root,那么你可以在
〜/ .rpmmacros
%_topdir %(echo "$HOME")/redhat并创建必要的子目录:
mkdir ~/redhat ~/redhat/{BUILD,RPMS,SOURCES,SPECS,SRPMS}但是,您仍然必须使用root来安装该软件包。
安装后,检查您是否在/usr/share/doc/mach-0.9.3/README中有文档
,并且/ etc / group
中有一个名为mach的组
。
可选:指向本地yum镜
对于确定性结果,您可能需要明确选择本地yum镜像,而不是依赖于自动重定向。 这在/ etc / mach / location中完成
。 例如,如果你在英国,你可能想改变
centos = 'http://mirror.centos.org/centos'
至
centos = 'http://www.mirrorservice.org/sites/mirror.centos.org'
设置用户
任何要使用马赫环境的用户都需要成为补充组织的成员。 您可以通过将其用户名添加到/ etc / group
中的行末尾来实现:
mach:x:102:user1,user2,user3...
为自己的非root帐户执行此操作,然后注销并重新登录。
注意:由于mach依赖于共享组权限,您的umask值必须为0002(允许在您创建的所有文件和目录上进行组写入)。 检查它,如果需要,更改它:
$ umask 0002 # this is OK $ umask 0022 # this is wrong $ umask 0002 $ umask 0002 # now it's correct
您的umask将在每个会话开始时重置,因此如果不将其默认为0002,则需要更新.profile或每次登录时手动更改它。
最后,每个用户需要创建一个文件〜/ .machrc,
如下所示:
config['installer'] = 'yum' config['files'] = { '/etc/hosts': ''' 127.0.0.1 builder.example.com builder localhost ''', '/etc/resolv.conf': ''' nameserver 1.1.1.1 nameserver 2.2.2.2 search example.com ''' } config['defaultroot'] = 'centos-4-i386-extras' config['macros'] = { 'vendor': 'My Company Name', }
(或者:将它们全局设置在/etc/mach.conf中
)
这给出了在chroot环境中需要的一些参数。 在/ etc / hosts
行中,第一个主机名是要作为构建主机显示在包中的第一个主机名,第二个主机名应该是本机上的“主机名”的实际输出(如果不同)
查看/etc/mach/dist.d/
下的文件, 了解
chroot环境的各种选择。 上述示例为CentOS 4系统构建了包,除了基本的存储库之外,还提供了“extras”存储库。
有关更多详细信息,请参阅自述文件。
准备构建环境
确保在/ var(至少2GB)下有大量可用的磁盘空间,然后按照以下步骤操作:
$ umask
0002 # Confirm this is 0002 !!
$ mach setup build
Preparing root
Installing package set 'minimal' .........................
Installing package set 'base' ............................
... snip lots ...
Retrying installing package set 'base' .............
Installing package set 'build' ...........................
Making snapshot ...
这是您第一次运行缓慢,因为它下载(使用yum)您想要构建的发行版的一整套软件包。 但是这些包被缓存。 所以在将来,即使你把整个chroot环境炸掉,它也不会在重建时重新下载所有的软件包。
说到这个,你应该如何希望完全敬酒建筑环境,并从头开始重新创建它,具体如下:
$ mach clean
$ mach setup build
您的新根位于/ var / lib / mach / roots / distro /
,您可以这样浏览:
$ mach chroot
Entering /var/lib/mach/roots/centos-4-i386-extras, type exit to leave.
ERROR: ld.so: object '/usr/lib/libselinux-mach.so' from
LD_PRELOAD cannot be preloaded: ignored.
-bash-3.1# ls /
bin dev home media opt root selinux sys usr
boot etc lib mnt proc sbin srv tmp var
-bash-3.1# exit
logout
$
建筑包装
这是乐趣开始的地方。 您只需给一个或多个.spec文件或.src.rpm文件进行Mach 构建 :
$ mach build foo.spec bar.spec ...
要么
$ mach rebuild foo.src.rpm bar.src.rpm ...
Mach自动完成所有其余操作,并将Shiny的完成程序包放在/ var / tmp / mach / distro /下
。
一个工作的例子:perl-SOAP-Lite
我们来试试我之前提到的“硬”RPM包。
$ umask
0002 # just checking!
$ wget http://svn.rpmforge.net/svn/trunk/rpms/perl-SOAP-Lite/perl-SOAP-Lite.spec
$ mach build perl-SOAP-Lite.spec
Building .src.rpm from perl-SOAP-Lite.spec
... snip ...
Build of perl-SOAP-Lite-0.710.05-1 succeeded, results in
/var/tmp/mach/centos-4-i386-extras/perl-SOAP-Lite-0.710.05-1
Results: /var/tmp/mach/centos-4-i386-extras/perl-SOAP-Lite-0.710.05-1
Build done.
而已。 “Results:”行告诉您包含已经构建的RPM软件包的目录:
$ ls -l /var/tmp/mach/centos-4-i386-extras/perl-SOAP-Lite-0.710.05-1
total 764
-rw-rw-r-- 1 candlerb mach 440039 May 15 16:43 perl-SOAP-Lite-0.710.05-1.noarch.rpm
-rw-rw-r-- 1 candlerb mach 270301 May 15 16:43 perl-SOAP-Lite-0.710.05-1.src.rpm
-rw-rw-r-- 1 candlerb mach 2734 May 15 16:43 perl-SOAP-Lite.spec
-rw-rw-r-- 1 candlerb mach 50507 May 15 16:43 rpm.log
如果一切顺利,那么微笑。
故障排除
缺少依赖关系
有时一个包将无法构建,因为它依赖于供应商的二进制存储库中不可用的另一个包。 例如,使用较早版本的CentOS,perl-SOAP-Lite包将无法构建,因为它依赖于不存在的perl-Compress-Zlib。
没问题:只需找到一个.spec文件,并告诉mach来构建该包。
$ wget http://svn.rpmforge.net/svn/trunk/rpms/perl-Compress-Zlib/perl-Compress-Zlib.spec
$ mach build perl-SOAP-Lite.spec perl-Compress-Zlib.spec
您甚至不需要在命令行中指定.spec文件的顺序。 Mach对它们进行排序,以便在依赖它们的包之前构建依赖关系。
其他问题
如果您仍然遇到问题,请添加'-d'标志以启用详细的调试输出,如下所示:
$ mach -d build foo.spec bar.spec
如果mach抱怨存储库被锁定,并且您确定没有其他用户正在使用它(例如,以前的版本被强制中止),那么您可以使用mach解锁
解锁它。
有时,一个软件包可能对一个不在yum存储库中的软件包有一个BuildRequires:依赖,也不能从源代码构建(一个例子是一个依赖于oracle-instantclient-devel
二进制RPM的软件包) 。 您可以通过手动将RPM文件复制到/ var / lib / mach / roots / distro /usr/src/rpm/RPMS.mach-local/
来解决此问题
。
多根
您可以一次安装多个发行版chroot。 只需使用mach -r发行版
即可随时选择您感兴趣的内容,或者在〜/ .machrc中更改defaultroot
因此,单个构建机可以为各种不同的目标系统构建完全干净的包。 您所需要的只是一点磁盘空间和带宽。