RPM Packaging for OpenStack is an cross-distribution and cross-vendor effort to create common templates for building OpenStack packages for RPM based Linux and OpenStack distributions. The project was started with the goal of unifying the independent packaging efforts of RDO and SUSE, but is really open for anyone who wants to contribute RPM packaging spec files for any distribution.

Introduction

RPM Packaging for OpenStack is an cross-distribution and cross-vendor effort to create common templates for building OpenStack packages for RPM based Linux and OpenStack distributions. The project was started with the goal of unifying the independent packaging efforts of RDO and SUSE, but is really open for anyone who wants to contribute RPM packaging spec files for any distribution.

Goals

The goal of the project is to build up a central repository for RPM .spec files and in the longer run unify the downstream packaging efforts into one jointly maintained upstream project. We intend to also maintain the packaging of the stable/ branch lifecycle of the OpenStack Mitaka release.

安装 renderspec

renderspec 是将 rpm-packaging 生成specs文件的工具,下载安装如下:

[root@xiexianbin-cn ~]# git clone https://github.com/openstack/renderspec.git
Cloning into 'renderspec'...
remote: Counting objects: 296, done.
remote: Total 296 (delta 0), reused 0 (delta 0), pack-reused 296
Receiving objects: 100% (296/296), 58.57 KiB | 63.00 KiB/s, done.
Resolving deltas: 100% (156/156), done.
[root@xiexianbin-cn ~]# cd renderspec/
[root@xiexianbin-cn renderspec]# ll
total 52
drwxr-xr-x. 3 root root    20 Mar 28 17:31 doc
-rw-r--r--. 1 root root 10143 Mar 28 17:31 LICENSE
-rw-r--r--. 1 root root  1482 Mar 28 17:31 README.rst
drwxr-xr-x. 3 root root    87 Mar 28 17:31 renderspec
-rw-r--r--. 1 root root   367 Mar 28 17:31 requirements.txt
-rw-r--r--. 1 root root  1095 Mar 28 17:31 setup.cfg
-rw-r--r--. 1 root root  1030 Mar 28 17:31 setup.py
-rw-r--r--. 1 root root   423 Mar 28 17:31 test-requirements.txt
-rw-r--r--. 1 root root 15677 Mar 28 17:31 tests.py
drwxr-xr-x. 2 root root    28 Mar 28 17:31 tools
-rw-r--r--. 1 root root   984 Mar 28 17:31 tox.ini

安装依赖包:

[root@xiexianbin-cn renderspec]# pip install -r requirements.txt
[root@xiexianbin-cn renderspec]# pip install -r test-requirements.txt

安装

[root@xiexianbin-cn renderspec]# python setup.py install

renderspec 使用的时候有一个bug,如下:

[root@xiexianbin-cn renderspec]# renderspec --help
Traceback (most recent call last):
  File "/usr/bin/renderspec", line 6, in <module>
    from renderspec import main
  File "/usr/lib/python2.7/site-packages/renderspec/__init__.py", line 34, in <module>
    from renderspec import versions
  File "/usr/lib/python2.7/site-packages/renderspec/versions.py", line 19, in <module>
    from packaging.requirements import Requirement
  File "/usr/lib/python2.7/site-packages/packaging/requirements.py", line 59, in <module>
    MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker")
TypeError: __call__() takes exactly 2 arguments (1 given)
[root@xiexianbin-cn renderspec]# 

解决方式:

I made changes to the file requirements.py where the error occurred. For @hysg, that would be this file:

/usr/lib/python2.7/site-packages/packaging/requirements.py

On me on OS X, it’s here:

/Library/Python/2.7/site-packages/packaging/requirements.py

I modified the the offending line by removing the parentheses for the call to MARKER_EXPR, as demonstrated below:

#MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker")
MARKER_EXPR = originalTextFor(MARKER_EXPR)("marker")

And that worked.

参考:http://t.cn/R6Syeg0

最终安装完成:

[root@xiexianbin-cn ~]# renderspec --help
usage: renderspec [-h] [-o OUTPUT] [--spec-style {suse,fedora}]
                  [--epochs EPOCHS] [--requirements REQUIREMENTS]
                  [input-template]

