Browse code

refresh the devstack plugin docs, add plugin registry

The devstack plugin docs mostly referred to in tree plugins, which is
honestly something we don't want people doing. Instead restructure the
whole document to talk about external plugins as the only kinds of
plugins, and focus on a workflow to make that easy for people to work
through.

This also adds a plugin-registry page to start listing known plugins
somewhere centrally. Some sample content was added, hopefully people
will submit patches to include their plugins.

This does drop the section on hypervisor plugins. That's not currently
something that we expect a ton of people to work on, so diving into
the code for this should be fine.

Change-Id: Ifc0b831c90a1a45daa507a009d1dcffcd6e2deca

Sean Dague authored on 2015/06/19 21:26:45
Showing 3 changed files
... ...
@@ -10,6 +10,7 @@ DevStack - an OpenStack Community Production
10 10
    overview
11 11
    configuration
12 12
    plugins
13
+   plugin-registry
13 14
    faq
14 15
    changes
15 16
    hacking
16 17
new file mode 100644
... ...
@@ -0,0 +1,73 @@
0
+..
1
+  Note to reviewers: the intent of this file is to be easy for
2
+  community members to update. As such fast approving (single core +2)
3
+  is fine as long as you've identified that the plugin listed actually exists.
4
+
5
+==========================
6
+ DevStack Plugin Registry
7
+==========================
8
+
9
+Since we've created the external plugin mechanism, it's gotten used by
10
+a lot of projects. The following is a list of plugins that currently
11
+exist. Any project that wishes to list their plugin here is welcomed
12
+to.
13
+
14
+Official OpenStack Projects
15
+===========================
16
+
17
+The following are plugins that exist for official OpenStack projects.
18
+
19
++--------------------+-------------------------------------------+--------------------+
20
+|Plugin Name         |URL                                        |Comments            |
21
++--------------------+-------------------------------------------+--------------------+
22
+|magnum              |git://git.openstack.org/openstack/magnum   |                    |
23
++--------------------+-------------------------------------------+--------------------+
24
+|trove               |git://git.openstack.org/openstack/trove    |                    |
25
++--------------------+-------------------------------------------+--------------------+
26
+|zaqar               |git://git.openstack.org/openstack/zarar    |                    |
27
++--------------------+-------------------------------------------+--------------------+
28
+
29
+
30
+
31
+Drivers
32
+=======
33
+
34
++--------------------+-------------------------------------------------+------------------+
35
+|Plugin Name         |URL                                              |Comments          |
36
++--------------------+-------------------------------------------------+------------------+
37
+|dragonflow          |git://git.openstack.org/openstack/dragonflow     |[d1]_             |
38
++--------------------+-------------------------------------------------+------------------+
39
+|odl                 |git://git.openstack.org/openstack/networking-odl |[d2]_             |
40
++--------------------+-------------------------------------------------+------------------+
41
+
42
+.. [d1] demonstrates example of installing 3rd party SDN controller
43
+.. [d2] demonstrates a pretty advanced set of modes that that allow
44
+        one to run OpenDayLight either from a pre-existing install, or
45
+        also from source
46
+
47
+Alternate Configs
48
+=================
49
+
50
++-------------+------------------------------------------------------------+------------+
51
+| Plugin Name | URL                                                        | Comments   |
52
+|             |                                                            |            |
53
++-------------+------------------------------------------------------------+------------+
54
+|glusterfs    |git://git.openstack.org/stackforge/devstack-plugin-glusterfs|            |
55
++-------------+------------------------------------------------------------+------------+
56
+|             |                                                            |            |
57
++-------------+------------------------------------------------------------+------------+
58
+
59
+Additional Services
60
+===================
61
+
62
++-------------+------------------------------------------+------------+
63
+| Plugin Name | URL                                      | Comments   |
64
+|             |                                          |            |
65
++-------------+------------------------------------------+------------+
66
+|ec2-api      |git://git.openstack.org/stackforge/ec2api |[as1]_      |
67
++-------------+------------------------------------------+------------+
68
+|             |                                          |            |
69
++-------------+------------------------------------------+------------+
70
+
71
+.. [as1] first functional devstack plugin, hence why used in most of
72
+         the examples.
... ...
@@ -2,78 +2,83 @@
2 2
 Plugins
