blob: fe567e227721da1a89639d50354a3af93666f90f [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
Adam Gandelman7ca90cd2015-03-04 17:25:07 -0800225
Ian Wienandfa9aadf2019-01-15 18:31:05 +1100226
227Devstack based
228--------------
229
230Devstack provides a custom framework for getting packages installed at
231an early phase of its execution. These packages may be defined in a
232plugin as files that contain new-line separated lists of packages
233required by the plugin
234
Takashi Kajinamib609c802025-01-07 10:51:03 +0900235Supported packaging systems include apt and dnf across multiple
Ian Wienandfa9aadf2019-01-15 18:31:05 +1100236distributions. To enable a plugin to hook into this and install
237package dependencies, packages may be listed at the following
238locations in the top-level of the plugin repository:
Adam Gandelman7ca90cd2015-03-04 17:25:07 -0800239
240- ``./devstack/files/debs/$plugin_name`` - Packages to install when running
Martin Kopec90e54792022-08-16 17:29:16 +0200241 on Ubuntu or Debian.
Adam Gandelman7ca90cd2015-03-04 17:25:07 -0800242
243- ``./devstack/files/rpms/$plugin_name`` - Packages to install when running
Stephen Finucane970891a2021-03-02 16:45:39 +0000244 on Red Hat, Fedora, or CentOS.
Adam Gandelman7ca90cd2015-03-04 17:25:07 -0800245
Ian Wienandfa9aadf2019-01-15 18:31:05 +1100246Although there a no plans to remove this method of installing
247packages, plugins should consider it deprecated for ``bindep`` support
248described below.
249
250bindep
251------
252
253The `bindep <https://docs.openstack.org/infra/bindep>`__ project has
254become the defacto standard for OpenStack projects to specify binary
255dependencies.
256
257A plugin may provide a ``./devstack/files/bindep.txt`` file, which
258will be called with the *default* profile to install packages. For
259details on the syntax, etc. see the bindep documentation.
260
261It is also possible to use the ``bindep.txt`` of projects that are
262being installed from source with the ``-bindep`` flag available in
263install functions. For example
264
265.. code-block:: bash
266
267 if use_library_from_git "diskimage-builder"; then
268 GITREPO["diskimage-builder"]=$DISKIMAGE_BUILDER_REPO_URL
269 GITDIR["diskimage-builder"]=$DEST/diskimage-builder
270 GITBRANCH["diskimage-builder"]=$DISKIMAGE_BUILDER_REPO_REF
271 git_clone_by_name "diskimage-builder"
272 setup_dev_lib -bindep "diskimage-builder"
273 fi
274
275will result in any packages required by the ``bindep.txt`` of the
276``diskimage-builder`` project being installed. Note however that jobs
277that switch projects between source and released/pypi installs
278(e.g. with a ``foo-dsvm`` and a ``foo-dsvm-src`` test to cover both
279released dependencies and master versions) will have to deal with
280``bindep.txt`` being unavailable without the source directory.
281
Sean Dague0124e082015-06-19 08:26:45 -0400282
283Using Plugins in the OpenStack Gate
284===================================
285
286For everyday use, DevStack plugins can exist in any git tree that's
287accessible on the internet. However, when using DevStack plugins in
288the OpenStack gate, they must live in projects in OpenStack's
Zhang Jinnan9f6b5422015-10-20 01:19:06 +0800289gerrit. This allows testing of the plugin as well as provides network
Sean Dague0124e082015-06-19 08:26:45 -0400290isolation against upstream git repository failures (which we see often
291enough to be an issue).
292
293Ideally a plugin will be included within the ``devstack`` directory of
Zhang Jinnan9f6b5422015-10-20 01:19:06 +0800294the project they are being tested. For example, the openstack/ec2-api
Atsushi SAKAI20401432015-07-27 20:42:44 +0900295project has its plugin support in its own tree.
Sean Dague0124e082015-06-19 08:26:45 -0400296
297However, some times a DevStack plugin might be used solely to
298configure a backend service that will be used by the rest of
299OpenStack, so there is no "project tree" per say. Good examples
300include: integration of back end storage (e.g. ceph or glusterfs),
301integration of SDN controllers (e.g. ovn, OpenDayLight), or
302integration of alternate RPC systems (e.g. zmq, qpid). In these cases
303the best practice is to build a dedicated
Zhang Jinnan9f6b5422015-10-20 01:19:06 +0800304``openstack/devstack-plugin-FOO`` project.
Sean Dague0124e082015-06-19 08:26:45 -0400305
Matt Riedemann9b6d2f22019-06-18 10:43:16 -0400306Legacy project-config jobs
307--------------------------
308
Sean Dague0124e082015-06-19 08:26:45 -0400309To enable a plugin to be used in a gate job, the following lines will
Chris Dentdcc8a302015-06-27 12:45:21 +0000310be needed in your ``jenkins/jobs/<project>.yaml`` definition in
Matt Riedemann9b6d2f22019-06-18 10:43:16 -0400311`project-config <https://opendev.org/openstack/project-config/>`_::
Sean Dague0124e082015-06-19 08:26:45 -0400312
313 # Because we are testing a non standard project, add the
314 # our project repository. This makes zuul do the right
315 # reference magic for testing changes.
Zhang Jinnan9f6b5422015-10-20 01:19:06 +0800316 export PROJECTS="openstack/ec2-api $PROJECTS"
Sean Dague0124e082015-06-19 08:26:45 -0400317
318 # note the actual url here is somewhat irrelevant because it
319 # caches in nodepool, however make it a valid url for
320 # documentation purposes.
Matt Riedemann9b6d2f22019-06-18 10:43:16 -0400321 export DEVSTACK_LOCAL_CONFIG="enable_plugin ec2-api https://opendev.org/openstack/ec2-api"
322
323Zuul v3 jobs
324------------
325
326See the ``devstack_plugins`` example in :doc:`zuul_ci_jobs_migration`.
Sean Dague0124e082015-06-19 08:26:45 -0400327
328See Also
329========
330
331For additional inspiration on devstack plugins you can check out the
Andreas Jaeger8dd89e52019-08-11 16:00:12 +0200332:doc:`Plugin Registry <plugin-registry>`.
Chris Dentebbbc052017-08-16 16:00:16 +0100333
334.. _service types authority: https://specs.openstack.org/openstack/service-types-authority/