Convert a .spec.j2 template into a .spec

positional arguments:
  input-template        specfile jinja2 template to render. default: *.spec.j2

optional arguments:
  -h, --help            show this help message and exit
  -o OUTPUT, --output OUTPUT
                        output filename or '-' for stdout. default: autodetect
  --spec-style {suse,fedora}
                        distro style you want to use. default: fedora
  --epochs EPOCHS       yaml file with epochs listed.
  --requirements REQUIREMENTS
                        file(s) which contain PEP0508 compatible requirement
                        lines. Last mentioned file has highest priority.
                        default: []
[root@xiexianbin-cn ~]# 

利用生产 specs

克隆 rpm-packaging 源码:

[root@xiexianbin-cn ~]# git clone https://github.com/openstack/rpm-packaging.git -b stable/newton
Cloning into 'rpm-packaging'...
remote: Counting objects: 7345, done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 7345 (delta 2), reused 0 (delta 0), pack-reused 7337
Receiving objects: 100% (7345/7345), 996.62 KiB | 427.00 KiB/s, done.
Resolving deltas: 100% (4447/4447), done.
[root@xiexianbin-cn ~]# cd rpm-packaging/
[root@xiexianbin-cn rpm-packaging]# git branch
* stable/newton
[root@xiexianbin-cn rpm-packaging]# 

使用方法:

[root@xiexianbin-cn tools]# cat README.rst 
RPM Packaging for OpenStack internal tooling README
===================================================

This directory provides useful tooling for contributors to
the RPM Packaging project.


tools/run_renderspec.sh
+++++++++++++++++++++++

This tool can be used to generate usable spec files for all supported
RPM distributions from shipped templates. It will browse recursively
the directory passed in argument to find spec templates.
If no directory is given, it will search in current directory.

Usage::

  tools/run_renderspec.sh <path>


tools/run_speccleaner.sh
++++++++++++++++++++++++

This tool can be used to run spec-cleaner on generated spec files.
It will browse recursively the directory passed in argument and will
display as an unified diff, differences to our standards.
If no directory is given, it will search in current directory.

Usage::

  tools/run_speccleaner.sh <path>


[root@xiexianbin-cn tools]# 

生成specs:

[root@xiexianbin-cn rpm-packaging]# sh tools/run_renderspec.sh > /root/a.log
+ basedir=/root/rpm-packaging
+ specdir=/root/rpm-packaging/openstack/
+ WORKSPACE=/root/rpm-packaging
+ OUTPUTDIR=/root/rpm-packaging/logs/
+ specstyles='suse fedora'
+ MAXPROC=4
+ mkdir -p /root/rpm-packaging/logs/
+ for specstyle in '$specstyles'
+ rm -f /root/rpm-packaging/logs//automaton.spec.j2.suse /root/rpm-packaging/logs//Bareon.spec.j2.suse /root/rpm-packaging/logs//castellan.spec.j2.suse /root/rpm-packaging/logs//ceilometermiddleware.spec.j2.suse /root/rpm-packaging/logs//cliff.spec.j2.suse /root/rpm-packaging/logs//debtcollector.spec.j2.suse /root/rpm-packaging/logs//django_openstack_auth.spec.j2.suse /root/rpm-packaging/logs//futurist.spec.j2.suse /root/rpm-packaging/logs//glance_store.spec.j2.suse /root/rpm-packaging/logs//gnocchiclient.spec.j2.suse /root/rpm-packaging/logs//ironic-lib.spec.j2.suse /root/rpm-packaging/logs//keystoneauth1.spec.j2.suse /root/rpm-packaging/logs//keystonemiddleware.spec.j2.suse /root/rpm-packaging/logs//microversion_parse.spec.j2.suse /root/rpm-packaging/logs//mox3.spec.j2.suse /root/rpm-packaging/logs//openstackdocstheme.spec.j2.suse /root/rpm-packaging/logs//openstack-doc-tools.spec.j2.suse /root/rpm-packaging/logs//openstack-macros.spec.j2.suse /root/rpm-packaging/logs//openstacksdk.spec.j2.suse /root/rpm-packaging/logs//os-api-ref.spec.j2.suse /root/rpm-packaging/logs//os-brick.spec.j2.suse /root/rpm-packaging/logs//osc-lib.spec.j2.suse /root/rpm-packaging/logs//os-client-config.spec.j2.suse /root/rpm-packaging/logs//oslo.cache.spec.j2.suse /root/rpm-packaging/logs//oslo.concurrency.spec.j2.suse /root/rpm-packaging/logs//oslo.config.spec.j2.suse /root/rpm-packaging/logs//oslo.context.spec.j2.suse /root/rpm-packaging/logs//oslo.db.spec.j2.suse /root/rpm-packaging/logs//oslo.i18n.spec.j2.suse /root/rpm-packaging/logs//oslo.log.spec.j2.suse /root/rpm-packaging/logs//oslo.messaging.spec.j2.suse /root/rpm-packaging/logs//oslo.middleware.spec.j2.suse /root/rpm-packaging/logs//oslo.policy.spec.j2.suse /root/rpm-packaging/logs//oslo.privsep.spec.j2.suse /root/rpm-packaging/logs//oslo.reports.spec.j2.suse /root/rpm-packaging/logs//oslo.rootwrap.spec.j2.suse /root/rpm-packaging/logs//oslo.serialization.spec.j2.suse /root/rpm-packaging/logs//oslo.service.spec.j2.suse /root/rpm-packaging/logs//oslosphinx.spec.j2.suse /root/rpm-packaging/logs//oslotest.spec.j2.suse /root/rpm-packaging/logs//oslo.utils.spec.j2.suse /root/rpm-packaging/logs//oslo.versionedobjects.spec.j2.suse /root/rpm-packaging/logs//oslo.vmware.spec.j2.suse /root/rpm-packaging/logs//osprofiler.spec.j2.suse /root/rpm-packaging/logs//os-testr.spec.j2.suse /root/rpm-packaging/logs//os-vif.spec.j2.suse /root/rpm-packaging/logs//os-win.spec.j2.suse /root/rpm-packaging/logs//pycadf.spec.j2.suse /root/rpm-packaging/logs//pymod2pkg.spec.j2.suse /root/rpm-packaging/logs//python-barbicanclient.spec.j2.suse /root/rpm-packaging/logs//python-ceilometerclient.spec.j2.suse /root/rpm-packaging/logs//python-cinderclient.spec.j2.suse /root/rpm-packaging/logs//python-congressclient.spec.j2.suse /root/rpm-packaging/logs//python-designateclient.spec.j2.suse /root/rpm-packaging/logs//python-glanceclient.spec.j2.suse /root/rpm-packaging/logs//python-heatclient.spec.j2.suse /root/rpm-packaging/logs//python-ironicclient.spec.j2.suse /root/rpm-packaging/logs//python-ironic-inspector-client.spec.j2.suse /root/rpm-packaging/logs//python-k8sclient.spec.j2.suse /root/rpm-packaging/logs//python-keystoneclient.spec.j2.suse /root/rpm-packaging/logs//python-magnumclient.spec.j2.suse /root/rpm-packaging/logs//python-manilaclient.spec.j2.suse /root/rpm-packaging/logs//python-mistralclient.spec.j2.suse /root/rpm-packaging/logs//python-monascaclient.spec.j2.suse /root/rpm-packaging/logs//python-muranoclient.spec.j2.suse /root/rpm-packaging/logs//python-neutronclient.spec.j2.suse /root/rpm-packaging/logs//python-novaclient.spec.j2.suse /root/rpm-packaging/logs//python-openstackclient.spec.j2.suse
+ for specstyle in '$specstyles'
+ rm -f /root/rpm-packaging/logs//automaton.spec.j2.fedora /root/rpm-packaging/logs//Bareon.spec.j2.fedora /root/rpm-packaging/logs//castellan.spec.j2.fedora /root/rpm-packaging/logs//ceilometermiddleware.spec.j2.fedora /root/rpm-packaging/logs//cliff.spec.j2.fedora /root/rpm-packaging/logs//debtcollector.spec.j2.fedora /root/rpm-packaging/logs//django_openstack_auth.spec.j2.fedora /root/rpm-packaging/logs//futurist.spec.j2.fedora /root/rpm-packaging/logs//glance_store.spec.j2.fedora /root/rpm-packaging/logs//gnocchiclient.spec.j2.fedora /root/rpm-packaging/logs//ironic-lib.spec.j2.fedora /root/rpm-packaging/logs//keystoneauth1.spec.j2.fedora /root/rpm-packaging/logs//keystonemiddleware.spec.j2.fedora /root/rpm-packaging/logs//microversion_parse.spec.j2.fedora /root/rpm-packaging/logs//mox3.spec.j2.fedora /root/rpm-packaging/logs//openstackdocstheme.spec.j2.fedora /root/rpm-packaging/logs//openstack-doc-tools.spec.j2.fedora /root/rpm-packaging/logs//openstack-macros.spec.j2.fedora /root/rpm-packaging/logs//openstacksdk.spec.j2.fedora /root/rpm-packaging/logs//os-api-ref.spec.j2.fedora /root/rpm-packaging/logs//os-brick.spec.j2.fedora /root/rpm-packaging/logs//osc-lib.spec.j2.fedora /root/rpm-packaging/logs//os-client-config.spec.j2.fedora /root/rpm-packaging/logs//oslo.cache.spec.j2.fedora /root/rpm-packaging/logs//oslo.concurrency.spec.j2.fedora /root/rpm-packaging/logs//oslo.config.spec.j2.fedora /root/rpm-packaging/logs//oslo.context.spec.j2.fedora /root/rpm-packaging/logs//oslo.db.spec.j2.fedora /root/rpm-packaging/logs//oslo.i18n.spec.j2.fedora /root/rpm-packaging/logs//oslo.log.spec.j2.fedora /root/rpm-packaging/logs//oslo.messaging.spec.j2.fedora /root/rpm-packaging/logs//oslo.middleware.spec.j2.fedora /root/rpm-packaging/logs//oslo.policy.spec.j2.fedora /root/rpm-packaging/logs//oslo.privsep.spec.j2.fedora /root/rpm-packaging/logs//oslo.reports.spec.j2.fedora /root/rpm-packaging/logs//oslo.rootwrap.spec.j2.fedora /root/rpm-packaging/logs//oslo.serialization.spec.j2.fedora /root/rpm-packaging/logs//oslo.service.spec.j2.fedora /root/rpm-packaging/logs//oslosphinx.spec.j2.fedora /root/rpm-packaging/logs//oslotest.spec.j2.fedora /root/rpm-packaging/logs//oslo.utils.spec.j2.fedora /root/rpm-packaging/logs//oslo.versionedobjects.spec.j2.fedora /root/rpm-packaging/logs//oslo.vmware.spec.j2.fedora /root/rpm-packaging/logs//osprofiler.spec.j2.fedora /root/rpm-packaging/logs//os-testr.spec.j2.fedora /root/rpm-packaging/logs//os-vif.spec.j2.fedora /root/rpm-packaging/logs//os-win.spec.j2.fedora /root/rpm-packaging/logs//pycadf.spec.j2.fedora /root/rpm-packaging/logs//pymod2pkg.spec.j2.fedora /root/rpm-packaging/logs//python-barbicanclient.spec.j2.fedora /root/rpm-packaging/logs//python-ceilometerclient.spec.j2.fedora /root/rpm-packaging/logs//python-cinderclient.spec.j2.fedora /root/rpm-packaging/logs//python-congressclient.spec.j2.fedora /root/rpm-packaging/logs//python-designateclient.spec.j2.fedora /root/rpm-packaging/logs//python-glanceclient.spec.j2.fedora /root/rpm-packaging/logs//python-heatclient.spec.j2.fedora /root/rpm-packaging/logs//python-ironicclient.spec.j2.fedora /root/rpm-packaging/logs//python-ironic-inspector-client.spec.j2.fedora /root/rpm-packaging/logs//python-k8sclient.spec.j2.fedora /root/rpm-packaging/logs//python-keystoneclient.spec.j2.fedora /root/rpm-packaging/logs//python-magnumclient.spec.j2.fedora /root/rpm-packaging/logs//python-manilaclient.spec.j2.fedora /root/rpm-packaging/logs//python-mistralclient.spec.j2.fedora /root/rpm-packaging/logs//python-monascaclient.spec.j2.fedora /root/rpm-packaging/logs//python-muranoclient.spec.j2.fedora /root/rpm-packaging/logs//python-neutronclient.spec.j2.fedora /root/rpm-packaging/logs//python-novaclient.spec.j2.fedora /root/rpm-packaging/logs//python-openstackclient.spec.j2.fedora
+ count=0
+ echo 'run renderspec over specfiles from /root/rpm-packaging/openstack/'
+ for spec in '${specdir}/**/*.spec.j2'
+ for specstyle in '$specstyles'
+ echo 'run /root/rpm-packaging/openstack//automaton/automaton.spec.j2 for suse'
+ let count+=1
+ [[ count -eq 4 ]]
+ for specstyle in '$specstyles'
+ echo 'run /root/rpm-packaging/openstack//automaton/automaton.spec.j2 for fedora'
+ let count+=1
+ renderspec --spec-style suse /root/rpm-packaging/openstack//automaton/automaton.spec.j2 -o /root/rpm-packaging/logs/automaton.spec.j2.suse
+ [[ count -eq 4 ]]
+ for spec in '${specdir}/**/*.spec.j2'
+ for specstyle in '$specstyles'
+ echo 'run /root/rpm-packaging/openstack//bareon/Bareon.spec.j2 for suse'
+ let count+=1
+ [[ count -eq 4 ]]
+ for specstyle in '$specstyles'
+ echo 'run /root/rpm-packaging/openstack//bareon/Bareon.spec.j2 for fedora'
+ let count+=1
+ [[ count -eq 4 ]]
+ wait
+ renderspec --spec-style fedora /root/rpm-packaging/openstack//bareon/Bareon.spec.j2 -o /root/rpm-packaging/logs/Bareon.spec.j2.fedora
+ renderspec --spec-style fedora /root/rpm-packaging/openstack//automaton/automaton.spec.j2 -o /root/rpm-packaging/logs/automaton.spec.j2.fedora
+ renderspec --spec-style suse /root/rpm-packaging/openstack//bareon/Bareon.spec.j2 -o /root/rpm-packaging/logs/Bareon.spec.j2.suse
+ count=0