3 3
 =======
4 4
 
5
-DevStack has a couple of plugin mechanisms to allow easily adding
6
-support for additional projects and features.
5
+The OpenStack ecosystem is wide and deep, and only growing more so
6
+every day. The value of DevStack is that it's simple enough to
7
+understand what it's doing clearly. And yet we'd like to support as
8
+much of the OpenStack Ecosystem as possible. We do that with plugins.
7 9
 
8
-Extras.d Hooks
9
-==============
10
+DevStack plugins are bits of bash code that live outside the DevStack
11
+tree. They are called through a strong contract, so these plugins can
12
+be sure that they will continue to work in the future as DevStack
13
+evolves.
10 14
 
11
-These hooks are an extension of the service calls in
12
-``stack.sh`` at specific points in its run, plus ``unstack.sh`` and
13
-``clean.sh``. A number of the higher-layer projects are implemented in
14
-DevStack using this mechanism.
15
+Plugin Interface
16
+================
15 17
 
16
-The script in ``extras.d`` is expected to be mostly a dispatcher to
17
-functions in a ``lib/*`` script. The scripts are named with a
18
-zero-padded two digits sequence number prefix to control the order that
19
-the scripts are called, and with a suffix of ``.sh``. DevStack reserves
20
-for itself the sequence numbers 00 through 09 and 90 through 99.
18
+DevStack supports a standard mechansim for including plugins from
19
+external repositories. The plugin interface assumes the following:
21 20
 
22
-Below is a template that shows handlers for the possible command-line
23
-arguments:
21
+An external git repository that includes a ``devstack/`` top level
22
+directory. Inside this directory there can be 2 files.
24 23
 
25
-::
24
+- ``settings`` - a file containing global variables that will be
25
+  sourced very early in the process. This is helpful if other plugins
26
+  might depend on this one, and need access to global variables to do
27
+  their work.
26 28
 
27
-    # template.sh - DevStack extras.d dispatch script template
29
+  Your settings should include any ``enable_service`` lines required
30
+  by your plugin. This is especially important if you are kicking off
31
+  services using ``run_process`` as it only works with enabled
32
+  services.
28 33
 
29
-    # check for service enabled
30
-    if is_service_enabled template; then
34
+  Be careful to allow users to override global-variables for
35
+  customizing their environment.  Usually it is best to provide a
36
+  default value only if the variable is unset or empty; e.g. in bash
37
+  syntax ``FOO=${FOO:-default}``.
31 38
 
32
-        if [[ "$1" == "source" ]]; then
33
-            # Initial source of lib script
34
-            source $TOP_DIR/lib/template
35
-        fi
39
+- ``plugin.sh`` - the actual plugin. It is executed by devstack at
40
+  well defined points during a ``stack.sh`` run. The plugin.sh
41
+  internal structure is discussed bellow.
36 42
 
37
-        if [[ "$1" == "stack" && "$2" == "pre-install" ]]; then
38
-            # Set up system services
39
-            echo_summary "Configuring system services Template"
40
-            install_package cowsay
41 43
 
42
-        elif [[ "$1" == "stack" && "$2" == "install" ]]; then
43
-            # Perform installation of service source
44
-            echo_summary "Installing Template"
45
-            install_template
44
+Plugins are registered by adding the following to the localrc section
45
+of ``local.conf``.
46 46
 
47
-        elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
48
-            # Configure after the other layer 1 and 2 services have been configured
49
-            echo_summary "Configuring Template"
50
-            configure_template
47
+They are added in the following format::
51 48
 
52
-        elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
53
-            # Initialize and start the template service
54
-            echo_summary "Initializing Template"
55
-            ##init_template
56
-        fi
49
+  [[local|localrc]]
50
+  enable_plugin <NAME> <GITURL> [GITREF]
57 51
 
58
-        if [[ "$1" == "unstack" ]]; then
59
-            # Shut down template services
60
-            # no-op
61
-            :
62
-        fi
52
+- ``name`` - an arbitrary name. (ex: glustfs, docker, zaqar, congress)
53
+- ``giturl`` - a valid git url that can be cloned
54
+- ``gitref`` - an optional git ref (branch / ref / tag) that will be
55
+  cloned. Defaults to master.
63 56
 
64
-        if [[ "$1" == "clean" ]]; then
65
-            # Remove state and transient data
66
-            # Remember clean.sh first calls unstack.sh
67
-            # no-op
68
-            :
69
-        fi
70
-    fi
57
+An example would be as follows::
71 58
 
72
-The arguments are:
59
+  enable_plugin ec2api git://git.openstack.org/stackforge/ec2api
60
+
61
+plugin.sh contract
62
+==================
63
+
64
+``plugin.sh`` is a bash script that will be called at specific points
65
+during ``stack.sh``, ``unstack.sh``, and ``clean.sh``. It will be
66
+called in the following way::
67
+
68
+  source $PATH/TO/plugin.sh <mode> [phase]
73 69
 
74
--  **source** - Called by each script that utilizes ``extras.d`` hooks;
75
-   this replaces directly sourcing the ``lib/*`` script.
76
--  **stack** - Called by ``stack.sh`` three times for different phases
70
+``mode`` can be thought of as the major mode being called, currently
71
+one of: ``stack``, ``unstack``, ``clean``. ``phase`` is used by modes
72
+which have multiple points during their run where it's necessary to
73
+be able to execute code. All existing ``mode`` and ``phase`` points
74
+are considered **strong contracts** and won't be removed without a
75
+reasonable deprecation period. Additional new ``mode`` or ``phase``
76
+points may be added at any time if we discover we need them to support
77
+additional kinds of plugins in devstack.
78
+
79
+The current full list of ``mode`` and ``phase`` are:
80
+
81
+-  **stack** - Called by ``stack.sh`` four times for different phases
77 82
    of its run:
78 83
 
79 84
    -  **pre-install** - Called after system (OS) setup is complete and
... ...
@@ -84,106 +89,90 @@ The arguments are:
84 84
       been configured. All configuration files for enabled services
85 85
       should exist at this point.
86 86
    -  **extra** - Called near the end after layer 1 and 2 services have
87
-      been started. This is the existing hook and has not otherwise
88
-      changed.
87
+      been started.
89 88
 
90 89
 -  **unstack** - Called by ``unstack.sh`` before other services are shut
91 90
    down.
92 91
 -  **clean** - Called by ``clean.sh`` before other services are cleaned,
93 92
    but after ``unstack.sh`` has been called.
94 93
 
94
+Example plugin
95
+====================
95 96
 
96
-Externally Hosted Plugins
97
-=========================
97
+An example plugin would look something as follows.
98 98
 
99
-Based on the extras.d hooks, DevStack supports a standard mechansim
100
-for including plugins from external repositories. The plugin interface
101
-assumes the following:
99
+``devstack/settings``::
102 100
 
103
-An external git repository that includes a ``devstack/`` top level
104
-directory. Inside this directory there can be 2 files.
101
+    # settings file for template
102
+  enable_service template
105 103
 
106
-- ``settings`` - a file containing global variables that will be
107
-  sourced very early in the process. This is helpful if other plugins
108
-  might depend on this one, and need access to global variables to do
109
-  their work.
110 104
 
111
-  Your settings should include any ``enable_service`` lines required
112
-  by your plugin. This is especially important if you are kicking off
113
-  services using ``run_process`` as it only works with enabled
114
-  services.
105
+``devstack/plugin.sh``::
115 106
 
116
-  Be careful to allow users to override global-variables for
117
-  customizing their environment.  Usually it is best to provide a
118
-  default value only if the variable is unset or empty; e.g. in bash
119
-  syntax ``FOO=${FOO:-default}``.
107
+    # plugin.sh - DevStack plugin.sh dispatch script template
120 108
 
121
-- ``plugin.sh`` - the actual plugin. It will be executed by devstack
122
-  during it's run. The run order will be done in the registration
123
-  order for these plugins, and will occur immediately after all in
124
-  tree extras.d dispatch at the phase in question.  The plugin.sh
125
-  looks like the extras.d dispatcher above.
109
+    function install_template {
110
+        ...
111
+    }
126 112
 
127
-Plugins are registered by adding the following to the localrc section
128
-of ``local.conf``.
113
+    function init_template {
114
+        ...
115
+    }
129 116
 
130
-They are added in the following format::
117
+    function configure_template {
118
+        ...
119
+    }
131 120
 
132
-  [[local|localrc]]
133
-  enable_plugin <NAME> <GITURL> [GITREF]
121
+    # check for service enabled
122
+    if is_service_enabled template; then
134 123
 
135
-- ``name`` - an arbitrary name. (ex: glustfs, docker, zaqar, congress)
136
-- ``giturl`` - a valid git url that can be cloned
137
-- ``gitref`` - an optional git ref (branch / ref / tag) that will be
138
-  cloned. Defaults to master.
124
+        if [[ "$1" == "stack" && "$2" == "pre-install" ]]; then
125
+            # Set up system services
126
+            echo_summary "Configuring system services Template"
127
+            install_package cowsay
139 128
 
140
-An example would be as follows::
129
+        elif [[ "$1" == "stack" && "$2" == "install" ]]; then
130
+            # Perform installation of service source
131
+            echo_summary "Installing Template"
132
+            install_template
141 133
 
142
-  enable_plugin ec2api git://git.openstack.org/stackforge/ec2api
134
+        elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
135
+            # Configure after the other layer 1 and 2 services have been configured
136
+            echo_summary "Configuring Template"
137
+            configure_template
138
+
139
+        elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
140
+            # Initialize and start the template service
141
+            echo_summary "Initializing Template"
142
+            init_template
143
+        fi
144
+
145
+        if [[ "$1" == "unstack" ]]; then
146
+            # Shut down template services
147
+            # no-op
148
+            :
149
+        fi
143 150
 
144
-Plugins for gate jobs
145
-
146
-All OpenStack plugins that wish to be used as gate jobs need to exist
147
-in OpenStack's gerrit. Both ``openstack`` namespace and ``stackforge``
148
-namespace are fine. This allows testing of the plugin as well as
149
-provides network isolation against upstream git repository failures
150
-(which we see often enough to be an issue).
151
-
152
-Ideally plugins will be implemented as ``devstack`` directory inside
153
-the project they are testing. For example, the stackforge/ec2-api
154
-project has it's pluggin support in it's tree.
155
-
156
-In the cases where there is no "project tree" per say (like
157
-integrating a backend storage configuration such as ceph or glusterfs)
158
-it's also allowed to build a dedicated
159
-``stackforge/devstack-plugin-FOO`` project to house the plugin.
160
-
161
-Note jobs must not require cloning of repositories during tests.
162
-Tests must list their repository in the ``PROJECTS`` variable for
163
-`devstack-gate
164
-<https://git.openstack.org/cgit/openstack-infra/devstack-gate/tree/devstack-vm-gate-wrap.sh>`_
165
-for the repository to be available to the test.  Further information
166
-is provided in the project creator's guide.
167
-
168
-Hypervisor
169
-==========
170
-
171
-Hypervisor plugins are fairly new and condense most hypervisor
172
-configuration into one place.
173
-
174
-The initial plugin implemented was for Docker support and is a useful
175
-template for the required support. Plugins are placed in
176
-``lib/nova_plugins`` and named ``hypervisor-<name>`` where ``<name>`` is
177
-the value of ``VIRT_DRIVER``. Plugins must define the following
178
-functions:
179
-
180
--  ``install_nova_hypervisor`` - install any external requirements
181
--  ``configure_nova_hypervisor`` - make configuration changes, including
182
-   those to other services
183
--  ``start_nova_hypervisor`` - start any external services
184
--  ``stop_nova_hypervisor`` - stop any external services
185
--  ``cleanup_nova_hypervisor`` - remove transient data and cache
151
+        if [[ "$1" == "clean" ]]; then
152
+            # Remove state and transient data
153
+            # Remember clean.sh first calls unstack.sh
154
+            # no-op
155
+            :
156
+        fi
157
+    fi
158
+
159
+Plugin Execution Order
160
+======================
161
+
162
+Plugins are run after in tree services at each of the stages
163
+above. For example, if you need something to happen before Keystone
164
+starts, you should do that at the ``post-config`` phase.
165
+
166
+Multiple plugins can be specified in your ``local.conf``. When that
167
+happens the plugins will be executed **in order** at each phase. This
168
+allows plugins to conceptually depend on each other through
169
+documenting to the user the order they must be declared. A formal
170
+dependency mechanism is beyond the scope of the current work.
186 171
 
187 172
 System Packages
188 173
 ===============
... ...
@@ -205,3 +194,47 @@ repository:
205 205
 
206 206
 - ``./devstack/files/rpms-suse/$plugin_name`` - Packages to install when
207 207
   running on SUSE Linux or openSUSE.
208
+
209
+
210
+Using Plugins in the OpenStack Gate
211
+===================================
212
+
213
+For everyday use, DevStack plugins can exist in any git tree that's
214
+accessible on the internet. However, when using DevStack plugins in
215
+the OpenStack gate, they must live in projects in OpenStack's
216
+gerrit. Both ``openstack`` namespace and ``stackforge`` namespace are
217
+fine. This allows testing of the plugin as well as provides network
218
+isolation against upstream git repository failures (which we see often
219
+enough to be an issue).
220
+
221
+Ideally a plugin will be included within the ``devstack`` directory of
222
+the project they are being tested. For example, the stackforge/ec2-api
223
+project has its pluggin support in its own tree.
224
+
225
+However, some times a DevStack plugin might be used solely to
226
+configure a backend service that will be used by the rest of
227
+OpenStack, so there is no "project tree" per say. Good examples
228
+include: integration of back end storage (e.g. ceph or glusterfs),
229
+integration of SDN controllers (e.g. ovn, OpenDayLight), or
230
+integration of alternate RPC systems (e.g. zmq, qpid). In these cases
231
+the best practice is to build a dedicated
232
+``stackforge/devstack-plugin-FOO`` project.
233
+
234
+To enable a plugin to be used in a gate job, the following lines will
235
+be needed in your project.yaml definition::
236
+
237
+  # Because we are testing a non standard project, add the
238
+  # our project repository. This makes zuul do the right
239
+  # reference magic for testing changes.
240
+  export PROJECTS="stackforge/ec2-api $PROJECTS"
241
+
242
+  # note the actual url here is somewhat irrelevant because it
243
+  # caches in nodepool, however make it a valid url for
244
+  # documentation purposes.
245
+  export DEVSTACK_LOCAL_CONFIG="enable_plugin ec2-api git://git.openstack.org/stackforge/ec2-api"
246
+
247
+See Also
248
+========
249
+
250
+For additional inspiration on devstack plugins you can check out the
251
+`Plugin Registry <plugin-registry.html>`_.