Press "Enter" to skip to content

Linux之Mock使用方法

在进行编包的时候大多数人会使用rpmbuild命令在本机进行编译,这样可以使一些依赖及本地相关包的修改可以生效,但在开发过程中必须模拟用户的环境或是构建一个“干净的”环境(既没有任何其他依赖的改动,直接从yum下载构建一个纯用户环境),这样我们就需要mock命令来构建这样一个编译的纯环境来进行编译软件包。

1,安装mock
mock的安装方法比较简单,请参照这篇文章即可。安装完成以后,系统会自动多出一个名为mock的组。

2,mock使用方法
mock编译过程不要用root身份,先建立一个普通的用户,然后把用户加入mock组。

[root@test ~]# useradd mockbuilder 
[root@test ~]# usermod -a -G mock mockbuilder 
[root@test ~]# su - mockbuilder

注意:如果强行使用root身份执行mock命令,python将会抛出“RuntimeError: mock will not run from the root account”的错误。

使用内置的mock配置文件来进行编译

mock 的配置文件在/etc/mock/目录下,系统默认内置了fedora、epel-5、epel-6等系统的配置文件,通过查看这些.cfg的配置文件,可以了解到Mock的原理,即软件使用yum来下载一个最小化的系统,并放入chroot环境中。

下面以编译fedora 15 64位系统的软件包来举例(对应的配置文件为fedora-15-x86_64.cfg)

[mockbuilder@os1 ~]# mock -r fedora-15-x86_64 --init          #初始化,不需要加.cfg后缀
[mockbuilder@os1 ~]# mock -r fedora-15-x86_64 --rebuild package-1.2-3.src.rpm   #开始编译过程

初始化以后的最小化系统环境位于:/var/lib/mock/fedora-15-x86_64/root目录下,可以用chroot命令切换此最小化环境。
编译后的日志和软件包会保存在:/var/lib/mock/fedora-15-x86_64/result。

3,自定义配置文件来编译

为了演示整个过程,这里我们修改一下yum源服务器,手动建立了一个sysbuild分组,该分组包含了一个最小化系统所需的基础软件包。

在Yum源服务器上建议sysbuild分组(这里我们把sysbuild分组里的软件包写入1.xml文件中)

[root@os1 os]# yum install createrepo
[root@os1 os]# ls
drpms  Packages  repodata
[root@os1 os]# mv repodata repodata-bak  #备份原有repodata
[root@os1 os]# vim 1.xml  内容如下:

[code lang=”xml”]
<?xml version=’1.0′ encoding=’UTF-8′?>
<!DOCTYPE comps PUBLIC "-//CentOS//DTD Comps info//EN" "comps.dtd">
<comps>
<group>
<id>sysbuild</id>
<name>sysbuild</name>
<description>mock mini require</description>
<default>true</default>
<uservisible>false</uservisible>
<packagelist>
<packagereq type=’mandatory’>bash</packagereq>
<packagereq type=’mandatory’>bzip2</packagereq>
<packagereq type=’mandatory’>coreutils</packagereq>
<packagereq type=’mandatory’>cpio</packagereq>
<packagereq type=’mandatory’>diffutils</packagereq>
<packagereq type=’mandatory’>findutils</packagereq>
<packagereq type=’mandatory’>gawk</packagereq>
<packagereq type=’mandatory’>gcc</packagereq>
<packagereq type=’mandatory’>gcc-c++</packagereq>
<packagereq type=’mandatory’>grep</packagereq>
<packagereq type=’mandatory’>gzip</packagereq>
<packagereq type=’mandatory’>info</packagereq>
<packagereq type=’mandatory’>make</packagereq>
<packagereq type=’mandatory’>patch</packagereq>
<packagereq type=’mandatory’>sed</packagereq>
<packagereq type=’mandatory’>shadow-utils</packagereq>
<packagereq type=’mandatory’>tar</packagereq>
<packagereq type=’mandatory’>unzip</packagereq>
<packagereq type=’mandatory’>util-linux-ng</packagereq>
<packagereq type=’mandatory’>which</packagereq>
<packagereq type=’mandatory’>curl</packagereq>
<packagereq type=’mandatory’>git</packagereq>
<packagereq type=’mandatory’>gnupg</packagereq>
<packagereq type=’mandatory’>make</packagereq>
<packagereq type=’mandatory’>shadow-utils</packagereq>
<packagereq type=’mandatory’>redhat-release-server</packagereq>
<packagereq type=’mandatory’>redhat-rpm-config</packagereq>
<packagereq type=’mandatory’>rpm-build</packagereq>
</packagelist>
</group>