...

生成的spec文件:

[root@xiexianbin-cn rpm-packaging]# cd logs/
[root@xiexianbin-cn logs]# ll
total 640
-rw-r--r--. 1 root root 1491 Mar 28 18:00 automaton.spec.j2.fedora
-rw-r--r--. 1 root root 1492 Mar 28 18:00 automaton.spec.j2.suse
-rw-r--r--. 1 root root 3401 Mar 28 18:00 Bareon.spec.j2.fedora
-rw-r--r--. 1 root root 3410 Mar 28 18:00 Bareon.spec.j2.suse
-rw-r--r--. 1 root root 1916 Mar 28 18:00 castellan.spec.j2.fedora
-rw-r--r--. 1 root root 1925 Mar 28 18:00 castellan.spec.j2.suse
-rw-r--r--. 1 root root 1944 Mar 28 18:00 ceilometermiddleware.spec.j2.fedora
-rw-r--r--. 1 root root 1953 Mar 28 18:00 ceilometermiddleware.spec.j2.suse
-rw-r--r--. 1 root root 1909 Mar 28 18:00 cliff.spec.j2.fedora
-rw-r--r--. 1 root root 1932 Mar 28 18:00 cliff.spec.j2.suse
-rw-r--r--. 1 root root 2628 Mar 28 18:00 debtcollector.spec.j2.fedora
-rw-r--r--. 1 root root 2637 Mar 28 18:00 debtcollector.spec.j2.suse
-rw-r--r--. 1 root root 2129 Mar 28 18:00 django_openstack_auth.spec.j2.fedora
-rw-r--r--. 1 root root 2131 Mar 28 18:00 django_openstack_auth.spec.j2.suse
-rw-r--r--. 1 root root 1535 Mar 28 18:00 futurist.spec.j2.fedora
-rw-r--r--. 1 root root 1537 Mar 28 18:00 futurist.spec.j2.suse
-rw-r--r--. 1 root root 2842 Mar 28 18:00 glance_store.spec.j2.fedora
-rw-r--r--. 1 root root 2851 Mar 28 18:00 glance_store.spec.j2.suse
-rw-r--r--. 1 root root 2126 Mar 28 18:00 gnocchiclient.spec.j2.fedora
-rw-r--r--. 1 root root 2149 Mar 28 18:00 gnocchiclient.spec.j2.suse
-rw-r--r--. 1 root root 1166 Mar 28 18:01 ironic-lib.spec.j2.fedora

