Jump to: navigation, search

Oslo/CreatingANewLibrary

< Oslo
Revision as of 21:24, 12 February 2014 by Sergey Lukjanov (talk | contribs) (Configure Zuul to Run Jobs)

Creating an Initial Repository for Import

There are three sources for new Oslo libraries:

  1. Incubated code that is graduating.
  2. A brand new library.
  3. An existing library that we are adopting.

These subsections cover incubated code and new libraries. Existing libraries can skip ahead to "Importing the Repository into the CI System" below.

Choosing a Name

Oslo libraries are either named "oslo.something" or just "something". The oslo prefix is reserved for libraries which are expected to only be of use to OpenStack developers. Libraries that may be useful outside of OpenStack should have more generic names not already in use on the Python Package Index (https://pypi.python.org/pypi).

Creating a Library from Scratch

Project Management

Libraries using the "oslo" name prefix should use the Oslo project on launchpad for tracking bugs and blueprints: http://launchpad.net/oslo

Other libraries should register their own project and teams. (need more details here)

Git Repository

All OpenStack projects should use one of our cookiecutter templates for creating an initial repository to hold the source for the project.

 pip install cookiecutter

Choose the right template:

The template in openstack-dev/cookiecutter is suitable for libraries not sharing the oslo namespace package.

 cookiecutter https://git.openstack.org/openstack-dev/cookiecutter

The template in openstack-dev/oslo-cookiecutter should be used for libraries that are sharing the oslo namespace package.

 cookiecutter https://git.openstack.org/openstack-dev/oslo-cookiecutter

The output will be a new directory containing a project skeleton, ready to have your real project files added. This directory needs to be turned into a git repository that can be imported into the CI system in later steps. The simplest way to do that is to push a copy to github or other public git server.

 cd projectname
 git init .
 git add .
 git commit -m "set up project with cookiecutter template"
 # add your project files
 git remote add origin git@github.com:username/projectname.git
 git push -u origin master

It is best if the repository is not imported into the CI system until all of the relevant tests pass, since failing tests prevent other changes from being merged.

Graduating a Library from the Incubator

Graduating a library is a multi-step process. It isn't complicated, but there are a lot of details that are easy to miss. Please tread carefully.

The goal with incubated code is to extract it from the incubator with all of its history, and publish the results as a new library. A lot of that process is automated, but there are inevitably some manual steps -- especially to ensure that the tests work properly.

Updating the Incubator

Update oslo-incubator/MAINTAINERS:

Set the status of the module(s) to "Graduating".

Verify all of the correct names and contact details are present.

Extracting a Clean Copy of the History

Start by checking out a copy of the oslo-incubator to use for running the tool:

 cd /tmp
 mkdir graduation
 cd graduation
 git clone git://git.openstack.org/openstack/oslo-incubator

Now clone a second copy of the repository to be edited:

 git clone git://git.openstack.org/openstack/oslo-incubator oslo.i18n

The graduation script works by editing the git history of the current repository, removing commits that do not touch the files you want to keep. It then rearranges the resulting files and sets up the oslo package namespace. To do these things, it needs to know the name of the new library being created and the names of the files you wish to keep.

 cd oslo.i18n
 ../oslo-incubator/tools/graduate.sh i18n openstack/common/gettextutils.py tests/unit/test_gettext.py

The script is fairly I/O intensive, and will take a while to run. It logs all of its output to /tmp/oslo-graduate.XXXX/output.log, and other scratch files are kept in the same directory.

Manual Fixes

It is not possible to completely automate the process of reorganizing the library code and ensuring that it will work, so there are several manual tasks to be performed next.

  1. Add missing dependencies
  2. Fix broken imports within the current repository resulting from files being renamed
  3. Make sure the tests run -- not just make sure tox passes, make sure it is actually running the tests (moving files around makes this break silently some times)
  4. Test the new library with some of the projects that use the incubator version now

Publish Your Results

When you have a clean version of the library, publish it to a public git repository (e.g., on github). This copy of the project history will be used in subsequent steps.

Receive Oslo Team Sign-off

Before proceeding to import the library into the OpenStack CI system, post to the openstack-dev mailing list asking for the Oslo team to review the public repository.

Importing the Repository into the CI System

openstack-infra/config

These instructions are based on the steps for creating a new Stackforge project with some variations, and apply to changes made in the openstack-infra/config git repository.

All of the changes described in this section should be submitted together as one patchset. Refer to https://review.openstack.org/#/c/70435/ for an example.

Add the project to the master project list

Edit modules/openstack_project/files/review.projects.yaml to add a new section like:

 - project: openstack/project-name
   description: Latest and greatest cloud stuff.
   group: oslo
   upstream: git://github.com/awesumsauce/project-name.git

The projects in the file need to be listed in alphabetical order.

Provide a very brief description of the library, especially if it is not named oslo.something-obvious

Set the "group" to "oslo" to use https://launchpad.net/oslo for tracking bugs and milestones. For libraries with existing launchpad projects, set the "group" to the name of the launchpad project.

Set the "upstream" URL to the repository created earlier. If the existing library being imported is already on stackforge, the import can be handled by renaming the repository instead of using the upstream URL, so leave that line out.

Add Gerrit permissions

Each project should have 2 groups. The first, "project-name-core", is the normal core group, with permission to +2 changes. The other, "project-name-milestone", is a (usually smaller) group able to push tags to trigger releases.

Create modules/openstack_project/files/gerrit/acls/openstack/project-name.config:

 [access "refs/heads/*"]
       label-Code-Review = -2..+2 group project-name-core
       label-Approved = +0..+1 group project-name-core
       workInProgress = group project-name-core
 [access "refs/heads/milestone-proposed"]
       label-Code-Review = -2..+2 group project-name-milestone
       label-Approved = +0..+1 group project-name-milestone
 [access "refs/tags/*"]
       create = group project-name-milestone
       pushTag = group project-name-milestone
 [receive]
       requireChangeId = true
       requireContributorAgreement = true
 [submit]
       mergeContent = true

Add Basic Jenkins Jobs

Establish the standard Python jobs, including publishing releases to PyPI and pre-release tarballs to tarballs.openstack.org.

Edit modules/openstack_project/files/jenkins_job_builder/config/projects.yaml to add:

- project:
   name: project-name
   github-org: openstack
   node: precise
   tarball-site: tarballs.openstack.org
   doc-publisher-site: docs.openstack.org
   jobs:
     - python-jobs
     - openstack-publish-jobs
     - pypi-jobs

Configure Zuul to Run Jobs

Zuul is the gate keeper. It watches for changes in gerrit to trigger the appropriate jobs. To start, establish the rules for the basic jobs already configured, but not the full devstack-gate jobs.

Edit modules/openstack_project/files/zuul/layout.yaml to add a section like:

 - name: openstack/project-name
   template:
     - name: python-jobs
     - name: openstack-server-publish-jobs
   check:
     - gate-project-name-python33
     - gate-project-name-pypy
     - gate-project-name-requirements
   gate:
     - gate-project-name-python33
     - gate-project-name-pypy
     - gate-project-name-requirements
   pre-release:
     - project-name-tarball
   release:
     - project-name-tarball:
       - project-name-pypi-upload:
         - post-mirror-python26
         - post-mirror-python27
         - post-mirror-python33

You can find more info about job templates in he beginning of modules/openstack_project/files/zuul/layout.yaml in section "project-templates:".

For projects with documentation hosted on readthedocs.org, include "hook-project-name-rtfd" under the post, pre-release, and release groups.

Wait Here

The rest of the process needs this initial import to finish, so coordinate with the Infra team, and read ahead, but don't do any of these other steps until the import is complete and the new repository is configured.

Update the Gerrit Group Members

Once the review is approved and groups are created, Ask the Infra team to add you to both groups in gerrit, and then you can add other members.

The "oslo-core" group should be added to every sub-project core list (as a group, not individually).

The project PTL and Oslo PTL, at least, should be added to "project-name-milestone", and other developers who understand the release process can volunteer to be added as well.

Add Project to the Requirements Mirror List

The global requirements repository (openstack/requirements) controls which packages are available in the PyPI mirror used for the CI system. It also automatically contributes updates to the requirements lists for OpenStack projects when the global requirements change.

Edit the projects.txt file to add the new library, adding "openstack/project-name" in the appropriate place in alphabetical order.

Refer to https://review.openstack.org/#/c/35845/ for an example.

Add Project to the Governance Repository

Each project managed by an official program in OpenStack needs to be listed in reference/programs.yaml in the openstack/governance repository to indicate who owns the project so we know where ATCs voting rights extend.

Find the "Common Libraries" section in reference/programs.yaml and add the new project to the list of "other" projects under Oslo. (No Oslo projects are designated as core right now.)

Common Libraries:
  codename: Oslo
  ptl: Doug Hellmann (dhellmann)
  mission:
    To produce a set of python libraries containing code shared by OpenStack
    projects. The APIs provided by these libraries should be high quality,
    stable, consistent, documented and generally applicable.
  url: https://wiki.openstack.org/wiki/Oslo
  projects:
    other:
    - openstack/oslo-incubator
    - openstack/oslo.config
    - openstack/oslo.messaging
    - openstack/oslo.rootwrap
    - openstack/oslo.sphinx
    - openstack/oslo.version
    - openstack-dev/cookiecutter
    - openstack-dev/hacking
    - openstack-dev/pbr

Add the Project to the Oslo Library List

Edit Oslo wiki page to add the new project to the list of libraries we maintain. Include a brief description.

Verify That Gerrit and the Test Jobs are Working

The next step is to verify that you can submit a change request for the repository, the tests run successfully, you have permission to approve changes, and the release process works.

Add a .gitreview File to the Repository

The review plugin for git looks in the root of the repository to find a .gitreview file with location instructions for interacting with gerrit to submit change requests, pull down changes for review, etc. Adding this file to your repository now allows you to verify all of the review machinery works, without potentially having issues because of a more complicated changeset.

Check out a clean copy of your new repository and in the root directory of the checkout add a .gitreview file containing:

[gerrit]
host=review.openstack.org
port=29418
project=openstack/project-name.git

Prepare the changeset and submit it with "git review".

Wait for the various test suites to run and for Jenkins to verify the changeset.

Approve the change (or have another core reviewer do it).

Wait for the test and merge jobs to run successfully.

Prepare an Initial Release

Make Your Library Useful

Before going any farther, make the library do something useful.

If you are importing an existing library with features, you can go ahead.

If you are creating a brand new library, add some code and tests to provide some minimal functionality useful to another project.

Give OpenStack Permission to Publish Releases

New libraries without any releases need to be manually registered on PyPI.

If you already have PyPI credentials, visit https://pypi.python.org/pypi?%3Aaction=submit_form and fill in only the required fields.

If you do not have PyPI credentials, you can either create them or ask an Oslo dev who has them to handle this step for you.

Next your project needs to be updated so the "openstackci" user has "Owner" permissions.

Visit https://pypi.python.org/pypi?:action=role_form&package_name=project-name and add "openstackci" in the "User Name" field, set the role to Owner, and click "Add Role".


PyPI-role-maintenance.png

Tagging a Release

To verify that the release machinery works, push a signed tag to the "gerrit" remote. Use the smallest version number possible. If this is the first release, use 0.1. If other releases of the library exist, choose an appropriate next version number using the semantic versioning rules.

Run:

 git tag -s -m "descriptive message" $version
 git push gerrit $version

Wait a little while for the pypi job to run and publish the release.

If you need to check the logs, you can use the "git-os-job" plugin (https://pypi.python.org/pypi/git-os-job):

 git os-job $version

Marking Incubator Obsolete

After the first successful release of a newly graduated library, the status of the module(s) should be updated to "Obsolete." During this phase, only critical bug fixes will be allowed in the incubator version of the code. New features and minor bugs should be fixed in the released library, and effort should be spent focusing on having downstream projects consume the library.

Allowing Other OpenStack Projects to Use Your Library

OpenStack projects share a common global requirements list so that all components can be installed together on the same system. To allow other projects to use your library, you need to update that requirements list.

Update the Global Requirements List

Check out the openstack/requirements git repository and modify global-requirements.txt to add the new library.

See https://review.openstack.org/#/c/35845/ for an example.

Setting up Gate Testing

The devstack gate jobs install all OpenStack projects from source so that the appropriate git revisions (head, or revisions in the merge queue) are tested together. To include the new library in these tests, it needs to be included in the list of projects in the devstack gate wrapper script. For the same feature to work for developers outside of the gate, the project needs to be added to the Oslo portion of devstack.

Updating devstack-vm-gate-wrap.sh

Check out openstack-infra/devstack-gate and edit devstack-vm-gate-wrap.sh to add the new project:

 PROJECTS="openstack/project-name $PROJECTS"

Keep the list in alphabetical order.

See https://review.openstack.org/#/c/72487/ for an example.

Wait for these changes to be accepted before proceeding.

Updating devstack

Check out openstack-dev/devstack.

Edit lib/oslo to add a variable defining where the source should go:

 NEWPROJECT_DIR=$DEST/newproject

Edit the "install_oslo()" function in lib/oslo to add commands to check out the repository:

 function install_oslo() {
   ...
   git_clone $NEWPROJECT_REPO $NEWPROJECT_DIR $NEWPROJECT_BRANCH
   setup_develop $NEWPROJECT_DIR
   ...
 }

Edit stackrc to add the other variables needed for configuring the new library:

 # new-project
 NEWPROJECT_REPO=${NEWPROJECT_REPO:-${GIT_BASE}/openstack/new-project.git}
 NEWPROJECT_BRANCH=${NEWPROJECT_BRANCH:-master}

See https://review.openstack.org/#/c/72437/ for an example.

Wait for these changes to be accepted before proceeding.

Adding Symmetric Gating with the Rest of OpenStack

add the appropriate gate jobs in openstack-infra/config

Update Consuming Projects

Now that the library is fully integrated with the rest of the OpenStack test infrastructure, projects can be updated to use it safely. Send email to the openstack-dev mailing list notifying the community that the library is available and ready for use.

Coordinate with the development teams for each project to find a time in their dev cycle when they can work with you on the update and review the necessary changes.


Checklist

  1. Create Initial Repository
    1. Graduation
      1. Update MAINTAINERS in incubator with status and name
      2. Run graduate.sh
      3. Fix the output of graduate.sh
    2. New Project
      1. Use cookiecutter template to make a new project
      2. Publish git repo
  2. Oslo team review new repository
  3. openstack-infra/config
    1. modules/openstack_project/files/review.projects.yaml
    2. modules/openstack_project/files/gerrit/acls/stackforge/project-name.config
    3. modules/openstack_project/files/jenkins_job_builder/config/projects.yaml
    4. modules/openstack_project/files/zuul/layout.yaml
  4. Update Gerrit Groups
  5. openstack/requirements projects.txt
  6. openstack/governance reference/programs.yaml
  7. Oslo library list
  8. .gitreview
  9. Make the library do something
  10. Give openstackci Owner permissions on PyPI
  11. Tag a release
  12. Mark graduated code obsolete in oslo-incubator
  13. openstack/requirements global-requirements.txt
  14. openstack-infra/devstack-gate devstack-vm-gate-wrap.sh
  15. openstack-dev/devstack
    1. lib/oslo
    2. stackrc
  16. Update consumers