Browse Source

This repository is now retired

The Release Management Team ceased using this months ago. Its
contents are replaced with a retirement notice so that potential
users will realize it is no longer maintained. Publicly announced

Change-Id: Ia30884174c43ef1c1afcc1f4a18b3c0051a89d8e
Jeremy Stanley 4 years ago
  1. 60
  2. 4
  3. 4
  4. 176
  5. 925
  6. 101
  7. 63
  8. 109
  9. 21
  10. 152
  11. 147
  12. 64
  13. 61
  14. 151
  15. 23
  16. 198
  17. 225
  18. 119
  19. 145
  20. 60
  21. 56
  22. 64
  23. 49
  24. 76
  25. 111
  26. 2
  27. 215
  28. 45
  29. 27
  30. 18
  31. 2337
  32. 4
  33. 203
  34. 170
  35. 1364
  36. 7
  37. 1446
  38. 28
  39. 41
  40. 21
  41. 296
  42. 292
  43. 315
  44. 320
  45. 298
  46. 296
  47. 290
  48. 292
  49. 295
  50. 299
  51. 296
  52. 39
  53. 49
  54. 78
  55. 80
  56. 34
  57. 57
  58. 34
  59. 35
  60. 43
  61. 46
  62. 63
  63. 49
  64. 29
  65. 43
  66. 352
  67. 292
  68. 410
  69. BIN
  70. BIN
  71. 2671
  72. BIN
  73. BIN
  74. BIN
  75. BIN
  76. BIN
  77. 395
  78. 10220
  79. 201
  80. 4961
  81. 9
  82. 99
  83. 68
  84. 80
  85. 2
  86. 10
  87. BIN
  88. BIN
  89. BIN
  90. 45
  91. BIN
  92. BIN
  93. BIN
  94. BIN
  95. BIN
  96. BIN
  97. BIN
  98. BIN
  99. BIN
  100. BIN
  101. Some files were not shown because too many files have changed in this diff Show More

.gitignore vendored

@ -1,60 +0,0 @@
# C extensions
# Packages
# Installer logs
# Unit test / coverage reports
# Translations
# Mr Developer
# Complexity
# Sphinx
# pbr generates these
# Editors
# local temporary directory


@ -1,4 +0,0 @@


@ -1,4 +0,0 @@
test_command=OS_STDOUT_CAPTURE=1 OS_STDERR_CAPTURE=1 OS_TEST_TIMEOUT=60 ${PYTHON:-python} -m discover -t ./ . $LISTOPT $IDOPTION
test_id_option=--load-list $IDFILE


@ -1,176 +0,0 @@
Apache License
Version 2.0, January 2004
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
implied, including, without limitation, any warranties or conditions
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.