...

例如:python-keystoneclient.spec.j2.fedora 内容如下:

[root@xiexianbin-cn logs]# cat python-keystoneclient.spec.j2.fedora
%global sname python-keystoneclient
Name:           python-keystoneclient
Epoch:          0
Version:        3.5.0
Release:        0
Summary:        Client library for OpenStack Identity API
License:        ASL 2.0
Group:          Development/Languages/Python
Url:            http://launchpad.net/%{sname}
Source0:        https://pypi.io/packages/source/p/%{sname}/%{sname}-%{version}.tar.gz
BuildRequires:  openssl
BuildRequires:  openstack-macros
BuildRequires:  python-debtcollector
BuildRequires:  python-devel
BuildRequires:  python-keystoneauth1
BuildRequires:  python-lxml
BuildRequires:  python-mock
BuildRequires:  python-oslo-config
BuildRequires:  python-oslo-i18n
BuildRequires:  python-oslo-serialization
BuildRequires:  python-oslo-utils
BuildRequires:  python-oslotest
BuildRequires:  python-pbr
BuildRequires:  python-positional
BuildRequires:  python-requests-mock
BuildRequires:  python-six
BuildRequires:  python-testrepository
BuildRequires:  python-testresources
BuildRequires:  python-testscenarios
Requires:       python-debtcollector
Requires:       python-keystoneauth1
Requires:       python-oslo-config
Requires:       python-oslo-i18n
Requires:       python-oslo-serialization
Requires:       python-oslo-utils
Requires:       python-positional
Requires:       python-requests
Requires:       python-six
Requires:       python-stevedore
BuildArch:      noarch

