本篇通过nova项目的rpm包构建来演示基本的rpm构建过程。
之前在安装nova-compute服务时,遇到了nova-compute服务要求qemu-kvm >= 2.9.0的依赖问题,但是对应版本的操作系统仅有2.7.0的安装包,所以利用这次机会学习了一下如何自己构建openstack nova rpm包,并把相关的步骤记录了下来。
RPM包的构建需要用到一个以.spec结尾的文件(即软件包描述文件), 这个文件中包含了软件包的诸多信息,如软件包的名字、版本、类别、依赖、说明摘要、创建时要执行什么指令、安装时要执行什么操作、以及软件包所要包含的文件列表等。spec文件可以自己写(但通常不要这么干,除非是自己的项目),但通常是直接使用别人写好的spec文件。
xxx.src.rpm: 以src.rpm结尾的包称为源码包,源码包中包含了很多的文件(主要包括源码,甚至包括service的配置文件等),以及前面提到的spec文件。所以如果我们想要重新编译一个rpm包,最好的方法就是找到这个rpm包的源码包,通过源码包构建新的rpm包。
下面开始以重新构建openstack-nova-compute-16.1.7-1.el7.noarch.rpm包为例来演示RPM包的构建过程。
找到openstack-nova-compute-16.1.7-1.el7.noarch.rpm对应的源码包,即下图中的openstack-nova-16.1.7-1.el7.src.rpm,将其下载到本地:
创建mockbuild用户和组(解决 rpm -i xxx.src.rpm 时的警告问题),如果已有mockbuild用户和组,则无需重复执行此操作
[root@centos ~]# groupadd mockbuild
[root@centos ~]# useradd mockbuild -g mockbuild
安装源码包 openstack-nova-16.1.7-1.el7.src.rpm
# 这里使用的是root用户,无需切换到前面创建的mockbuild用户执行
[root@centos ~]# rpm -i /root/openstack-nova-16.1.7-1.el7.src.rpm
# 安装完成后,在当前用户的home目录下(这里是root用户,所以home目录是/root)会生成一个rpmbuild目录
[root@centos ~]# ll ~ | grep rpmbuild
drwxr-xr-x 4 root root 34 10月 17 15:42 rpmbuild
# 通过tree命令查看一下rpmbuild下的文件结构,可以看到所有文件的用户和组都是mockbuild:mockbuild
[root@centos ~]# tree -ug ~/rpmbuild/
/root/rpmbuild/
├── [root root ] SOURCES
│ ├── [mockbuil mockbuil] nova-16.1.7.tar.gz # 源码文件
│ ├── [mockbuil mockbuil] nova-dist.conf
│ ├── [mockbuil mockbuil] nova-ifc-template
│ ├── [mockbuil mockbuil] nova.logrotate
│ ├── [mockbuil mockbuil] nova_migration_authorized_keys
│ ├── [mockbuil mockbuil] nova_migration_identity
│ ├── [mockbuil mockbuil] nova_migration-rootwrap_cold_migration
│ ├── [mockbuil mockbuil] nova_migration-rootwrap.conf
│ ├── [mockbuil mockbuil] nova_migration-sudoers
│ ├── [mockbuil mockbuil] nova-migration-wrapper
│ ├── [mockbuil mockbuil] nova-placement-api.conf
│ ├── [mockbuil mockbuil] nova-ssh-config
│ ├── [mockbuil mockbuil] nova-sudoers
│ ├── [mockbuil mockbuil] openstack-nova-api.service
│ ├── [mockbuil mockbuil] openstack-nova-cells.service
│ ├── [mockbuil mockbuil] openstack-nova-compute.service # nova-compute服务定义文件
│ ├── [mockbuil mockbuil] openstack-nova-conductor.service
│ ├── [mockbuil mockbuil] openstack-nova-consoleauth.service
│ ├── [mockbuil mockbuil] openstack-nova-console.service
│ ├── [mockbuil mockbuil] openstack-nova-metadata-api.service
│ ├── [mockbuil mockbuil] openstack-nova-network.service
│ ├── [mockbuil mockbuil] openstack-nova-novncproxy.service
│ ├── [mockbuil mockbuil] openstack-nova-novncproxy.sysconfig
│ ├── [mockbuil mockbuil] openstack-nova-os-compute-api.service
│ ├── [mockbuil mockbuil] openstack-nova-scheduler.service
│ ├── [mockbuil mockbuil] openstack-nova-serialproxy.service
│ ├── [mockbuil mockbuil] openstack-nova-spicehtml5proxy.service
│ ├── [mockbuil mockbuil] openstack-nova-xvpvncproxy.service
│ └── [mockbuil mockbuil] policy.json
└── [root root ] SPECS
└── [mockbuil mockbuil] openstack-nova.spec # spec文件
2 directories, 30 files
源码包安装完成以后,接下来就可以对 "源码" 或者 "*.spec" 等文件执行修改操作。比如:
此处要做的事情就是修改openstack-nova.spec来更改openstack-nova-compute与qemu-kvm的依赖关系:
# 编辑SPECS/openstack-nova.spec,搜索qemu-kvm找到如下的一段定义(170行至183行)
[root@centos ~]# vim ~/rpmbuild/SPECS/openstack-nova.spec
...
169 Requires: genisoimage
170 # Ensure that the _right_ verion of QEMU binary is shipped based on
171 # distribution.
172 %if 0%{?fedora}
173 Requires(pre): qemu-kvm >= 2.9.0
174 %endif
175 # NOTE-1: CentOS package is called 'qemu-kvm-ev', but it has a
176 # compatiblity "Provides: qemu-kvm-rhev", so it'll do the right
177 # thing, that's why we're not special-casing CentOS here.
178 # NOTE-2: Explicitly conditionalize on RHEL-7, as we have to
179 # re-evaluate the QEMU version string for each RHOS / RHEL
180 # release.
181 %if 0%{?rhel} == 7
182 Requires(pre): qemu-kvm-rhev >= 2.9.0
183 %endif
184 Requires: bridge-utils
...
# 将上面找到的内容(170~183行)直接删除,并增加新的依赖关系(170行),然后保存退出即可
[root@centos ~]# vim ~/rpmbuild/SPECS/openstack-nova.spec
...
169 Requires: genisoimage
170 Requires: qemu-kvm >= 2.7.0
171 Requires: bridge-utils
...
上一步是根据自己的需要修改源码包,修改完成后的最后一个步骤就是构建新的rpm包
# 进入到rpmbuild/SPECS目录下
[root@centos ~]# cd ~/rpmbuild/SPECS
# 安装rpm-build,安装完成后才会有rpmbuild命令
[root@centos ~]# yum install rpm-build
# 构建新的rpm包,命令为(任选一个命令即可):
# rpmbuild -ba xxx.spec: 编译后生成*.rpm和*.src.rpm
# rpmbuild -bb xxx.spec: 编译后只生成*.rpm
# rpmbuild -bs xxx.spec: 编译后只生成*.src.rpm
# 我们此处不需要源码包,所以使用rpmbuild -bb命令就可以了(构建可能需要一些依赖包,需要先手动安装上)
[root@centos ~]# rpmbuild -bb openstack-nova.spec
# 构建完成后,在~/rpmbuild目录下又会生成几个新的目录
[root@centos ~]# ll ~/rpmbuild/
总用量 4
drwxr-xr-x 3 root root 25 10月 17 16:14 BUILD # 编译rpm包的临时目录
drwxr-xr-x 2 root root 6 10月 17 16:17 BUILDROOT # 编译后生成的软件临时安装目录
drwxr-xr-x 3 root root 20 10月 17 16:17 RPMS # 最终生成的可安装rpm包的所在目录
drwxr-xr-x 2 root root 4096 10月 17 15:55 SOURCES # 所有源代码和补丁文件的存放目录
drwxr-xr-x 2 root root 33 10月 17 16:04 SPECS # 存放SPEC文件的目录(重要)
drwxr-xr-x 2 root root 6 10月 17 16:14 SRPMS # 最终的rpm源码格式存放路径
# 从目录的作用可知道,新构建出来的rpm包就位于 RPMS 目录下
[root@controller ~]# tree ~/rpmbuild/RPMS
/root/rpmbuild/RPMS
└── noarch
├── openstack-nova-16.1.7-1.el7.noarch.rpm
├── openstack-nova-api-16.1.7-1.el7.noarch.rpm
├── openstack-nova-cells-16.1.7-1.el7.noarch.rpm
├── openstack-nova-common-16.1.7-1.el7.noarch.rpm
├── openstack-nova-compute-16.1.7-1.el7.noarch.rpm
├── openstack-nova-conductor-16.1.7-1.el7.noarch.rpm
├── openstack-nova-console-16.1.7-1.el7.noarch.rpm
├── openstack-nova-doc-16.1.7-1.el7.noarch.rpm
├── openstack-nova-migration-16.1.7-1.el7.noarch.rpm
├── openstack-nova-network-16.1.7-1.el7.noarch.rpm
├── openstack-nova-novncproxy-16.1.7-1.el7.noarch.rpm
├── openstack-nova-placement-api-16.1.7-1.el7.noarch.rpm
├── openstack-nova-scheduler-16.1.7-1.el7.noarch.rpm
├── openstack-nova-serialproxy-16.1.7-1.el7.noarch.rpm
├── openstack-nova-spicehtml5proxy-16.1.7-1.el7.noarch.rpm
├── python-nova-16.1.7-1.el7.noarch.rpm
└── python-nova-tests-16.1.7-1.el7.noarch.rpm
1 directory, 17 files
至此,openstack nova项目的rpm包构建就完成了,把构建好的rpm包放到需要的服务器上直接安装就可以了。
这种方式直接将整个nova项目打包成了一个rpm包,没有按照nova-api, nova-compute等服务来区分rpm包。
安装rpm-build包,安装完成后才会有rpmbuild命令
[root@centos ~]# yum install rpm-build
进入python源码目录,确保已经有了setup.py,没有则需要自己创建
[root@centos ~]# cd /home/nova
[root@centos nova]# ll
total 1700
drwxr-xr-x 3 root root 4096 Oct 16 20:20 api-guide
drwxr-xr-x 3 root root 4096 Oct 16 20:20 api-ref
-rw-r--r-- 1 root root 59749 Oct 16 23:24 AUTHORS
-rw-r--r-- 1 root root 17 Oct 16 20:20 babel.cfg
-rw-r--r-- 1 root root 1310 Oct 16 20:20 bindep.txt
drwxr-xr-x 3 root root 4096 Oct 16 23:24 build
-rw-r--r-- 1 root root 1534095 Oct 16 23:24 ChangeLog
drwxr-xr-x 3 root root 4096 Oct 16 20:20 contrib
-rw-r--r-- 1 root root 535 Oct 16 20:20 CONTRIBUTING.rst
drwxr-xr-x 2 root root 4096 Oct 16 20:20 devstack
drwxr-xr-x 2 root root 4096 Oct 16 23:29 dist
drwxr-xr-x 6 root root 4096 Oct 16 20:20 doc
drwxr-xr-x 3 root root 4096 Oct 16 20:20 etc
drwxr-xr-x 2 root root 4096 Oct 16 20:20 gate
-rw-r--r-- 1 root root 6955 Oct 16 20:20 HACKING.rst
-rw-r--r-- 1 root root 10143 Oct 16 20:20 LICENSE
-rw-r--r-- 1 root root 735 Oct 16 20:20 MAINTAINERS
drwxr-xr-x 29 root root 4096 Oct 16 20:20 nova
drwxr-xr-x 2 root root 4096 Oct 16 23:24 nova.egg-info
drwxr-xr-x 3 root root 4096 Oct 16 20:20 placement-api-ref
drwxr-xr-x 3 root root 4096 Oct 16 20:20 playbooks
drwxr-xr-x 3 root root 4096 Oct 16 20:20 plugins
-rw-r--r-- 1 root root 2397 Oct 16 20:20 README.rst
drwxr-xr-x 4 root root 4096 Oct 16 20:20 releasenotes
-rw-r--r-- 1 root root 2346 Oct 16 20:20 requirements.txt
-rw-r--r-- 1 root root 3726 Oct 16 20:20 setup.cfg
-rw-r--r-- 1 root root 1030 Oct 16 20:20 setup.py
-rw-r--r-- 1 root root 1133 Oct 16 20:20 test-requirements.txt
-rw-r--r-- 1 root root 55 Oct 16 20:20 tests-functional-py3.txt
-rw-r--r-- 1 root root 492 Oct 16 20:20 tests-py3.txt
drwxr-xr-x 5 root root 4096 Oct 16 20:20 tools
-rw-r--r-- 1 root root 9339 Oct 16 20:20 tox.ini
执行下面的命令构建rpm包
# 构建rpm包
[root@centos nova]# python setup.py bdist_rpm
......
+ cd /home/nova/build/bdist.linux-mips64el/rpm/BUILD
+ rm -rf nova-16.1.9.dev7
+ exit 0
moving build/bdist.linux-mips64el/rpm/SRPMS/nova-16.1.9.dev7-1.src.rpm -> dist
moving build/bdist.linux-mips64el/rpm/RPMS/noarch/nova-16.1.9.dev7-1.noarch.rpm -> dist
# 构建完成后,rpm包会移动到当前目录下的dist目录下,其中noarch.rpm就是可以直接安装的二进制包,
# 而src.rpm则是源码包,是不能直接安装的。
[root@centos nova]# ll dist/
total 28360
-rw-r--r-- 1 root root 8015596 Oct 16 23:29 nova-16.1.9.dev7-1.noarch.rpm
-rw-r--r-- 1 root root 10507637 Oct 16 23:29 nova-16.1.9.dev7-1.src.rpm
-rw-r--r-- 1 root root 10510450 Oct 16 23:24 nova-16.1.9.dev7.tar.gz
# 查看noarch.rpm包的依赖关系,从输出可以看到,这些依赖关系和官方提供的有很大区别,官方提供的包会提示
# 大量的依赖关系,而我们自己构建的rpm包则没有这些依赖关系
[root@centos nova]# yum deplist dist/nova-16.1.9.dev7-1.noarch.rpm
Loaded plugins: langpacks, priorities
package: nova.noarch 16.1.9.dev7-1
dependency: /bin/bash
provider: bash.mips64el 4.2.46-28.ns7_4
dependency: /usr/bin/python
provider: python.mips64el 2.7.5-58.ns7_4.2
dependency: python(abi) = 2.7
provider: python.mips64el 2.7.5-58.ns7_4.2
安装nova-16.1.9.dev7-1.noarch.rpm
[root@centos nova]# yum install dist/nova-16.1.9.dev7-1.noarch.rpm
参考资料:
http://abcdxyzk.github.io/blog/2014/10/30/tools-src-rpm/
https://cbs.centos.org/koji/buildinfo?buildID=24790
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。