@ -1,919 +1,10 @@
openstack-releasing - A set of scripts to handle OpenStack release process
This project is no longer maintained.
How to Release
The contents of this repository are still available in the Git
source code management system. To see the contents of this
repository before it reached its end of life, please check out the
previous commit with "git checkout HEAD^1".
Deliverables should all be using post-versioning, getting their version
information from git tags and not having any version specifier in the
Release requests are filed as patches to deliverables files in
the ``openstack/releases`` repository, see the README there for more
Before beginning this process, you need to set up ``gpg`` with a valid
key, and authorize launchpad to run the release tools
commands. Authorizing launchpad can be tricky on a system that only
provides a terminal-based browser, since the launchpad site does not
work well with the default configuration of ``lynx`` (cookies and
referrer headers need to be enabled for the launchpad site). Newer
versions of launchpadlib also rely on keyring, which may require a
password for every command being run if you are not in a graphical
environment with a better interactive key manager. Talk with dhellmann
if you start a release and run into trouble with launchpad auth.
When a release request is ready to be approved, follow these steps:
#. The release team member taking responsibility for the
release should approve the change in ``openstack/releases``.
Release requests should not be approved until we are actually ready
to cut the release.
#. After the release request merges, check out or update a local copy
of ``openstack/releases`` to get the new version of the file under
the ``deliverables`` directory. Make sure you check out the
releases repository to the commit with the new release request you
want to process, in case multiple requests merge around the same
time. The release tools only look at the most recent commit to
detect which deliverable files have changed.
#. Check out or update a local copy of
``openstack-infra/project-config`` repository, which contains the
tools for tagging a release.
#. Change directories to
#. Create or update a virtualenv and install all of the dependencies
for the release tools using
as the basis.
For example::
$ virtualenv .venv
$ source .venv/bin/activate
$ pip install -U -r requirements.txt
#. Run ````, giving the path to the
``openstack/releases`` repository.
For example::
$ ./ ~/repos/openstack/releases
#. As the release script runs, it will prompt you for your GPG key
passphrase before adding the tag. This gives you a last chance to
review the proposed tag before proceeding. After the tag is created
locally and pushed up to the remote server, the script will push
comments to closed Launchpad bugs since the previous tag.
#. Announce the release.
1. Milestones are manually announced once all projects are done
(usually at the closing of the milestone window), using an email
recapitulating all projects that did a milestone tag and
pointing to milestone tarballs. The process to follow for
announcements of releases will be added here soon.
2. Library and tool releases are announced via one of the OpenStack
mailing lists. See the instructions for running
The prerequisites for all of the scripts are defined in
Each shell script should try to create a Python virtualenv to install
the packages before running any of the commands written in Python. If
you start seeing import errors after updating your sandbox, it is
likely that a new dependency was added. Try removing ``.tox/venv`` and
running the command again.
Top-level scripts
The top-level scripts call the various base tools to get their work done.
.. note::
The scripts involved in tagging releases have moved from this
repository to
Final release for pre-versioned components follows a slightly different
process. Just before RC1 we need to create a stable/* release branch. creates a stable/$SERIES branch from the specified SHA, and turns
all Launchpad bugs for the RC1 milestone to FixReleased (which means
"present in the release branch").
It supports deliverables with multiple repositories, using an additional
parameter to point to the main deliverable (in which case it skips Launchpad
update). It special-cases oslo-incubator, where it doesn't wait for a tarball
to be built.
./ 7432f32d838ab346c liberty nova
Create a series/liberty branch for Nova at commit 7432f32d838ab346c, and
mark FixCommitted bugs FixReleased, while targeting them to the juno-rc1
./ 3472368b3a546d liberty neutron-fwaas neutron
Create a series/liberty branch for neutron-fwaas at commit 3472368b3a546d.
This script is used for pre-versioned projects to publish RCs and final
release from the stable/$SERIES branch. It applies the RC or final tag,
pushes it, waits for the tarball build, and uploads the resulting
tarball to Launchpad (while marking it released).
It supports deliverables with multiple repositories, using an additional
parameter to point to the main deliverable (in which case it uploads to the
main Launchpad page). It special-cases oslo-incubator, where no tarball is
generated or needs to be uploaded.
./ kilo rc1 cinder
Push 2015.1.0rc1 tag to current cinder stable/kilo branch HEAD, wait for
the tarball build, and upload the resulting tarball to Launchpad (while
marking it released).
./rcdelivery kilo final neutron-fwaas neutron
Push 2015.1.0 final tag to current neutron-fwaas stable/kilo branch HEAD
(which should be the last RC), wait for the tarball build, and upload the
resulting tarball to the "neutron" Launchpad page.
This produces a set of release notes intended to be sent as an
announcement email when a new library or package is produced. It is
more suitable for libraries than for the major projects, because it
includes a list of all of the changes and diff-stats output to show
which files changed.
The script parses the README.rst to find a line matching "``Bugs:``",
extracts the URL following the colon, and includes that information in
the output.
The bugs URL is converted to a launchpad project URL and combined with
the final version number to produce a *milestone* URL.
The script uses ``python`` to determine the project name and
the one-line description to include in the output text.
release-notes ~/repos/openstack/oslo.config 1.7.0 1.8.0
Print the release notes between versions 1.7.0 and 1.8.0 for the
project in the ``~/repos/openstack/oslo.config`` directory.
release-notes --show-dates --changes-only ~/repos/openstack/oslo.config 1.8.0 HEAD
Print the list of changes after 1.8.0 for the project in the
``~/repos/openstack/oslo.config`` directory, including the date of
the change but leaving out the email message boilerplate. This mode
is useful for examining the list of unreleased changes in a project
to decide if a release is warranted and to pick a version number.
Test or configure the launchpad credentials. This will set up a
keyring entry for the launchpad site, prompt for credentials, and
handle the OAuth handshake. All of the other launchpad-connected
commands will do these steps, too, but this command takes no other
action after logging in so it is safe to run it repeatedly.
Script to check the current list of constraints against the most
recent release for all of the library projects. This script can be
used at any point, but is especially intended to ensure that the
constraints for things we release are all updated at the end of a
release cycle. To run the script, check out both the release-tools and
requirements repositories and then run the script as::
$ /path/to/requirements-repository stable/mitaka
Tool to report on the status of milestone tags for projects using the
cycle-with-milestone release model.
$ milestone-checkup ~/repos/openstack/releases newton 2
training-labs (Documentation)
did not find /home/dhellmann/repos/openstack/releases/deliverables/newton/training-labs.yaml
aodh (Telemetry)
did not find /home/dhellmann/repos/openstack/releases/deliverables/newton/aodh.yaml
ceilometer (Telemetry)
did not find /home/dhellmann/repos/openstack/releases/deliverables/newton/ceilometer.yaml
astara (astara)
Base tools
Marks a Launchpad milestone as released and sets it inactive so no
more bugs or blueprints can be targeted to it.
milestone-close oslotest 1.8.0
Renames a Launchpad milestone.
milestone-rename oslo.rootwrap next-juno 1.3.0
Rename oslo.rootwrap next-juno milestone to 1.3.0.
Converts milestone code names (juno-1) to version numbers suitable for tags
(2014.2.b1). If used with --onlycheck, only checks that the milestone
exists in Launchpad (useful for Swift where the rules are different).
./ nova kilo-3
Returns 2015.1.0b3 (after checking that the kilo-3 milestone exists in Nova)
./ swift 2.1.0 --onlycheck
Exists successfully if there is a 2.1.0 milestone in Swift.
This script fetches a specific branch from a git repository into a temp
directory and compares its content with the content of a tarball produced
from it (using "python sdist"). The difference should only contain
additional generated files (Changelog, AUTHORS...) and missing ignored
files (.gitignore...).
./ nova master
Check the difference between Nova master branch contant and a tarball
that would be generated from it.
Download published tarballs and compare them against what is produced
by running the sdist command locally. This can be used to verify that
a tarball published for download was built correctly and has not been
./ openstack/nova 13.0.0
Given a release series, download and validate all of the tarballs to
ensure that they match what was tagged.
./ ~/repos/openstack/releases mitaka
This script fetches opened bugs for a project in order to prepare bugs with no
activity in the last D days for expiration by:
- unsetting bug assignee
- unsetting bug milestone
- setting bug status to Incomplete
- adding a comment explaining why we updated the bug
./ neutron --days 180
Prepare for expiration neutron bugs with no activity not updated in the last
180 days.
./ glance --days 365 --test
Test prepare for expiration on Launchpad Staging servers.
./ glance --days 365 --dry-run
Prepare for expiration dry-run: print actions without executing them.
Closes *Launchpad* bug reports which are older than the oldest stable release
(usually 18 months, see ``DAYS_SINCE_CREATED``). It ignores bug reports which:
* have a special comment (see constant ``STILL_VALID_FLAG``).
* have the status ``In Progress``
* have the importance ``Wishlist``
By default it uses a *dry-run* to not accidentally close bug reports. You
have to use a flag to make it a real execution.
Closed bug reports will have:
* status = ``Won't Fix``
* assignee = ``None``
* importance = ``Undecided``
* a comment which explains *why* this was done.
./ nova --verbose
Show which bug reports of *Nova* **would be** expired (a dry-run is the
./ nova --no-dry-run
Actually expire old bug reports of *Nova*.
./ nova --no-dry-run --credentials-file cred.txt
Use a credentials file to expire bug reports (see `launchpad-login`_).
export LP_CREDS_FILE=path/to/my/lp/credentials/files/cred.txt
./ nova --no-dry-run
Use an environment variable to access the credentials file instead of the
``--credentials-file`` flag.
This script fetches bugs for a project (by default all "FixCommitted" bugs,
or all open bugs targeted to a given milestone if you pass the --milestone
argument) and sets a milestone target for them (--settarget) and/or sets their
status to "Fix Released" (--fixrelease).
It ignores bugs that have already a milestone set, if that milestone does
not match the one in --settarget.
./ nova --settarget=grizzly-3 --fixrelease
Sets the target for all Nova FixCommitted bugs to grizzly-3 and mark
them 'Fix Released'.
./ glance --settarget=grizzly-2 --status='Fix Released' --test
Test setting the target for all untargeted Glance FixReleased bugs to
grizzly-2 on Launchpad Staging servers.
./ neutron --milestone juno-3 --settarget juno-rc1
Move all juno-3 open bugs from juno-3 to juno-rc1 milestone.
This script queries Jenkins tarball-building jobs to find either a job
matching the provided --mpsha SHA building milestone-proposed.tar.gz,
or a job matching the provided --tag. It then waits for that job completion
and reports the built tarball name.
./ cinder --mpsha=59089e56f674f5f94f67c5986e9a616bb669d846
Looks for a cinder-branch-tarball job matching SHA 59089e... which would
produce a milestone-proposed.tar.gz tarball, and waits for completion
./ cinder --tag=2013.1.1
Looks for a cinder-tarball job for tag "2013.1.1" and waits for completion.
This script grabs a tarball from and uploads it
to Launchpad, marking the milestone released and inactive in the process.
If used with the --nop argument, it will only mark the milestone released and
inactive (this is used for projects like oslo-incubator which do not release
source code).
The script prompts you to confirm that the tarball looks like the one you
intend to release, and to sign the tarball upload.
./ nova 2015.1.0 --milestone=kilo-3
Uploads Nova's nova-2015.1.0b3.tar.gz to the kilo-3 milestone page.
./ glance 2015.1.0 --test
Uploads Glance's glance-2015.1.0.tar.gz to the final "2015.1.0" milestone
as glance-2015.1.0.tar.gz, on Launchpad staging server
./ cinder 2012.2.3 --tarball=stable-folsom
Uploads Cinder's current cinder-stable-folsom.tar.gz to the 2012.2.3
milestone as cinder-2012.2.3.tar.gz
This script moves blueprints and bugs from interim milestones to the final
release milestone page, in order to show all bugs and features fixed during
the cycle. For Swift, this will only move X-rc* bugs and blueprints to
final X release.
The --copytask mode is an experimental variant where a series bugtask is
created and the release milestone is set on that bugtask, preserving the
information from the "development" bugtask (and the milestone the bug was
fixed in).
./ cinder kilo 2015.1.0
Moves Cinder blueprints and bugs from intermediary kilo milestones
to the final 2015.1 milestone page.
./ --test swift grizzly 1.8.0
Moves Swift 1.8.0-rc* blueprints and bugs to the final 1.8.0 page, on
Launchpad staging server
./ --copytask glance kilo 2015.1.0
Moves Glance blueprints from intermediary kilo milestones to the final
2015.1.0 milestone page. Creates kilo series task for all grizzly bugs
and sets the milestone for those to 2015.1.0.
This script lets you create milestones in Launchpad in bulk. It is given a
YAML description of the milestone dates and the projects to add milestones
to. The script is idempotent and can safely be run multiple times. See
create_milestones.sample.yaml for an example configuration file.
milestones-create havana.yaml
This script lets you create one series and milestone in Launchpad. The
script is idempotent and can safely be run multiple times.
milestone-ensure oslo.config liberty next-liberty
This experimental script facilitates setting blueprint fields for approved
specs. It takes the project and blueprint name as arguments. For specs that
are still under review (--in-review) it will set them to "Blocked" (and
definition status to Review). For approved specs it will set definition
status to Approved, and set Spec URL. In both cases it will set the target
milestone, approver name and specified priority (by default, 'Low').
./ glance super-spec --milestone=juno-2 --priority=Medium
Glance's super-spec.rst was approved and you want to add it to juno-2,
with Medium priority. This will do it all for you.
./ nova --specpath=specs/kilo/approved/my-awesome-spec.rst
--in-review --milestone=juno-2
Nova's my-awesome-spec.rst is still under review, but you would like to
add the my-awesome-spec blueprint to juno-2 (marked Blocked). Since it's
located in a non-standard path, we specify it using --specpath parameter.
./ nova my-awesome-spec --priority=High
my-awesome-spec is now approved. You want to flip all the approval bits,
but also change its priority to High. There is no need to pass --specpath
again, spec2bp will infer it from the blueprint URL field.
A script that can be used to quickly "freeze" all open reviews to a stable
branch. It may also be used to "thaw" frozen reviews upon re-opening of
the branch for merges. Reviews are frozen by adding a -2 and thawed by
reverting that and adding a 0.
To view open reviews for stable/icehouse 2014.1.4:
./ -r 2014.1.4 query
View open reviews for stable/icehouse 2014.1.4.
./ -r 2014.1.4 -o ~/openstack/2014.1.4-freeze.txt
Freeze all open reviews proposed to stable/icehouse. 2014.1.4-freeze.txt will
contain all frozen reviews and this can be used to thaw later on.
./stable_freeze -r 2014.1.4 -i ~/openstack/2014.1.4-freeze.txt thaw
Thaw all reviews previously frozen and stored in 2014.1.4-freeze.txt.
./stable_freeze -r 2014.1.4 -i ~/openstack/2014.1.4-freeze.txt \
-c 123777 -c 123778 freeze
Freeze individual changes that have been proposed after the stable freeze
period started. References to these reviews will be appended to
2014.1.4-freeze.txt to be unfrozen later on.
A script to periodically clean up blueprints (adjusting series goal based on
target milestone, and optionally kicking unpriotized blueprints from the
milestone. ttx is running it in a cron so you don't have to.
To clean up Nova kilo blueprints::
./ nova kilo
A script to cleanup translations for a release. It updates all
translation source files, downloads translation files and removes
translation files that are not sufficiently translated. It results in
a change that then needs to get reviewed and send to gerrits.
To generate a cleanup patch for nova::
./ kilo nova
Run around milestone release time, this script retrieves and parses the list
of blueprints for a given project and:
* sets the milestone target and series goal on recently-implemented blueprints
* removes the milestone target on incomplete milestone-targeted blueprints
./ nova liberty-1
Displays proposed adjustments around Nova liberty-1 blueprints.
./ nova liberty-1 --target --clean
Targets missing implemented blueprints and cleans incomplete ones for Nova
in liberty-1.
Add a comment to a set of Launchpad bugs. This command requires basic
Launchpad credentials (see launchpad-login).
add-comment --subject='Winner' --content='You won!' 1000000 2000000
Add a 'You won!' comment (with subject line 'Winner') to Launchpad
bugs #1000000 and #2000000
Lift your -2 reviews from a project. Use this after the stable branch has been
created and the project is ready for accept new features.
This tool uses the Gerrit REST API. So you need to provide your username and
password somehow. You probably already have a .gertty.yaml, if not make one.
update_reviews oslo.config
The tool looks for all of the changes in the project that you have a -2 vote on
and changes your vote to 0, with the message "This project is now open for new
List Launchpad bugs mentioned in master commit messages starting from a specified commit.
./ -r ../neutron --start=8.0.0
Use ``--stop`` option to list bugs mentioned in stable branch messages stopping
from a specified commit.
./ -B -r ../neutron --start=8.0.0 --stop=origin/stable/mitaka
Use ``-B`` option to ignore patches that were already backported into all
stable branches.
./ -B -r ../neutron --start=8.0.0
Use ``-e`` option to ignore patches that don't apply cleanly to one of stable
./ -e -r ../neutron --start=8.0.0
Use ``-sb`` option to also include StoryBoard bugs
./ -sb -r ../octavia --start=1.0.0
Reads the list of Launchpad bug numbers on stdin and filters out those of
importance specified. Filtering out Wishlist bugs if importance not specified.
./ [...] --start=8.0.0 | \
./ neutron
List bugs that are fixed in master since 8.0.0 that are not of Wishlist
./ --start=8.0.0 | \
./ neutron | \
./ neutron --importance Low
List bugs that are fixed in master since 8.0.0 that are not of Wishlist or Low
Reads the list of Launchpad bug numbers on stdin and filters out those with
a tag specified.
./ [...] --start=8.0.0 | \
./ neutron --tag in-stable-mitaka
List bugs that are fixed in master since 8.0.0 that don't have relevant fixes
merged in stable/mitaka.
Reads the list of Launchpad bug numbers on stdin and writes out a nice and
detailed description for each of them.
./ [...] --start=8.0.0 | ./ neutron
Pull in detailed description for bugs that are fixed in master since 8.0.0.
Clean up <*>-backport-potential tags for bugs with in-stable-<*> tag set.
./ neutron python-neutronclient
Append a tag to bugs specified on stdin.
./ [...] --start=8.0.0 | ./ foo-tag
This command will add the 'foo-tag' tag to all bugs fixed since 8.0.0.
Reads the list of StoryBoard story numbers on stdin, filters out stories
matching a tag.
./ [...] -sb --start=1.0.0 | \
./ in-stable-pike
List stories fixed in master since 1.0.0 that do not have relevant fixes merged
in stable/pike.
Appends a tag to stories specified on stdin.
./ [...] -sb --start=1.0.0 | \
./ foo-tag
This command will add the 'foo-tag' tag to all stories fixed since 1.0.0.
End of Life
The ```` script is provided to end-of-life branches. It
will abandon any changes on the to-be-removed branch, create a
``branch-eol`` tag at the current branch ``HEAD`` and then remove the
To run the script, ensure you are either in the "Release Managers"
group or a gerrit admin. add yourself to "Project Bootstrappers"
temporarily in ```` (note: this is a gerrit
limitation with branch deletion permissions. This may not be required
in the future). Be careful and remember to remove yourself at the end
to avoid accidental changes.
Usually the release team will have provided the branches to remove
grouped by project in an easy to use format. The command goes
something like:: -- stable/oldbranch oldbranch-eol openstack/project1 openstack/python-project1
It's usually best to run under ``screen`` and save the log file in
case of unintended consequences.
gpg tips
Tags will be signed, so ensure ``gpg`` is setup correctly for password
caching or you will have to type your password a lot. ``gpg2`` has
better support for ``gpg-agent``, so ``git config --global gpg.program
gpg2`` will probably just "do the right thing" (note if you're
migrating from ``gpg``, you may need to import your keys with
``gpg2 --import < ~/.gnupg/secreing.gpg``).
For any further questions, please email or join #openstack-release on


@ -1,101 +0,0 @@
# Copyright 2015 Thierry Carrez <>
# All Rights Reserved.
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from __future__ import print_function
import argparse
import datetime
import sys
import launchpadlib.launchpad
import pytz
# Parameters
parser = argparse.ArgumentParser(description="Update BPs on milestone closure")
parser.add_argument('project', help='The project to act on')
parser.add_argument('milestone', help='The milestone to set')
parser.add_argument("--target", action='store_true',
help='Set target and/or series goal for implemented BPs')
parser.add_argument("--clear", action='store_true',
help='Clear milestone from incomplete blueprints')
parser.add_argument("--test", action='store_const', const='staging',
default='production', help='Use LP staging server to test')
args = parser.parse_args()
# Connect to Launchpad
print("Connecting to Launchpad...")
launchpad = launchpadlib.launchpad.Launchpad.login_with('openstack-releasing',
args.test, version='devel')
project = launchpad.projects[args.project]
milestone = project.getMilestone(name=args.milestone)
if not milestone:
parser.error('Target milestone %s does not exist' % args.milestone)
series = milestone.series_target
# Get the blueprints
print("Retrieving blueprints...")
now =
to_clear = []
to_series = []
to_target = []
count = 0
bps = project.all_specifications
numbps = len(bps)
# Also get the series-targeted approved blueprints
seriesbps = series.valid_specifications
print("retrieved %d blueprints" % numbps)
# Parse the blueprints
print("Parsing blueprints...")
for bp in bps:
count = count + 1
sys.stdout.write("\r%d%%" % int(count * 100 / numbps))
if ((bp.implementation_status == 'Implemented') and
((now - bp.date_completed) < datetime.timedelta(days=92)) and
(not bp.milestone or not bp.milestone.date_targeted or
bp.milestone.date_targeted >= milestone.date_targeted)):
if bp not in seriesbps:
if bp.milestone != milestone:
elif not bp.is_complete and bp.milestone == milestone:
if (to_target):
print("Those are implemented: need milestone target added")
for bp in to_target:
bp.milestone = milestone
if (to_series):
print("Those are implemented: need series goal added/approved")
for bp in to_series:
if (to_clear):
print("Those are incomplete: need their milestone target cleared")
for bp in to_clear:
if args.clear:
bp.milestone = None


@ -1,63 +0,0 @@
#!/usr/bin/env python
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
This tool will transform bug numbers into proper Launchpad links.
import argparse
import sys
from launchpadlib.launchpad import Launchpad
def _parse_args():
parser = argparse.ArgumentParser(
description='Dump useful bug info.')
'project', help='Launchpad project name')
return parser.parse_args()
def _annotate_bug(lp, project, bugnum):
bug = lp.bugs[bugnum]
for task in bug.bug_tasks:
if task.bug_target_name == project:
assignee = if task.assignee else 'Unassigned'
'%(url)s "%(title)s" (%(importance)s,%(status)s) [%(tags)s] [%(assignee)s]' %
{'url': '' % bugnum,
'title': bug.title,
'importance': task.importance,
'status': task.status,
'tags': ','.join(bug.tags),
'assignee': assignee})
def main():
args = _parse_args()
lp = Launchpad.login_with('openstack-releasing', 'production')
for line in sys.stdin.readlines():
bugnum = line.strip()
_annotate_bug(lp, args.project, bugnum)
if __name__ == '__main__':


@ -1,109 +0,0 @@
# Script to automatically adjust series goal based on target milestone
# in Launchpad blueprints, and possibly remove unprioritized blueprints
# Copyright 2013 Thierry Carrez <>
# All Rights Reserved.
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from __future__ import print_function
import argparse
import sys
import launchpadlib.launchpad
# Parse arguments
parser = argparse.ArgumentParser(description="Adjust blueprint series goal/milestones")
parser.add_argument('projectname', help='Project or projectgroup to act on')
parser.add_argument('seriesname', help='Series to act on')
parser.add_argument('--nokick', action='store_true',
help='Do not kick unprioritized BPs out of milestones')
parser.add_argument('--dryrun', action='store_true',
help='Just show what would be done')
args = parser.parse_args()
kickmessage = ("You should not set a milestone target unless the blueprint"
" has been properly prioritized by the project drivers.")
# Log into LP
lp = launchpadlib.launchpad.Launchpad.login_with('adjust-series-goal', 'production', version='devel')
projectgroup = lp.project_groups[args.projectname]
projects = projectgroup.projects
except (KeyError, AttributeError):
projects = [lp.projects[args.projectname], ]
except KeyError:
print("%s: no such project or projectgroup" % args.projectname)
for project in projects:
print("== %s ==" %
series = project.getSeries(name=args.seriesname)
# Get the milestones for the series
milestones = []
active_milestones = series.active_milestones_collection
except AttributeError:
print("No milestone in series %s for %s, skipping" %
for ms in series.active_milestones_collection:
# Get the blueprints with seriesgoal set
accepted = series.valid_specifications
# Find targeted blueprints that are not in the series
for bp in project.valid_specifications:
if bp.milestone in milestones:
if bp.priority in ["Undefined", "Not"]:
# Blueprint is in milestone but has no priority
if not args.nokick:
print("KICK %s (from %s)" % (,
if not args.dryrun:
bp.milestone = None
if bp.whiteboard is None:
bp.whiteboard = ""
if kickmessage not in bp.whiteboard:
bp.whiteboard += ("\n\n" + kickmessage + "\n")
bp.whiteboard += "(This is an automated message)\n"
if bp not in accepted:
# BP has milestone & prio, but not accepted for series yet
print("SETGOAL %s" %
if not args.dryrun:
# Get the blueprints in the series
proposed = []
for bp in series.all_specifications:
if not bp.is_complete:
if bp.milestone not in milestones:
# Blueprint is in series, no milestone
print("CLEARGOAL %s" %
if not args.dryrun:
if not bp.has_accepted_goal:
if bp.priority not in ["Undefined", "Not"]:
# BP is proposed/declined in series, has mstone + prio
print("APPROVEGOAL %s" %
if not args.dryrun:


@ -1,21 +0,0 @@
# This is a cross-platform list tracking distribution packages needed by tests;
# see for additional information.
dbus-devel [platform:rpm]
dbus-glib-devel [platform:rpm]
language-pack-en [platform:ubuntu]
libffi-dev [platform:dpkg]
libffi-devel [platform:rpm]
libssl-dev [platform:dpkg]
openssl-devel [platform:rpm]
virtual/libffi [platform:gentoo]
locales [platform:debian]
python-dev [platform:dpkg]
python-devel [platform:rpm]
python-libvirt [platform:dpkg]
python3-all-dev [platform:ubuntu !platform:ubuntu-precise]
python3-dev [platform:dpkg]
python3-devel [platform:fedora]
python3.4 [platform:ubuntu-trusty]
python34-devel [platform:centos]
python3.5 [platform:ubuntu-xenial]


@ -1,152 +0,0 @@
#!/usr/bin/env python
# Copyright 2015 Markus Zoeller <>
# All Rights Reserved.
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# +-----+ 1 1..* +----------+
# | bug +----------------> bug_task |
# +--+--+ +-----+----+
# | |
# | |
# | +---------+ |
# +-------> project <-------+
# 1..* +---------+ 1
# One bug has at least 1 bug_task.
# One bug_task belongs to exactly one bug.
# One bug can affect multiple projects
# One bug_task is specific to one project
import argparse
import logging
import os
import launchpadlib.launchpad
# Parameters
parser = argparse.ArgumentParser(description="Cleanup Launchpad (LP) Bugs")
parser.add_argument('projectname', help='The project to act on')
parser.add_argument("--test", action='store_const', const='staging',
default='production', help='Use LP staging server to test')
parser.add_argument("--newbugs", action="store_true",
help="Cleanup inconsistencies in new bugs")
parser.add_argument('exceptions', type=int, nargs='*', help='Bugs to ignore')
parser.add_argument('--dryrun', action='store_true',
help='Do not actually do anything')
parser.add_argument("-v", "--verbose", action="store_true",
help="increase output verbosity")
args = parser.parse_args()
class LaunchpadCleanup(object):
"""Triggers specific cleanups in Launchpad."""
def __init__(self, project_name, server="staging", dryrun=True,
self.project_name = project_name
self.client = self._create_launchpad_client(server)
self.dryrun = dryrun
self.ignoreable_bug_ids = ignoreable_bug_ids"Created launchpad client for server '%s'", server)
if self.dryrun:"That's a dry run, nothing will happen")
def _create_launchpad_client(self, server):
cachedir = os.path.expanduser("~/.launchpadlib/cache/")
if not os.path.exists(cachedir):
os.makedirs(cachedir, 0o0700)