%description
Client library for interacting with Openstack Identity API.

%package doc
Summary:        Documentation for OpenStack Identity API Client
Group:          Documentation
BuildRequires:  python-sphinx
BuildRequires:  python-oslo-sphinx

%description doc
Documentation for the client library for interacting with Openstack
Identity API.

%prep
%setup -q -n %{sname}-%{version}

%build
%{py2_build}

# Build HTML docs and man page
%{__python2} setup.py build_sphinx

%install
%{py2_install}

# Delete tests
rm -fr %{buildroot}%{python2_sitelib}/tests

# Fix hidden-file-or-dir warnings
rm -fr html/.doctrees html/.buildinfo

%check
export PYTHONPATH="%{python2_sitearch}:%{python2_sitelib}:%{buildroot}%{python2_sitelib}"
# don't want to depend on hacking for package building
rm keystoneclient/tests/unit/test_hacking_checks.py
%{__python2} setup.py testr

%files
%doc README.rst
%license LICENSE
%{python2_sitelib}/keystoneclient
%{python2_sitelib}/*.egg-info

%files doc
%doc doc/build/html
%license LICENSE

%changelog[root@xiexianbin-cn logs]# 

然后就可以使用rpmbuild生成对应的rpm包。可参考:

https://github.com/openstack/rpm-packaging-tools

https://xiexianbin.cn/openstack/2015/08/04/use-src-rpm-build-openstack-rpms

完毕。