Devref for out-of-tree plugin/driver contribution

Change-Id: I6198acce97409e0e87520a31f2749b62d607e9c1
This commit is contained in:
Henry Gessau 2015-06-01 13:52:18 -04:00
parent 211c035577
commit b510dd5c2e

View File

@ -1,6 +1,19 @@
Contributing new extensions to Neutron
======================================
**NOTE!**
---------
**Third-party plugins/drivers which do not start decomposition in Liberty will
be marked as deprecated, and they will be removed before the Mxxx-3
milestone.**
Read on for details ...
Introduction
------------
Neutron has a pluggable architecture, with a number of extension points.
This documentation covers aspects relevant to contributing new Neutron
v2 core (aka monolithic) plugins, ML2 mechanism drivers, and L3 service
@ -16,22 +29,44 @@ within the OpenStack Networking project. If you are a developer who
wants to provide a Neutron-based solution without interacting with the
Neutron community, you are free to do so, but you can stop reading now,
as this guide is not for you.
In fact, from the Kilo release onwards, the Neutron core team propose that
additions to the codebase adopt a structure where the *monolithic plugins*,
*ML2 MechanismDrivers*, and *L3 service plugins* are integration-only
(called "vendor integration" hereinafter) to code that lives outside the
tree (called "vendor library" hereinafter); the same applies for any
vendor-specific agents. The only part that is to stay in the tree is the
agent 'main' (a small python file that imports agent code from the vendor
library and starts it). 'Outside the tree' can be anything that is publicly
available: it may be a stackforge repo for instance, a tarball, a pypi package,
etc. A plugin/drivers maintainer team self-governs in order to promote sharing,
reuse, innovation, and release of the 'out-of-tree' deliverable. It should not
be required for any member of the core team to be involved with this process,
Plugins and drivers for non-reference implementations are known as
"third-party" code. This includes code for supporting vendor products, as well
as code for supporting open-source networking implementations.
Before the Kilo release these plugins and drivers were included in the Neutron
tree. During the Kilo cycle the third-party plugins and drivers underwent the
first phase of a process called decomposition. During this phase, each plugin
and driver moved the bulk of its logic to a separate git repository, while
leaving a thin "shim" in the neutron tree together with the DB models and
migrations (and perhaps some config examples).
During the Liberty cycle the decomposition concept was taken to its conclusion
by allowing third-party code to exist entirely out of tree. Further extension
mechanisms have been provided to better support external plugins and drivers
that alter the API and/or the data model.
In the Mxxx cycle we will **require** all third-party code to be moved out of
the neutron tree completely.
'Outside the tree' can be anything that is publicly available: it may be a repo
on git.openstack.org for instance, a tarball, a pypi package, etc. A
plugin/drivers maintainer team self-governs in order to promote sharing, reuse,
innovation, and release of the 'out-of-tree' deliverable. It should not be
required for any member of the core team to be involved with this process,
although core members of the Neutron team can participate in whichever capacity
is deemed necessary to facilitate out-of-tree development.
Below, the following strategies will be documented:
This guide is aimed at you as the maintainer of code that integrates with
Neutron but resides in a separate repository.
Contribution Process
--------------------
If you want to extend OpenStack Networking with your technology, and you want
to do it within the visibility of the OpenStack project, follow the guidelines
and examples below. We'll describe best practices for:
* Design and Development;
* Testing and Continuous Integration;
@ -40,105 +75,61 @@ Below, the following strategies will be documented:
* DevStack Integration;
* Documentation;
This document will then provide a working example on how to contribute
new additions to Neutron.
Once you have everything in place you may want to add your project to the list
of Neutron sub-projects. Submit a patch via a gerrit review to neutron to add
your project to ``doc/source/devref/sub_projects.rst``.
Blueprint Spec Submission Strategy
Design and Development
----------------------
Assuming you have a working repository, any development to your own repo does
not need any blueprint, specification or bugs against Neutron. However, if your
project is a part of the Neutron Stadium effort, you are expected to
participate in the principles of the Four Opens, meaning your design should be
done in the open. Thus, it is encouraged to file documentation for changes in
your own repository.
If your code is hosted on git.openstack.org then the gerrit review system is
automatically provided. Contributors should follow the review guidelines
similar to those of Neutron. However, you as the maintainer have the
flexibility to choose who can approve/merge changes in your own repo.
It is recommended (but not required, see `policies
<http://docs.openstack.org/developer/neutron/policies/thirdparty-ci.html>`_)
that you set up a third-party CI system. This will provide a vehicle for
checking the third-party code against Neutron changes. See `Testing and
Continuous Integration`_ below for more detailed recommendations.
Design documents can still be supplied in form of Restructured Text (RST)
documents, within the same third-party library repo. If changes to the common
Neutron code are required, an `RFE
<http://docs.openstack.org/developer/neutron/policies/blueprints.html#neutron-request-for-feature-enhancements>`_
may need to be filed. However every case is different and you are invited to
seek guidance from Neutron core reviewers about what steps to follow.
Testing and Continuous Integration
----------------------------------
Provided contributors adhere to the abovementioned development footprint
they should not be required to follow the spec process for changes that
only affect their vendor integration and library. New contributions can
simply be submitted for code review, with the proviso that adequate
documentation and 3rd CI party is supplied at the time of the code
submission. For tracking purposes, the review itself can be tagged
with a Launchpad bug report. The bug should be marked as wishlist to
avoid complicating tracking of Neutron's primary deliverables. Design
documents can still be supplied in form of RST documents, within the same
vendor library repo. If substantial change to the common Neutron code are
required, a spec that targets common Neutron code will be required, however
every case is different and a contributor is invited to seek guidance from
the Neutron core team as to what steps to follow, and whether a spec or
a bug report is more suited for what a contributor needs to deliver.
The following strategies are recommendations only, since third-party CI testing
is not a enforced requirement. However, these strategies are employed by the
majority of the plugin/driver contributors that actively participate in the
Neutron development community, since they have learned from experience how
quickly their code can fall out of sync with the rapidly changing Neutron core
code base.
Once again, for submitting the integration module to the Neutron codebase,
no spec is required.
* You should run unit tests in your own external library (e.g. on
git.openstack.org where Jenkins setup is for free).
Development Strategy
--------------------
* Your third-party CI should validate third-party integration with Neutron via
functional testing. The third-party CI is a communication mechanism. The
objective of this mechanism is as follows:
* The following elements are suggested to be contributed in the tree
for plugins and drivers (called vendor integration hereinafter):
* Data models
* Extension definitions
* Configuration files
* Requirements file targeting vendor code
* Things that do not remain in the tree (called vendor library hereinafter):
* Vendor specific logic
* Associated unit tests
The idea here would be to provide in-tree the plugin/driver code that
implements an API, but have it delegate to out-of-tree code for
backend-specific interactions. The vendor integration will then typically
involve minor passthrough/parsing of parameters, minor handling of DB objects
as well as handling of responses, whereas the vendor library will do the
heavylifting and implement the vendor-specific logic. The boundary between
the in-tree layer and the out-of-tree one should be defined by the contributor
while asking these types of questions:
* If something changes in my backend, do I need to alter the integration
layer drastically? Clearly, the less impact there is, the better the
separation being achieved.
* If I expose vendor details (e.g. protocols, auth, etc.), can I easily swap
and replace the targeted backend (e.g. hardware with a newer version
being supplied) without affecting the integration too much? Clearly, the
more reusable the integration the better the separation.
As mentioned above, the vendor code *must* be available publicly, and a git
repository makes the most sense. By doing so, the module itself can be made
accessible using a pip requirements file. This file should not be confused
with the Neutron requirements file that lists all common dependencies. Instead
it should be a file 'requirements.txt' that is located in neutron/plugins/pluginXXX/,
whose content is something along the lines of 'my_plugin_xxx_library>=X.Y.Z'.
Vendors are responsible for ensuring that their library does not depend on
libraries conflicting with global requirements, but it could depend on
libraries not included in the global requirements. Just as in Neutron's
main requirements.txt, it will be possible to pin the version of the vendor
library.
For instance, a vendor integration module can become as simple as one that
performs only the following:
* Registering config options
* Registering the plugin class
* Registering the models
* Registering the extensions
Testing Strategy
----------------
The testing process will be as follow:
* No unit tests for the vendor integration of plugins and drivers are deemed
necessary. The expectation is that contributors would run unit test in their
own external library (e.g. in stackforge where Jenkins setup is for free).
For unit tests that validate the vendor library, it is the responsibility of
the vendor to choose what CI system they see fit to run them. There is no
need or requirement to use OpenStack CI resources if they do not want to.
Having said that, it may be useful to provide coverage for the shim layer in
the form of basic validation as done in `ODL <https://git.openstack.org/cgit/openstack/networking-odl/tree/networking_odl/tests/unit/ml2/test_mechanism_odl.py>`_ and `LBaaS A10 driver <https://git.openstack.org/cgit/openstack/neutron-lbaas/tree/neutron_lbaas/tests/unit/services/loadbalancer/drivers/a10networks/test_driver_v1.py>`_.
* 3rd Party CI will continue to validate vendor integration with Neutron via
functional testing. 3rd Party CI is a communication mechanism. This objective
of this mechanism is as follows:
* it communicates to plugin/driver contributors when someone has contributed
a change that is potentially breaking. It is then up to a given
contributor maintaining the affected plugin to determine whether the
failure is transient or real, and resolve the problem if it is.
* it communicates to you when someone has contributed a change that
potentially breaks your code. It is then up to you maintaining the affected
plugin/driver to determine whether the failure is transient or real, and
resolve the problem if it is.
* it communicates to a patch author that they may be breaking a plugin/driver.
If they have the time/energy/relationship with the maintainer of the
plugin/driver in question, then they can (at their discretion) work to
@ -146,69 +137,104 @@ The testing process will be as follow:
* it communicates to the community at large whether a given plugin/driver
is being actively maintained.
* A maintainer that is perceived to be responsive to failures in their
3rd party CI jobs is likely to generate community goodwill.
third-party CI jobs is likely to generate community goodwill.
It is worth noting that if the vendor library is hosted on StackForge, due to
current openstack-infra limitations, it is not possible to have 3rd party CI systems
participating in the gate pipeline for the StackForge repo. This means that the only
validation provided during the merge process to the StackForge repo is through unit
tests. Post-merge hooks can still be exploited to provide 3rd party CI feedback, and
alert the contributor/reviewer of potential issues. As mentioned above, 3rd party CI
systems will continue to validate Neutron core commits. This will allow them to
detect when incompatible changes occur, whether they are in Neutron or in the vendor
library repo.
It is worth noting that if the plugin/driver repository is hosted on
git.openstack.org, due to current openstack-infra limitations, it is not
possible to have third-party CI systems participating in the gate pipeline
for the repo. This means that the only validation provided during the merge
process to the repo is through unit tests. Post-merge hooks can still be
exploited to provide third-party CI feedback, and alert you of potential
issues. As mentioned above, third-party CI systems will continue to validate
Neutron core commits. This will allow them to detect when incompatible
changes occur, whether they are in Neutron or in the third-party repo.
Review and Defect Management Strategies
---------------------------------------
The usual process applies to the code that is part of OpenStack Neutron. More
precisely:
Defect Management
-----------------
Bugs affecting third-party code should *not* be filed in the Neutron project on
launchpad. Bug tracking can be done in any system you choose, but by creating a
third-party project in launchpad, bugs that affect both Neutron and your code
can be more easily tracked using launchpad's "also affects project" feature.
Security Issues
~~~~~~~~~~~~~~~
Here are some answers to how to handle security issues in your repo, taken
from `this openstack-dev mailing list message
<http://lists.openstack.org/pipermail/openstack-dev/2015-July/068617.html>`_:
- How should security your issues be managed?
The OpenStack Vulnerability Management Team (VMT) follows a `documented process
<https://security.openstack.org/vmt-process.html>`_ which can basically be
reused by any project-team when needed.
- Should the OpenStack security team be involved?
The OpenStack VMT directly oversees vulnerability reporting and disclosure for
a `subset of OpenStack source code repositories
<https://wiki.openstack.org/wiki/Security_supported_projects>`_. However they
are still quite happy to answer any questions you might have about
vulnerability management for your own projects even if they're not part of that
set. Feel free to reach out to the VMT in public or in private.
Also, the VMT is an autonomous subgroup of the much larger `OpenStack Security
project-team
<http://governance.openstack.org/reference/projects/security.html>`_. They're a
knowledgeable bunch and quite responsive if you want to get their opinions or
help with security-related issues (vulnerabilities or otherwise).
- Does a CVE need to be filed?
It can vary widely. If a commercial distribution such as Red Hat is
redistributing a vulnerable version of your software then they may assign one
anyway even if you don't request one yourself. Or the reporter may request one;
the reporter may even be affiliated with an organization who has already
assigned/obtained a CVE before they initiate contact with you.
- Do the maintainers need to publish OSSN or equivalent documents?
OpenStack Security Advisories (OSSA) are official publications of the OpenStack
VMT and only cover VMT-supported software. OpenStack Security Notes (OSSN) are
published by editors within the OpenStack Security project-team on more general
security topics and may even cover issues in non-OpenStack software commonly
used in conjunction with OpenStack, so it's at their discretion as to whether
they would be able to accommodate a particular issue with an OSSN.
However, these are all fairly arbitrary labels, and what really matters in the
grand scheme of things is that vulnerabilities are handled seriously, fixed
with due urgency and care, and announced widely -- not just on relevant
OpenStack mailing lists but also preferably somewhere with broader distribution
like the `Open Source Security mailing list
<http://oss-security.openwall.org/wiki/mailing-lists/oss-security>`_. The goal
is to get information on your vulnerabilities, mitigating measures and fixes
into the hands of the people using your software in a timely manner.
- Anything else to consider here?
The OpenStack VMT is in the process of trying to reinvent itself so that it can
better scale within the context of the "Big Tent." This includes making sure
the policy/process documentation is more consumable and reusable even by
project-teams working on software outside the scope of our charter. It's a work
in progress, and any input is welcome on how we can make this function well for
everyone.
* Bugs that affect vendor code can be filed against the Neutron integration,
if the integration code is at fault. Otherwise, the code maintainer may
decide to fix a bug without oversight, and update their requirements file
to target a new version of their vendor library. It makes sense to
require 3rd party CI for a given plugin/driver to pass when changing their
dependency before merging to any branch (i.e. both master and stable branches).
* Vendor specific code should follow the same review guidelines as any other
code in the tree. However, the maintainer has flexibility to choose who
can approve/merge changes in this repo.
Backport Management Strategies
------------------------------
As outlined in the `Spec proposal <http://specs.openstack.org/openstack/neutron-specs/specs/kilo/core-vendor-decomposition.html>`_
all new plugins and drivers will have to follow the contribution model
described here. As for existing plugins and drivers, no in-tree features can
be merged until some progress has been done to make the solution adhere to
this model. That said, there is the question of critical fixes and/or backports
to `stable branches <https://wiki.openstack.org/wiki/StableBranch>`_. The possible
scenarios are:
This section applies only to third-party maintainers who had code in the
Neutron tree during the Kilo and earlier releases. It will be obsolete once the
Kilo release is no longer supported.
If a change made to out-of-tree third-party code needs to be back-ported to
in-tree code in a stable branch, you may submit a review without a
corresponding master branch change. The change will be evaluated by core
reviewers for stable branches to ensure that the backport is justified and that
it does not affect Neutron core code stability.
* The decomposition just completed, we are in the cycle (X) where the decomposition
initiated: in this case, the Neutron master branch no longer have the vendor
library code, but the stable branch still does. Backports via straight
cherry-picks may not be possible, or as easy, therefore a custom backport to
stable could be deemed acceptable to Neutron's stable branches (e.g. stable/X-1
and/or stable/X-2), as required.
* The decomposition is complete, we are in the next cycle where the
decomposition work completed (X+1): backports will be done to the stable branch
available of the vendor library (stable/X), and Neutron's stable branch
(stable/X-1), as outlined in the previous step.
* The decomposition is complete, we are in two or more cycles after the
decomposition work completed (X+2, or later). Backports will be done to the
stable branch(s) available of the vendor library (stable/X, stable/X+1).
* The decomposition is in progress: as long as the vendor code is still in
master, patches will need to go to master before a backport to stable.
Acceptance will be determined on the scope of changes (based on both the
amount of work and severity of the issue). In this case, the plugin or
driver maintainer will need to ensure that the fix gets applied to the
external repo, if necessary (to avoid missing it during the migration process).
* The decomposition has not started: in this case, depending on the issue,
review attention from core members is best effort, and although there is no
explicit rule to prevent them from merging to master, it is in the best interest
of the maintainer to avoid introducing or modifying existing code that will
ultimately be deprecated.
DevStack Integration Strategies
-------------------------------
@ -221,79 +247,34 @@ make sense depending on whether you are contributing a new or existing plugin or
driver.
If you are contributing a new plugin, the approach to choose should be based on
`Extras.d Hooks' externally hosted plugins <http://docs.openstack.org/developer/devstack/plugins.html#extras-d-hooks>`_.
With the extra.d hooks, the DevStack integration is colocated with the vendor integration
library, and it leads to the greatest level of flexibility when dealing with DevStack based
dev/test deployments.
`Extras.d Hooks' externally hosted plugins
<http://docs.openstack.org/developer/devstack/plugins.html#extras-d-hooks>`_.
With the extra.d hooks, the DevStack integration is co-located with the
third-party integration library, and it leads to the greatest level of
flexibility when dealing with DevStack based dev/test deployments.
Having said that, most Neutron plugins developed in the past likely already have
integration with DevStack in the form of `neutron_plugins <https://git.openstack.org/cgit/openstack-dev/devstack/tree/lib/neutron_plugins>`_.
If the plugin is being decomposed in vendor integration plus vendor library, it would
be necessary to adjust the instructions provided in the neutron_plugin file to pull the
vendor library code as a new dependency. For instance, the instructions below:
One final consideration is worth making for third-party CI setups: if `Devstack
Gate <https://git.openstack.org/cgit/openstack-infra/devstack-gate>`_ is used,
it does provide hook functions that can be executed at specific times of the
devstack-gate-wrap script run. For example, the `Neutron Functional job
<https://git.openstack.org/cgit/openstack-infra/project-config/tree/jenkins/jobs/neutron.yaml>`_
uses them. For more details see `devstack-vm-gate-wrap.sh
<https://git.openstack.org/cgit/openstack-infra/devstack-gate/tree/devstack-vm-gate-wrap.sh>`_.
::
INSTALL_FROM_REQUIREMENTS=$(trueorfalse True INSTALL_FROM_REQUIREMENTS)
Project Initial Setup
---------------------
if [[ "$INSTALL_FROM_REQUIREMENTS" == "False" ]]; then
git_clone $NEUTRON_LIB_REPO $NEUTRON_LIB_DIR $NEUTRON_LIB_BRANCH
setup_package $NEUTRON_LIB_DIR
else
# Retrieve the package from the vendor library's requirements.txt
plugin_package=$(cat $NEUTRON_LIB_REQUIREMENTS_FILE)
pip_install "$plugin_package"
fi
could be placed in 'neutron_plugin_configure_service', ahead of the service
configuration. An alternative could be under the `third_party section
<https://git.openstack.org/cgit/openstack-dev/devstack/tree/lib/neutron_thirdparty>`_,
if available. This solution can be similarly exploited for both monolithic
plugins or ML2 mechanism drivers. The configuration of the plugin or driver itself can be
done by leveraging the extensibility mechanisms provided by `local.conf <http://docs.openstack.org/developer/devstack/configuration.html>`_. In fact, since the .ini file for the vendor plugin or driver lives
in the Neutron tree, it is possible to do add the section below to local.conf:
::
[[post-config|$THE_FILE_YOU_NEED_TO_CUSTOMIZE]]
# Override your section config as you see fit
[DEFAULT]
verbose=True
Which in turn it is going to edit the file with the options outlined in the post-config
section.
The above mentioned approach, albeit valid, has the shortcoming of depending on DevStack's
explicit support for the plugin installation and configuration, and the plugin maintainer
is strongly encouraged to revise the existing DevStack integration, in order to evolve it
in an extras.d hooks based approach.
One final consideration is worth making for 3rd party CI setups: if `Devstack Gate
<https://git.openstack.org/cgit/openstack-infra/devstack-gate>`_ is used, it does provide hook
functions that can be executed at specific times of the devstack-gate-wrap script run.
For example, the `Neutron Functional job <https://git.openstack.org/cgit/openstack-infra/project-config/tree/jenkins/jobs/neutron.yaml>`_ uses them. For more details see `devstack-vm-gate-wrap.sh <https://git.openstack.org/cgit/openstack-infra/devstack-gate/tree/devstack-vm-gate-wrap.sh>`_.
Documentation Strategies
------------------------
It is the duty of the new contributor to provide working links that can be
referenced from the OpenStack upstream documentation.
#TODO(armax): provide more info, when available.
How-to
------
The how-to below assumes that the vendor library will be hosted on StackForge.
Stackforge lets you tap in the entire OpenStack CI infrastructure and can be
a great place to start from to contribute your new or existing driver/plugin.
The list of steps below are somewhat the tl;dr; version of what you can find
on http://docs.openstack.org/infra/manual/creators.html. They are meant to
The how-to below assumes that the third-party library will be hosted on
git.openstack.org. This lets you tap in the entire OpenStack CI infrastructure
and can be a great place to start from to contribute your new or existing
driver/plugin. The list of steps below are summarized version of what you can
find on http://docs.openstack.org/infra/manual/creators.html. They are meant to
be the bare minimum you have to complete in order to get you off the ground.
* Create a public repository: this can be a personal git.openstack.org repo or any
publicly available git repo, e.g. ``https://github.com/john-doe/foo.git``. This
would be a temporary buffer to be used to feed the StackForge one.
would be a temporary buffer to be used to feed the one on git.openstack.org.
* Initialize the repository: if you are starting afresh, you may *optionally*
want to use cookiecutter to get a skeleton project. You can learn how to use
cookiecutter on https://git.openstack.org/cgit/openstack-dev/cookiecutter.
@ -301,104 +282,273 @@ be the bare minimum you have to complete in order to get you off the ground.
want to skip this step now, build the history first (next step), and come back
here to initialize the remainder of the repository with other files being
generated by the cookiecutter (like tox.ini, setup.cfg, setup.py, etc.).
* Building the history: if you are contributing an existing driver/plugin,
you may want to preserve the existing history. If not, you can go to the
next step. To import the history from an existing project this is what
you need to do:
* Clone a copy of the neutron repository to be manipulated.
* Go into the Neutron repo to be changed.
* Execute file split.sh, available in ./tools, and follow instructions.
::
git clone https://git.openstack.org/openstack/neutron.git
cd neutron
./tools/split.sh
# Sit and wait for a while, or grab a cup of your favorite drink
At this point you will have the project pruned of everything else but
the files you want to export, with their history. The next steps are:
* Check out stable branches for the project: even though stable branches
are not strictly necessary during the creation of the StackForge repository
(as outlined in the next step below), they do not hurt, and it is
recommended to keep them during the import process.
* Add a remote that points to the repository created before.
* (Optional) If the repository has already being initialized with
cookiecutter, you need to pull first; if not, you can either push
the existing commits/tags or apply and commit further changes to fix
up the structure of repo the way you see fit.
* Finally, push commits and tags to the public repository. If you followed
theses instructions step-by-step, you will have a source repository
that contains both a master and stable branches, as well as tags. Some
of these steps are outlined below:
::
git remote add <foo> https://github.com/john-doe/foo.git
git pull foo master # OPTIONAL, if foo is non-empty
git push --all foo && git push --tags foo
* Create a StackForge repository: for this you need the help of the OpenStack
infra team. It is worth noting that you only get one shot at creating the
StackForge repository. This is the time you get to choose whether you want
to start from a clean slate, or you want to import the repo created during
the previous step. In the latter case, you can do so by specifying the
upstream section for your project in project-config/gerrit/project.yaml.
Steps are documented on the
`Repository Creator's Guide <http://docs.openstack.org/infra/manual/creators.html>`_.
* Create a repository on git.openstack.org (see `Official Sub-Projects
<http://docs.openstack.org/developer/neutron/devref/sub_projects.html>`_). For
this you need the help of the OpenStack infra team. It is worth noting that
you only get one shot at creating the repository on git.openstack.org. This
is the time you get to choose whether you want to start from a clean slate,
or you want to import the repo created during the previous step. In the
latter case, you can do so by specifying the upstream section for your
project in project-config/gerrit/project.yaml. Steps are documented on the
`Repository Creator's Guide
<http://docs.openstack.org/infra/manual/creators.html>`_.
* Ask for a Launchpad user to be assigned to the core team created. Steps are
documented in
`this section <http://docs.openstack.org/infra/manual/creators.html#update-the-gerrit-group-members>`_.
* Fix, fix, fix: at this point you have an external base to work on. You
can develop against the new stackforge project, the same way you work
with any other OpenStack project: you have pep8, docs, and python27 CI
jobs that validate your patches when posted to Gerrit. For instance, one
thing you would need to do is to define an entry point for your plugin
or driver in your own setup.cfg similarly as to how it is done
`here <https://git.openstack.org/cgit/openstack/networking-odl/tree/setup.cfg#n31>`_.
documented in `this section
<http://docs.openstack.org/infra/manual/creators.html#update-the-gerrit-group-members>`_.
* Fix, fix, fix: at this point you have an external base to work on. You can
develop against the new git.openstack.org project, the same way you work with
any other OpenStack project: you have pep8, docs, and python27 CI jobs that
validate your patches when posted to Gerrit. For instance, one thing you
would need to do is to define an entry point for your plugin or driver in
your own setup.cfg similarly as to how it is done in the `setup.cfg for ODL
<https://git.openstack.org/cgit/openstack/networking-odl/tree/setup.cfg#n31>`_.
* Define an entry point for your plugin or driver in setup.cfg
* Create 3rd Party CI account: if you do not already have one, follow
instructions for
`3rd Party CI <http://docs.openstack.org/infra/system-config/third_party.html>`_ to get one.
* TODO(armax): ...
* Create third-party CI account: if you do not already have one, follow
instructions for `third-party CI
<http://docs.openstack.org/infra/system-config/third_party.html>`_ to get
one.
Decomposition progress chart
============================
Integrating with the Neutron system
-----------------------------------
The chart below captures the progress of the core-vendor-decomposition effort
for existing plugins and drivers at the time the decomp effort started. New
drivers and plugins are not required to be listed here. This chart is short
lived: once the effort is complete, this chart no longer needs to exist and
will be removed. The following aspects are captured:
(This section currently describes the goals and progress of the completion of
the decomposition work during the Liberty development cycle. The content here
will be updated as the work progresses. In its final form this section will be
merged with the previous section. When all existing plugins/drivers are fully
decomposed, this document will be a recipe for how to add a new Neutron plugin
or driver completely out-of-tree.)
* Name: the name of the project that implements a Neutron plugin or driver. The
name is an internal target for links that point to source code, etc.
* Plugins/Drivers: whether the source code contains a core (aka monolithic)
plugin, a set of ML2 drivers, and/or (service) plugins (or extensions) for
firewall, vpn, and load balancers.
* Launchpad: whether the project is managed through Launchpad.
* PyPI: whether the project deliverables are available through PyPI.
* State: a code to represent the current state of the decomposition. Possible
values are:
For the Liberty cycle we aim to move all the existing third-party code out of
the Neutron tree. Each category of code and its removal plan is described
below.
* [A] External repo available, no code decomposition
* [B] External repo available, partial code decomposition
* [C] External repo available, code decomposition is complete
* [D] Not deemed required. Driver is already bare-bone and decomposition
effort is not considered justified. Assessment may change in the
future.
Absence of an entry for an existing plugin or driver means no active effort
has been observed or potentially not required.
* Completed in: the release in which the effort is considered completed. Code
completion can be deemed as such, if there is no overlap/duplication between
what exists in the Neutron tree, and what it exists in the vendor repo.
Existing Shims
~~~~~~~~~~~~~~
+-------------------------------+-----------------------+-----------+------------------+---------+--------------+
| Name | Plugins/Drivers | Launchpad | PyPI | State | Completed in |
+===============================+=======================+===========+==================+=========+==============+
| freescale-nscs | ml2,fw | no | no | [D] | |
+-------------------------------+-----------------------+-----------+------------------+---------+--------------+
Liberty Steps
+++++++++++++
The existing shims shall now be moved out of tree, together with any test
code. The entry points shall be moved as described below in `Entry Points`_.
Configuration Files
~~~~~~~~~~~~~~~~~~~
The ``data_files`` in the ``[files]`` section of ``setup.cfg`` of Neutron shall
not contain any third-party references. These shall be located in the same
section of the third-party repo's own ``setup.cfg`` file.
* Note: Care should be taken when naming sections in configuration files. When
the Neutron service or an agent starts, oslo.config loads sections from all
specified config files. This means that if a section [foo] exists in multiple
config files, duplicate settings will collide. It is therefore recommended to
prefix section names with a third-party string, e.g. [vendor_foo].
Liberty Steps
+++++++++++++
Third-party configuration files still in the neutron tree have no dependencies
and can simply be moved. The maintainers should add their configuration file(s)
to their repo and then remove them from neutron.
**ToDo: Inclusion in OpenStack documentation?**
Is there a recommended way to have third-party config options listed in the
configuration guide in docs.openstack.org?
Database Models and Migrations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A third-party repo may contain database models for its own tables. Although
these tables are in the Neutron database, they are independently managed
entirely within the third-party code. Third-party code shall **never** modify
neutron core tables in any way.
Each repo has its own alembic migration branch that adds, removes and modifies
its own tables in the neutron database schema.
* Note: Care should be taken when adding new tables. To prevent collision of
table names it is recommended to prefix them with a vendor/plugin string.
* Note: A third-party maintainer may opt to use a separate database for their
tables. This may complicate cases where there are foreign key constraints
across schemas for DBMS that do not support this well. Third-party maintainer
discretion advised.
The database tables owned by a third-party repo can have references to fields
in neutron core tables. However, the alembic branch for a plugin/driver repo
shall never update any part of a table that it does not own.
**Note: What happens when a referenced item changes?**
* **Q:** If a driver's table has a reference (for example a foreign key) to a
neutron core table, and the referenced item is changed in neutron, what
should you do?
* **A:** Fortunately, this should be an extremely rare occurrence. Neutron core
reviewers will not allow such a change unless there is a very carefully
thought-out design decision behind it. That design will include how to
address any third-party code affected. (This is another good reason why you
should stay actively involved with the Neutron developer community.)
The ``neutron-db-manage`` alembic wrapper script for neutron detects alembic
branches for installed third-party repos, and the upgrade command automatically
applies to all of them. A third-party repo must register its alembic migrations
at installation time. This is done by providing an entrypoint in setup.cfg as
follows:
For a third-party repo named ``networking-foo``, add the alembic_migrations
directory as an entrypoint in the ``neutron.db.alembic_migrations`` group::
[entry_points]
neutron.db.alembic_migrations =
networking-foo = networking_foo.db.migration:alembic_migrations
Liberty Steps
+++++++++++++
Each decomposed plugin/driver that has its own tables in the neutron database
should take these steps to move the models for the tables out of tree.
#. Add the models to the external repo.
#. Create a start migration for the repo's alembic branch. Note: it is
recommended to keep the migration file(s) in the same location in the
third-party repo as is done in the neutron repo,
i.e. ``networking_foo/db/migration/alembic_migrations/versions/*.py``
#. Remove the models from the neutron repo.
#. Add the names of the removed tables to ``DRIVER_TABLES`` in
``neutron/db/migration/alembic_migrations/external.py`` (this is used for
testing, see below).
**ToDo: neutron-db-manage autogenerate**
The alembic autogenerate command needs to support branches in external
repos. Bug #1471333 has been filed for this.
DB Model/Migration Testing
~~~~~~~~~~~~~~~~~~~~~~~~~~
Here is a `template functional test
<https://bugs.launchpad.net/neutron/+bug/1470678>`_ (TODO:Ann) third-party
maintainers can use to develop tests for model-vs-migration sync in their
repos. It is recommended that each third-party CI sets up such a test, and runs
it regularly against Neutron master.
Liberty Steps
+++++++++++++
The model_sync test will be updated to ignore the models that have been moved
out of tree. A ``DRIVER_TABLES`` list will be maintained in
``neutron/db/migration/alembic_migrations/external.py``.
Entry Points
~~~~~~~~~~~~
The `Python setuptools <https://pythonhosted.org/setuptools>`_ installs all
entry points for packages in one global namespace for an environment. Thus each
third-party repo can define its package's own ``[entry_points]`` in its own
``setup.cfg`` file.
For example, for the ``networking-foo`` repo::
[entry_points]
console_scripts =
neutron-foo-agent = networking_foo.cmd.eventlet.agents.foo:main
neutron.core_plugins =
foo_monolithic = networking_foo.plugins.monolithic.plugin:FooPluginV2
neutron.service_plugins =
foo_l3 = networking_foo.services.l3_router.l3_foo:FooL3ServicePlugin
neutron.ml2.type_drivers =
foo_type = networking_foo.plugins.ml2.drivers.foo:FooType
neutron.ml2.mechanism_drivers =
foo_ml2 = networking_foo.plugins.ml2.drivers.foo:FooDriver
neutron.ml2.extension_drivers =
foo_ext = networking_foo.plugins.ml2.drivers.foo:FooExtensionDriver
* Note: It is advisable to include ``foo`` in the names of these entry points to
avoid conflicts with other third-party packages that may get installed in the
same environment.
API Extensions
~~~~~~~~~~~~~~
Extensions can be loaded in two ways:
#. Use the ``append_api_extensions_path()`` library API. This method is defined
in ``neutron/api/extensions.py`` in the neutron tree.
#. Leverage the ``api_extensions_path`` config variable when deploying. See the
example config file ``etc/neutron.conf`` in the neutron tree where this
variable is commented.
Interface Drivers
~~~~~~~~~~~~~~~~~
Interface (VIF) drivers for the reference implementations are defined in
``neutron/agent/linux/interface.py``. Third-party interface drivers shall be
defined in a similar location within their own repo.
The entry point for the interface driver is a Neutron config option. It is up to
the installer to configure this item in the ``[default]`` section. For example::
[default]
interface_driver = networking_foo.agent.linux.interface.FooInterfaceDriver
**ToDo: Interface Driver port bindings.**
These are currently defined by the ``VIF_TYPES`` in
``neutron/extensions/portbindings.py``. We could make this config-driven
for agents. For Nova, selecting the VIF driver can be done outside of
Neutron (using the new `os-vif python library
<https://review.openstack.org/193668>`_?). Armando and Akihiro to discuss.
Rootwrap Filters
~~~~~~~~~~~~~~~~
If a third-party repo needs a rootwrap filter for a command that is not used by
Neutron core, then the filter shall be defined in the third-party repo.
For example, to add a rootwrap filters for commands in repo ``networking-foo``:
* In the repo, create the file:
``etc/neutron/rootwrap.d/foo.filters``
* In the repo's ``setup.cfg`` add the filters to data_files::
[files]
data_files =
etc/neutron/rootwrap.d =
etc/neutron/rootwrap.d/foo.filters
Extending python-neutronclient
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The maintainer of a third-party component may wish to add extensions to the
Neutron CLI client. Thanks to https://review.openstack.org/148318 this can now
be accomplished. See `Client Command Extensions
<client_command_extensions.html>`_.
Other repo-split items
~~~~~~~~~~~~~~~~~~~~~~
(These are still TBD.)
* Splitting policy.json? **ToDo** Armando will investigate.
* Generic instructions (or a template) for installing an out-of-tree plugin or
driver for Neutron. Possibly something for the networking guide, and/or a
template that plugin/driver maintainers can modify and include with their
package.
Decomposition Phase II Progress Chart
=====================================
TBD.