<category>
<id>sysbuild</id>
<name>sysbuild</name>
<description>mock mini require</description>
<display_order>60</display_order>
<grouplist>
<groupid>sysbuild</groupid>
</grouplist>
</category>
</comps>

在Yum源服务器上使用1.xml创建新的repodata

[root@os1 os]# createrepo -g 1.xml ./     #在./下生成新的repodata目录
[root@os1 os]# ls
1.xml  drpms  Packages  repodata  repodata-bak

在Mock服务器上创建自己的配置文件

[root@test ~]# cd /etc/mock
[root@test ~]# vim mock123.cfg   内容如下

[code lang=”plain”]
config_opts[‘root’] = ‘mock123-x86_64’ #将来编译的工作目录就是/var/lib/mock/mock123-x86_64
config_opts[‘target_arch’] = ‘x86_64’
config_opts[‘chroot_setup_cmd’] = ‘groupinstall sysbuild’ #sysbuild要和1.xml文件定义的group标签中的id字段一致
config_opts[‘dist’] = ‘mock123’ #only useful for –resultdir variable subst
config_opts[‘plugin_conf’][‘ccache_enable’] = False
config_opts[‘yum.conf’] = """

[main]
cachedir=/var/cache/yum
debuglevel=1
logfile=/var/log/yum.log
reposdir=/dev/null
retries=20
obsoletes=1
gpgcheck=0
assumeyes=1

[base]
name=base
baseurl=http://localhost/x86_64/os #填写repodata目录的上一级目录
cost=2000
enabled=1

[update] #注意跟上面的base不能一样,否则会报错
name=update #注意跟上面的base不能一样,否则会报错
baseurl=http://localhost/x86_64/os #填写repodata目录的上一级目录
cost=1000
enabled=1
"""

拷贝过去的时候需要注意去掉中文注释,否则python会报SyntaxError: Non-ASCII的错误。配置文件里三个双引号之间的部分,是yum的配置,将来会写入/var/lib/mock/mock123-x86_64/root/etc/yum/yum.conf中

在Mock服务器上使用自己的配置文件进行编绎

[root@test ~]# chown root:mock /etc/mock/mock123.cfg   #给予组权限
[root@test ~]# su - mockbuilder  #注意不能在/var/lib/mock/xxxx目录下执行
[mockbuilder@test ~]# mock -r mock123 --init  #注意不能在/var/lib/mock/xxxx目录下执行
[mockbuilder@test ~]# mock -r mock123 --rebuild packages-1.2.3.src.rpm

如果修改了/etc/mock/mock123.cfg文件,则需要重新初始化chroot环境
[mockbuilder@test ~]# mock -r mock123 --clean all
[mockbuilder@test ~]# mock -r mock123 --init

在初始化和编译的过程中,/var/lib/mock/mock123-x86_64 目录将会被锁定,因此在编译和初始化之前,请确保用户的工作目录不在该目录中。

后记:
1,有时候 /var/lib/mock/mock123-x86_64 目录下的 .lock 文件,并不会自动消失,如果出现错误,不防先退出 mockbuilder 用户,看看该目录下是否有 .lock文件。如果有,删除它,然后重新开始初始化过程。
2,如果增加了YUM源服务器上sysbuild分组的软件包,除了要在YUM源服务器上重新createrepo以外,还需要在Mock服务器上删除/var/cache/mock目录下的内容,这样增加的软件包才会出现在chroot环境中。

3 Comments

  1. Anonymous 2017-11-20

    111

  2. Michael翔 2018-09-06

    博主,我在/var/lib/mock/dlrn-euler-aarch64/root目录下,执行了chroot .操作,报错:
    chroot: 无法进入目录.: 不允许的操作

  3. Anonymous 2020-11-13

    谢谢博主能把此过程展现出来。可惜,复制你的,却都是错误。仅仅是你有意无意的改了一些东西。很难发现,太浪费时间了!一声叹息!

Leave a Reply

Your email address will not be published. Required fields are marked *