blob: 09ba98054875a1a2ad795edaf880781e3b223c53 [file] [log] [blame]
Dean Troyer0986a7b2014-10-29 22:08:13 -05001=======
2Plugins
3=======
Sean M. Collins09e550c2014-10-21 11:40:08 -04004
Sean Dague0124e082015-06-19 08:26:45 -04005The OpenStack ecosystem is wide and deep, and only growing more so
6every day. The value of DevStack is that it's simple enough to
7understand what it's doing clearly. And yet we'd like to support as
8much of the OpenStack Ecosystem as possible. We do that with plugins.
Sean M. Collins09e550c2014-10-21 11:40:08 -04009
Sean Dague0124e082015-06-19 08:26:45 -040010DevStack plugins are bits of bash code that live outside the DevStack
11tree. They are called through a strong contract, so these plugins can
12be sure that they will continue to work in the future as DevStack
13evolves.
Sean M. Collins09e550c2014-10-21 11:40:08 -040014
Chris Dentebbbc052017-08-16 16:00:16 +010015Prerequisites
16=============
17
18If you are planning to create a plugin that is going to host a service in the
19service catalog (that is, your plugin will use the command
20``get_or_create_service``) please make sure that you apply to the `service
21types authority`_ to reserve a valid service-type. This will help to make sure
22that all deployments of your service use the same service-type.
23
Sean Dague0124e082015-06-19 08:26:45 -040024Plugin Interface
25================
Sean M. Collins09e550c2014-10-21 11:40:08 -040026
Atsushi SAKAI20401432015-07-27 20:42:44 +090027DevStack supports a standard mechanism for including plugins from
Sean Dague0124e082015-06-19 08:26:45 -040028external repositories. The plugin interface assumes the following:
Sean Dague2c65e712014-12-18 09:44:56 -050029
30An external git repository that includes a ``devstack/`` top level
Deepak C Shetty93e24992015-11-18 12:29:33 +053031directory. Inside this directory there can be 3 files.
32
Jim Rollenhagen56632fc2015-12-10 05:57:19 -080033- ``override-defaults`` - a file containing global variables that
Deepak C Shetty93e24992015-11-18 12:29:33 +053034 will be sourced before the lib/* files. This allows the plugin
35 to override the defaults that are otherwise set in the lib/*
36 files.
37
Jim Rollenhagen56632fc2015-12-10 05:57:19 -080038 For example, override-defaults may export CINDER_ENABLED_BACKENDS
Deepak C Shetty93e24992015-11-18 12:29:33 +053039 to include the plugin-specific storage backend and thus be able
40 to override the default lvm only storage backend for Cinder.
Sean Dague2c65e712014-12-18 09:44:56 -050041
42- ``settings`` - a file containing global variables that will be
43 sourced very early in the process. This is helpful if other plugins
44 might depend on this one, and need access to global variables to do
45 their work.
Sean Dague33127a12015-02-09 15:17:27 -050046
47 Your settings should include any ``enable_service`` lines required
48 by your plugin. This is especially important if you are kicking off
49 services using ``run_process`` as it only works with enabled
50 services.
51
Ian Wienand51c48d42015-03-25 06:26:03 +110052 Be careful to allow users to override global-variables for
53 customizing their environment. Usually it is best to provide a
54 default value only if the variable is unset or empty; e.g. in bash
55 syntax ``FOO=${FOO:-default}``.
56
James E. Blairc5853ac2017-11-21 09:44:42 -080057 The file should include a ``define_plugin`` line to indicate the
58 plugin's name, which is the name that should be used by users on
59 "enable_plugin" lines. It should generally be the last component of
60 the git repo path (e.g., if the plugin's repo is
Riccardo Pittaub3ee6f42018-12-18 11:19:59 +010061 openstack/foo, then the name here should be "foo") ::
James E. Blairc5853ac2017-11-21 09:44:42 -080062
63 define_plugin <YOUR PLUGIN>
64
65 If your plugin depends on another plugin, indicate it in this file
66 with one or more lines like the following::
67
68 plugin_requires <YOUR PLUGIN> <OTHER PLUGIN>
69
70 For a complete example, if the plugin "foo" depends on "bar", the
71 ``settings`` file should include::
72
73 define_plugin foo
74 plugin_requires foo bar
75
76 Devstack does not currently use this dependency information, so it's
77 important that users continue to add enable_plugin lines in the
78 correct order in ``local.conf``, however adding this information
79 allows other tools to consider dependency information when
80 automatically generating ``local.conf`` files.
81
Sean Dague0124e082015-06-19 08:26:45 -040082- ``plugin.sh`` - the actual plugin. It is executed by devstack at
83 well defined points during a ``stack.sh`` run. The plugin.sh
Deepak C Shetty93e24992015-11-18 12:29:33 +053084 internal structure is discussed below.
Sean Dague0124e082015-06-19 08:26:45 -040085
Sean Dague2c65e712014-12-18 09:44:56 -050086
87Plugins are registered by adding the following to the localrc section
88of ``local.conf``.
89
90They are added in the following format::
91
Sean Dague33127a12015-02-09 15:17:27 -050092 [[local|localrc]]
Sean Dague2c65e712014-12-18 09:44:56 -050093 enable_plugin <NAME> <GITURL> [GITREF]
94
Atsushi SAKAI20401432015-07-27 20:42:44 +090095- ``name`` - an arbitrary name. (ex: glusterfs, docker, zaqar, congress)
Sean Dague2c65e712014-12-18 09:44:56 -050096- ``giturl`` - a valid git url that can be cloned
97- ``gitref`` - an optional git ref (branch / ref / tag) that will be
98 cloned. Defaults to master.
99
100An example would be as follows::
101
Matt Riedemann9b6d2f22019-06-18 10:43:16 -0400102 enable_plugin ec2-api https://opendev.org/openstack/ec2-api
Sean Dague2c65e712014-12-18 09:44:56 -0500103
Sean Dague0124e082015-06-19 08:26:45 -0400104plugin.sh contract
105==================
Ian Wienanddb1152c2015-01-13 10:18:49 +1100106
Sean Dague0124e082015-06-19 08:26:45 -0400107``plugin.sh`` is a bash script that will be called at specific points
108during ``stack.sh``, ``unstack.sh``, and ``clean.sh``. It will be
109called in the following way::
Ian Wienanddb1152c2015-01-13 10:18:49 +1100110
Sean Dague0124e082015-06-19 08:26:45 -0400111 source $PATH/TO/plugin.sh <mode> [phase]
Ian Wienanddb1152c2015-01-13 10:18:49 +1100112
Sean Dague0124e082015-06-19 08:26:45 -0400113``mode`` can be thought of as the major mode being called, currently
114one of: ``stack``, ``unstack``, ``clean``. ``phase`` is used by modes
115which have multiple points during their run where it's necessary to
116be able to execute code. All existing ``mode`` and ``phase`` points
117are considered **strong contracts** and won't be removed without a
118reasonable deprecation period. Additional new ``mode`` or ``phase``
119points may be added at any time if we discover we need them to support
120additional kinds of plugins in devstack.
Ian Wienanddb1152c2015-01-13 10:18:49 +1100121
Sean Dague0124e082015-06-19 08:26:45 -0400122The current full list of ``mode`` and ``phase`` are:
Ian Wienanddb1152c2015-01-13 10:18:49 +1100123
Sean Dague0124e082015-06-19 08:26:45 -0400124- **stack** - Called by ``stack.sh`` four times for different phases
125 of its run:
Sean M. Collins09e550c2014-10-21 11:40:08 -0400126
Sean Dague0124e082015-06-19 08:26:45 -0400127 - **pre-install** - Called after system (OS) setup is complete and
128 before project source is installed.
129 - **install** - Called after the layer 1 and 2 projects source and
130 their dependencies have been installed.
131 - **post-config** - Called after the layer 1 and 2 services have
132 been configured. All configuration files for enabled services
133 should exist at this point.
134 - **extra** - Called near the end after layer 1 and 2 services have
135 been started.
Vasyl Saienko8e0fc9d2016-12-06 09:35:02 +0200136 - **test-config** - Called at the end of devstack used to configure tempest
Matthew Treinish655c22c2016-05-02 13:29:10 -0400137 or any other test environments
Sean M. Collins09e550c2014-10-21 11:40:08 -0400138
Sean Dague0124e082015-06-19 08:26:45 -0400139- **unstack** - Called by ``unstack.sh`` before other services are shut
140 down.
141- **clean** - Called by ``clean.sh`` before other services are cleaned,
142 but after ``unstack.sh`` has been called.
Sean M. Collins09e550c2014-10-21 11:40:08 -0400143
Sean Dague0124e082015-06-19 08:26:45 -0400144Example plugin
145====================
146
147An example plugin would look something as follows.
148
149``devstack/settings``::
150
Riccardo Pittaub3ee6f42018-12-18 11:19:59 +0100151 # settings file for template
Sean Dague0124e082015-06-19 08:26:45 -0400152 enable_service template
153
154
155``devstack/plugin.sh``::
156
157 # plugin.sh - DevStack plugin.sh dispatch script template
158
159 function install_template {
160 ...
161 }
162
163 function init_template {
164 ...
165 }
166
167 function configure_template {
168 ...
169 }
170
171 # check for service enabled
172 if is_service_enabled template; then
173
174 if [[ "$1" == "stack" && "$2" == "pre-install" ]]; then
175 # Set up system services
176 echo_summary "Configuring system services Template"
177 install_package cowsay
178
179 elif [[ "$1" == "stack" && "$2" == "install" ]]; then
180 # Perform installation of service source
181 echo_summary "Installing Template"
182 install_template
183
184 elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
185 # Configure after the other layer 1 and 2 services have been configured
186 echo_summary "Configuring Template"
187 configure_template
188
189 elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
190 # Initialize and start the template service
191 echo_summary "Initializing Template"
192 init_template
193 fi
194
195 if [[ "$1" == "unstack" ]]; then
196 # Shut down template services
197 # no-op
198 :
199 fi
200
201 if [[ "$1" == "clean" ]]; then
202 # Remove state and transient data
203 # Remember clean.sh first calls unstack.sh
204 # no-op
205 :
206 fi
207 fi
208
209Plugin Execution Order
210======================
211
212Plugins are run after in tree services at each of the stages
213above. For example, if you need something to happen before Keystone
214starts, you should do that at the ``post-config`` phase.
215
216Multiple plugins can be specified in your ``local.conf``. When that
217happens the plugins will be executed **in order** at each phase. This
218allows plugins to conceptually depend on each other through
219documenting to the user the order they must be declared. A formal
220dependency mechanism is beyond the scope of the current work.
Adam Gandelman7ca90cd2015-03-04 17:25:07 -0800221
222System Packages
223===============
224
225Devstack provides a framework for getting packages installed at an early
dieterlybf9f9a52015-09-21 13:24:00 -0600226phase of its execution. These packages may be defined in a plugin as files
Adam Gandelman7ca90cd2015-03-04 17:25:07 -0800227that contain new-line separated lists of packages required by the plugin
228
229Supported packaging systems include apt and yum across multiple distributions.
230To enable a plugin to hook into this and install package dependencies, packages
231may be listed at the following locations in the top-level of the plugin
232repository:
233
234- ``./devstack/files/debs/$plugin_name`` - Packages to install when running
235 on Ubuntu, Debian or Linux Mint.
236
237- ``./devstack/files/rpms/$plugin_name`` - Packages to install when running
238 on Red Hat, Fedora, CentOS or XenServer.
239
240- ``./devstack/files/rpms-suse/$plugin_name`` - Packages to install when
241 running on SUSE Linux or openSUSE.
Sean Dague0124e082015-06-19 08:26:45 -0400242
243
244Using Plugins in the OpenStack Gate
245===================================
246
247For everyday use, DevStack plugins can exist in any git tree that's
248accessible on the internet. However, when using DevStack plugins in
249the OpenStack gate, they must live in projects in OpenStack's
Zhang Jinnan9f6b5422015-10-20 01:19:06 +0800250gerrit. This allows testing of the plugin as well as provides network
Sean Dague0124e082015-06-19 08:26:45 -0400251isolation against upstream git repository failures (which we see often
252enough to be an issue).
253
254Ideally a plugin will be included within the ``devstack`` directory of
Zhang Jinnan9f6b5422015-10-20 01:19:06 +0800255the project they are being tested. For example, the openstack/ec2-api
Atsushi SAKAI20401432015-07-27 20:42:44 +0900256project has its plugin support in its own tree.
Sean Dague0124e082015-06-19 08:26:45 -0400257
258However, some times a DevStack plugin might be used solely to
259configure a backend service that will be used by the rest of
260OpenStack, so there is no "project tree" per say. Good examples
261include: integration of back end storage (e.g. ceph or glusterfs),
262integration of SDN controllers (e.g. ovn, OpenDayLight), or
263integration of alternate RPC systems (e.g. zmq, qpid). In these cases
264the best practice is to build a dedicated
Zhang Jinnan9f6b5422015-10-20 01:19:06 +0800265``openstack/devstack-plugin-FOO`` project.
Sean Dague0124e082015-06-19 08:26:45 -0400266
Matt Riedemann9b6d2f22019-06-18 10:43:16 -0400267Legacy project-config jobs
268--------------------------
269
Sean Dague0124e082015-06-19 08:26:45 -0400270To enable a plugin to be used in a gate job, the following lines will
Chris Dentdcc8a302015-06-27 12:45:21 +0000271be needed in your ``jenkins/jobs/<project>.yaml`` definition in
Matt Riedemann9b6d2f22019-06-18 10:43:16 -0400272`project-config <https://opendev.org/openstack/project-config/>`_::
Sean Dague0124e082015-06-19 08:26:45 -0400273
274 # Because we are testing a non standard project, add the
275 # our project repository. This makes zuul do the right
276 # reference magic for testing changes.
Zhang Jinnan9f6b5422015-10-20 01:19:06 +0800277 export PROJECTS="openstack/ec2-api $PROJECTS"
Sean Dague0124e082015-06-19 08:26:45 -0400278
279 # note the actual url here is somewhat irrelevant because it
280 # caches in nodepool, however make it a valid url for
281 # documentation purposes.
Matt Riedemann9b6d2f22019-06-18 10:43:16 -0400282 export DEVSTACK_LOCAL_CONFIG="enable_plugin ec2-api https://opendev.org/openstack/ec2-api"
283
284Zuul v3 jobs
285------------
286
287See the ``devstack_plugins`` example in :doc:`zuul_ci_jobs_migration`.
Sean Dague0124e082015-06-19 08:26:45 -0400288
289See Also
290========
291
292For additional inspiration on devstack plugins you can check out the
293`Plugin Registry <plugin-registry.html>`_.
Chris Dentebbbc052017-08-16 16:00:16 +0100294
295.. _service types authority: https://specs.openstack.org/openstack/service-types-authority/