From b510dd5c2e4eb6c33be1e047e00991ce51d6aec0 Mon Sep 17 00:00:00 2001 From: Henry Gessau Date: Mon, 1 Jun 2015 13:52:18 -0400 Subject: [PATCH] Devref for out-of-tree plugin/driver contribution Change-Id: I6198acce97409e0e87520a31f2749b62d607e9c1 --- doc/source/devref/contribute.rst | 820 ++++++++++++++++++------------- 1 file changed, 485 insertions(+), 335 deletions(-) diff --git a/doc/source/devref/contribute.rst b/doc/source/devref/contribute.rst index b24366685..a39d011a3 100644 --- a/doc/source/devref/contribute.rst +++ b/doc/source/devref/contribute.rst @@ -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``. + + +Design and Development +---------------------- -Blueprint Spec Submission Strategy +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 +`_) +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 +`_ +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. - -Once again, for submitting the integration module to the Neutron codebase, -no spec is required. - -Development Strategy --------------------- +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. -* 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 `_ and `LBaaS A10 driver `_. - -* 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. +* You should run unit tests in your own external library (e.g. on + git.openstack.org where Jenkins setup is for free). + +* 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: + + * 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. - - 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. - -Review and Defect Management Strategies ---------------------------------------- - -The usual process applies to the code that is part of OpenStack Neutron. More -precisely: - -* 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. + third-party CI jobs is likely to generate community goodwill. + + 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. + + +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 +`_: + +- How should security your issues be managed? + +The OpenStack Vulnerability Management Team (VMT) follows a `documented process +`_ 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 +`_. 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 +`_. 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 +`_. 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. + Backport Management Strategies ------------------------------ -As outlined in the `Spec proposal `_ -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 `_. The possible -scenarios are: - -* 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. +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. + 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 `_. -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. - -Having said that, most Neutron plugins developed in the past likely already have -integration with DevStack in the form of `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: - - :: - - INSTALL_FROM_REQUIREMENTS=$(trueorfalse True INSTALL_FROM_REQUIREMENTS) - - 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 -`_, -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 `_. 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 -`_ 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 `_ uses them. For more details see `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 +`Extras.d Hooks' externally hosted plugins +`_. +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. + +One final consideration is worth making for third-party CI setups: if `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 +`_ +uses them. For more details see `devstack-vm-gate-wrap.sh +`_. + + +Project Initial Setup +--------------------- + +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 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 `_. +* Create a repository on git.openstack.org (see `Official Sub-Projects + `_). 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 + `_. * Ask for a Launchpad user to be assigned to the core team created. Steps are - documented in - `this section `_. -* 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 `_. + documented in `this section + `_. +* 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 + `_. * 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 `_ to get one. -* TODO(armax): ... - - -Decomposition progress chart -============================ - -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: - -* 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: - - * [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. - -+-------------------------------+-----------------------+-----------+------------------+---------+--------------+ -| Name | Plugins/Drivers | Launchpad | PyPI | State | Completed in | -+===============================+=======================+===========+==================+=========+==============+ -| freescale-nscs | ml2,fw | no | no | [D] | | -+-------------------------------+-----------------------+-----------+------------------+---------+--------------+ +* Create third-party CI account: if you do not already have one, follow + instructions for `third-party CI + `_ to get + one. + + +Integrating with the Neutron system +----------------------------------- + +(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.) + +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. + + +Existing Shims +~~~~~~~~~~~~~~ + +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 +`_ (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 `_ 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 + `_?). 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 +`_. + + +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. -- 2.45.2