在这篇博文openstack软件包管理我已经介绍了下openstack打包原理最核心的原理和问题,但是并没有以实际的例子来介绍,因此这篇博文主要是通过cinder的spec文件来深入的讲解如何通过rpmbuild工具打出自己的版本,顺带对涉及到rpmbuild相关的知识做讲解,本次博文的主要笔记直接记录在spec文件里中。
我的rpmbuild的测试环境:
RPM 版本 4.11.3
rpmbuild构建路径采用默认值,具体如下
%_topdir %{getenv:HOME}/rpmbuild
%_rpmdir %{_topdir}/RPMS
%_sourcedir %{_topdir}/SOURCES
%_specdir %{_topdir}/SPECS
%_srcrpmdir %{_topdir}/SRPMS
%_buildrootdir %{_topdir}/BUILDROOT
%buildroot %{_buildrootdir}/%{name}-%{version}-%{release}.%{_arch}
关于如何配置自定义的宏环境,可以参考rpm 宏定义。
将下面的cinder.spec放入~/rpmbuild/SPECS/
将spec用到的source原文件(tarball、patch文件、控制脚本等)手动拷贝到~/rpmbuild/SOURCES
执行打包编译
rpmbuild -ba ~/rpmbuild/SPECS/
-ba:打源码包和二进制包
-bb:只构建二进制包
何为打源码包?生成在SRPMS下面的.src.rpm包
何为二进制包?生成在RPMS下面的.rpm包
其他的可以通过rpmbuild --help自行查看
生成的.rpm包在~/rpmbuild/RPMS/
生成的.src.rpm包在~/rpmbuild/SRPMS/
最终生成的包有:
openstack-cinder-7.0.0-123.el7.centos.noarch.rpm
python-cinder-7.0.0-1.el7.centos.noarch.rpm
openstack-cinder-7.0.0-1.el7.centos.src.rpm
包名称的构成:{Name}-{Version}-{Release}.{BuildArch}.rpm or .src.rpm
下面就是cinder.spec的内容,里面带有每个关键点的解释。
%global with_doc %{!?_without_doc:1}%{?_without_doc:0}
%global pypi_name cinder
%global release_name liberty
#global是用来定义一些全局变量,变量的反问语法是%{},如果是%{?},则表示变量如果有定义才取值
%{!?upstream_version: %global upstream_version %{version}%{?milestone}}
Name: openstack-cinder
#打出来的rpm包的名字
# Liberty semver reset
# https://review.openstack.org/#/q/I6a35fa0dda798fad93b804d00a46af80f08d475c,n,z
Epoch: 1
Version: 7.0.0
Release: 123%{?milestone}%{?dist}
#dist的值在/etc/rpm/macros.dist里面定义:%dist .el7.centos
Summary: OpenStack Volume service
License: ASL 2.0
URL: http://www.openstack.org/software/openstack-storage/
Source0: http://tarballs.openstack.org/%{pypi_name}/%{pypi_name}-%{upstream_version}.tar.gz
#源码包下载路径,这里目前我没看到rpmbuild有相关参数可以控制自动下,我的做法是:1、手动打执行版本的tarball,将其拷贝到SOURCES下。2、通过spectool工具来自动下载
#如果是自己手动打的tarball,最好要通过python标准的打包方式:python setup.py sdist来发布,否则会涉及到解压出来的发布软件包的版本问题.
#下面这些都是原来打包进rpm包的配置和systemd的控制文件
Source1: cinder-dist.conf
Source2: cinder.logrotate
Source3: cinder-tgt.conf
Source10: openstack-cinder-api.service
Source11: openstack-cinder-scheduler.service
Source12: openstack-cinder-volume.service
Source13: openstack-cinder-backup.service
Source20: cinder-sudoers
BuildArch: noarch
#以BuildRequires定义的包是指在python setup.py build编译的时候需要用到的依赖
BuildRequires: intltool
BuildRequires: python-d2to1
BuildRequires: python-oslo-sphinx
BuildRequires: python-pbr
BuildRequires: python-sphinx
BuildRequires: python2-devel
BuildRequires: python-setuptools
BuildRequires: python-netaddr
BuildRequires: systemd
BuildRequires: git
BuildRequires: os-brick
BuildRequires: python-oslo-concurrency
BuildRequires: python-oslo-messaging
BuildRequires: python-oslo-service
# Required to build cinder.conf
BuildRequires: python-keystonemiddleware
BuildRequires: python-glanceclient
BuildRequires: python-novaclient
BuildRequires: python-swiftclient
BuildRequires: python-oslo-db
BuildRequires: python-oslo-config >= 2:1.11.0
BuildRequires: python-oslo-policy
BuildRequires: python-oslo-reports
BuildRequires: python-oslotest
BuildRequires: python-oslo-versionedobjects
BuildRequires: python-oslo-vmware
BuildRequires: python-crypto
BuildRequires: python-lxml
BuildRequires: python-osprofiler
BuildRequires: python-paramiko
BuildRequires: python-suds
BuildRequires: python-taskflow
#以Requires定义的包是指在安装rpm包的时候依赖或者说对python来说就是指:python setup.py install
Requires: openstack-utils
Requires: python-cinder = %{epoch}:%{version}-%{release}
# we dropped the patch to remove PBR for Delorean
Requires: python-pbr
# as convenience
Requires: python-cinderclient
Requires(post): systemd
Requires(preun): systemd
Requires(postun): systemd
Requires(pre): shadow-utils
Requires: lvm2
Requires: python-osprofiler
Requires: python-rtslib
#这是默认包即openstack-cinder包的描述
%description
OpenStack Volume (codename Cinder) provides services to manage and
access block storage volumes for use by Virtual Machine instances.
#这里是指定义一个新的包,包名为python-cinder,所有关于这个包的信息,依赖都在这个字段下面书写
%package -n python-cinder
Summary: OpenStack Volume Python libraries
Group: Applications/System
Requires: sudo
Requires: MySQL-python
Requires: qemu-img
Requires: sysfsutils
Requires: os-brick
Requires: python-paramiko
Requires: python-qpid
Requires: python-kombu
Requires: python-amqplib
Requires: python-eventlet
Requires: python-greenlet
Requires: python-iso8601
Requires: python-netaddr
Requires: python-lxml
Requires: python-anyjson
Requires: python-cheetah
Requires: python-stevedore
Requires: python-suds
Requires: python-sqlalchemy
Requires: python-migrate
Requires: python-paste-deploy
Requires: python-routes
Requires: python-webob
Requires: python-glanceclient >= 1:0
Requires: python-swiftclient >= 1.2
Requires: python-keystoneclient
Requires: python-novaclient >= 1:2.15
Requires: python-oslo-config >= 1:1.2.0
Requires: python-oslo-db >= 1.0.0
Requires: python-six >= 1.5.0
Requires: python-psutil >= 1.1.1
Requires: python-babel
Requires: python-lockfile
Requires: python-jinja2
Requires: python-oslo-rootwrap
Requires: python-oslo-utils
Requires: python-oslo-serialization
Requires: python-oslo-db
Requires: python-oslo-context
Requires: python-oslo-concurrency
Requires: python-oslo-middleware
Requires: python-taskflow >= 0.7.1
Requires: python-oslo-messaging >= 1.8.0
Requires: python-keystonemiddleware >= 1.5.0
Requires: python-oslo-reports
Requires: python-oslo-service
Requires: python-oslo-versionedobjects
Requires: libcgroup-tools
Requires: iscsi-initiator-utils
Requires: python-osprofiler
#新包python-cinder的描述
%description -n python-cinder
OpenStack Volume (codename Cinder) provides services to manage and
access block storage volumes for use by Virtual Machine instances.
This package contains the cinder Python library.
#spec语法的逻辑控制块,如果定义with_doc,则会打出一个doc包
%if 0%{?with_doc}
%package doc
Summary: Documentation for OpenStack Volume
Group: Documentation
Requires: %{name} = %{epoch}:%{version}-%{release}
BuildRequires: graphviz
# Required to build module documents
BuildRequires: python-eventlet
BuildRequires: python-routes
BuildRequires: python-sqlalchemy
BuildRequires: python-webob
# while not strictly required, quiets the build down when building docs.
BuildRequires: python-migrate, python-iso8601
%description doc
OpenStack Volume (codename Cinder) provides services to manage and
access block storage volumes for use by Virtual Machine instances.
This package contains documentation files for cinder.
%endif
#到这里关于包的定义,描述都结束,接下来就是开始编译前准备,做的事无非就是将源码包解压在BUILD构建
#目录下,再通过一些扩展宏对构建包做一些处理,比如将其初始化为一个git仓库。
%prep
%autosetup -n cinder-%{upstream_version} -S git
#autosetup是rpm替代setup的宏,相关用法参考rpm宏定义及openstack软件包管理
#这段相当于直接执行shell的脚本
find . \( -name .gitignore -o -name .placeholder \) -delete
find cinder -name \*.py -exec sed -i '/\/usr\/bin\/env python/{d;q}' {} +
# Remove the requirements file so that pbr hooks don't add it
# to distutils requires_dist config
rm -rf {test-,}requirements.txt tools/{pip,test}-requires
#开始build阶段,先设置PYTHONPAHT,再执行build动作
%build
# Generate config file
PYTHONPATH=. tools/config/generate_sample.sh from_tox
%{__python2} setup.py build
#安装rpm的时候执行的动作
%install
%{__python2} setup.py install -O1 --skip-build --root %{buildroot}
#下面这些动作都是rpm安装的时候做的事,装完源代码之后还会做一些系统环境相关的配置
# docs generation requires everything to be installed first
export PYTHONPATH="$( pwd ):$PYTHONPATH"
pushd doc
%if 0%{?with_doc}
SPHINX_DEBUG=1 sphinx-build -b html source build/html
# Fix hidden-file-or-dir warnings
rm -fr build/html/.doctrees build/html/.buildinfo
%endif
# Create dir link to avoid a sphinx-build exception
mkdir -p build/man/.doctrees/
ln -s . build/man/.doctrees/man
SPHINX_DEBUG=1 sphinx-build -b man -c source source/man build/man
mkdir -p %{buildroot}%{_mandir}/man1
install -p -D -m 644 build/man/*.1 %{buildroot}%{_mandir}/man1/
popd
# Setup directories
install -d -m 755 %{buildroot}%{_sharedstatedir}/cinder
install -d -m 755 %{buildroot}%{_sharedstatedir}/cinder/tmp
install -d -m 755 %{buildroot}%{_localstatedir}/log/cinder
# Install config files
install -d -m 755 %{buildroot}%{_sysconfdir}/cinder
install -p -D -m 640 %{SOURCE1} %{buildroot}%{_datadir}/cinder/cinder-dist.conf
install -d -m 755 %{buildroot}%{_sysconfdir}/cinder/volumes
install -p -D -m 644 %{SOURCE3} %{buildroot}%{_sysconfdir}/tgt/conf.d/cinder.conf
install -p -D -m 640 etc/cinder/rootwrap.conf %{buildroot}%{_sysconfdir}/cinder/rootwrap.conf
install -p -D -m 640 etc/cinder/api-paste.ini %{buildroot}%{_sysconfdir}/cinder/api-paste.ini
install -p -D -m 640 etc/cinder/policy.json %{buildroot}%{_sysconfdir}/cinder/policy.json
install -p -D -m 640 etc/cinder/cinder.conf.sample %{buildroot}%{_sysconfdir}/cinder/cinder.conf
# Install initscripts for services
install -p -D -m 644 %{SOURCE10} %{buildroot}%{_unitdir}/openstack-cinder-api.service
install -p -D -m 644 %{SOURCE11} %{buildroot}%{_unitdir}/openstack-cinder-scheduler.service
install -p -D -m 644 %{SOURCE12} %{buildroot}%{_unitdir}/openstack-cinder-volume.service
install -p -D -m 644 %{SOURCE13} %{buildroot}%{_unitdir}/openstack-cinder-backup.service
# Install sudoers
install -p -D -m 440 %{SOURCE20} %{buildroot}%{_sysconfdir}/sudoers.d/cinder
# Install logrotate
install -p -D -m 644 %{SOURCE2} %{buildroot}%{_sysconfdir}/logrotate.d/openstack-cinder
# Install pid directory
install -d -m 755 %{buildroot}%{_localstatedir}/run/cinder
# Install rootwrap files in /usr/share/cinder/rootwrap
mkdir -p %{buildroot}%{_datarootdir}/cinder/rootwrap/
install -p -D -m 644 etc/cinder/rootwrap.d/* %{buildroot}%{_datarootdir}/cinder/rootwrap/
# Symlinks to rootwrap config files
mkdir -p %{buildroot}%{_sysconfdir}/cinder/rootwrap.d
for filter in %{_datarootdir}/os-brick/rootwrap/*.filters; do
ln -s $filter %{buildroot}%{_sysconfdir}/cinder/rootwrap.d/
done
# Remove unneeded in production stuff
rm -f %{buildroot}%{_bindir}/cinder-all
rm -f %{buildroot}%{_bindir}/cinder-debug
rm -fr %{buildroot}%{python2_sitelib}/cinder/tests/
rm -fr %{buildroot}%{python2_sitelib}/run_tests.*
rm -f %{buildroot}/usr/share/doc/cinder/README*
#安装前的准备阶段,执行在%install阶段前
%pre
getent group cinder >/dev/null || groupadd -r cinder --gid 165
if ! getent passwd cinder >/dev/null; then
useradd -u 165 -r -g cinder -G cinder,nobody -d %{_sharedstatedir}/cinder -s /sbin/nologin -c "OpenStack Cinder Daemons" cinder
fi
exit 0
#安装后的收尾阶段,执行在%install之后
%post
%systemd_post openstack-cinder-volume
%systemd_post openstack-cinder-api
%systemd_post openstack-cinder-scheduler
%systemd_post openstack-cinder-backup
#卸载rpm包之前的适合动作
%preun
%systemd_preun openstack-cinder-volume
%systemd_preun openstack-cinder-api
%systemd_preun openstack-cinder-scheduler
%systemd_preun openstack-cinder-backup
#卸载rpm包之后的动作
%postun
%systemd_postun_with_restart openstack-cinder-volume
%systemd_postun_with_restart openstack-cinder-api
%systemd_postun_with_restart openstack-cinder-scheduler
%systemd_postun_with_restart openstack-cinder-backup
#默认的包openstack-cinder所包含的文件列表
%files
%dir %{_sysconfdir}/cinder
%config(noreplace) %attr(-, root, cinder) %{_sysconfdir}/cinder/cinder.conf
%config(noreplace) %attr(-, root, cinder) %{_sysconfdir}/cinder/api-paste.ini
%config(noreplace) %attr(-, root, cinder) %{_sysconfdir}/cinder/rootwrap.conf
%config(noreplace) %attr(-, root, cinder) %{_sysconfdir}/cinder/policy.json
%config(noreplace) %{_sysconfdir}/logrotate.d/openstack-cinder
%config(noreplace) %{_sysconfdir}/sudoers.d/cinder
%config(noreplace) %{_sysconfdir}/tgt/conf.d/cinder.conf
%{_sysconfdir}/cinder/rootwrap.d/
%attr(-, root, cinder) %{_datadir}/cinder/cinder-dist.conf
%dir %attr(0750, cinder, root) %{_localstatedir}/log/cinder
%dir %attr(0755, cinder, root) %{_localstatedir}/run/cinder
%dir %attr(0755, cinder, root) %{_sysconfdir}/cinder/volumes
%{_bindir}/cinder-*
%{_unitdir}/*.service
%{_datarootdir}/cinder
%{_mandir}/man1/cinder*.1.gz
%defattr(-, cinder, cinder, -)
%dir %{_sharedstatedir}/cinder
%dir %{_sharedstatedir}/cinder/tmp
#python-cinder包所包含的文件列表,cinder项目的源代码都在这个包里面,这个包相当于公共基础包
%files -n python-cinder
%{?!_licensedir: %global license %%doc}
%license LICENSE
%{python2_sitelib}/cinder
%{python2_sitelib}/cinder-*.egg-info
#doc包所包含的文件列表
%if 0%{?with_doc}
%files doc
%doc doc/build/html
%endif
#这个不重要
%changelog
* Fri Oct 16 2015 Haikel Guemar 1:7.0.0-1
- Update to upstream 7.0.0
* Wed Oct 07 2015 Haikel Guemar 7.0.0-0.2.0rc2
- Update to upstream 7.0.0.0rc2
* Wed Sep 30 2015 Haikel Guemar 7.0.0-0.1rc1
- Update to upstream 7.0.0.0rc1
* Wed Jun 17 2015 Haïkel Guémar 2015.1.0-3
- Fix CVE-2015-1851 (RHBZ #1231822)
* Mon May 04 2015 Alan Pevec 2015.1.0-2
- update keystone_authtoken section in sample conf
* Thu Apr 30 2015 Alan Pevec 2015.1.0-1
- OpenStack Kilo release