blob: b8da7e1237ff55fc6f31c487d3b02e362ecb2581 [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
Sean Dague0124e082015-06-19 08:26:45 -040015Plugin Interface
16================
Sean M. Collins09e550c2014-10-21 11:40:08 -040017
Atsushi SAKAI20401432015-07-27 20:42:44 +090018DevStack supports a standard mechanism for including plugins from
Sean Dague0124e082015-06-19 08:26:45 -040019external repositories. The plugin interface assumes the following:
Sean Dague2c65e712014-12-18 09:44:56 -050020
21An external git repository that includes a ``devstack/`` top level
Deepak C Shetty93e24992015-11-18 12:29:33 +053022directory. Inside this directory there can be 3 files.
23
24- ``override_defaults`` - a file containing global variables that
25 will be sourced before the lib/* files. This allows the plugin
26 to override the defaults that are otherwise set in the lib/*
27 files.
28
29 For example, override_defaults may export CINDER_ENABLED_BACKENDS
30 to include the plugin-specific storage backend and thus be able
31 to override the default lvm only storage backend for Cinder.
Sean Dague2c65e712014-12-18 09:44:56 -050032
33- ``settings`` - a file containing global variables that will be
34 sourced very early in the process. This is helpful if other plugins
35 might depend on this one, and need access to global variables to do
36 their work.
Sean Dague33127a12015-02-09 15:17:27 -050037
38 Your settings should include any ``enable_service`` lines required
39 by your plugin. This is especially important if you are kicking off
40 services using ``run_process`` as it only works with enabled
41 services.
42
Ian Wienand51c48d42015-03-25 06:26:03 +110043 Be careful to allow users to override global-variables for
44 customizing their environment. Usually it is best to provide a
45 default value only if the variable is unset or empty; e.g. in bash
46 syntax ``FOO=${FOO:-default}``.
47
Sean Dague0124e082015-06-19 08:26:45 -040048- ``plugin.sh`` - the actual plugin. It is executed by devstack at
49 well defined points during a ``stack.sh`` run. The plugin.sh
Deepak C Shetty93e24992015-11-18 12:29:33 +053050 internal structure is discussed below.
Sean Dague0124e082015-06-19 08:26:45 -040051
Sean Dague2c65e712014-12-18 09:44:56 -050052
53Plugins are registered by adding the following to the localrc section
54of ``local.conf``.
55
56They are added in the following format::
57
Sean Dague33127a12015-02-09 15:17:27 -050058 [[local|localrc]]
Sean Dague2c65e712014-12-18 09:44:56 -050059 enable_plugin <NAME> <GITURL> [GITREF]
60
Atsushi SAKAI20401432015-07-27 20:42:44 +090061- ``name`` - an arbitrary name. (ex: glusterfs, docker, zaqar, congress)
Sean Dague2c65e712014-12-18 09:44:56 -050062- ``giturl`` - a valid git url that can be cloned
63- ``gitref`` - an optional git ref (branch / ref / tag) that will be
64 cloned. Defaults to master.
65
66An example would be as follows::
67
Zhang Jinnan9f6b5422015-10-20 01:19:06 +080068 enable_plugin ec2-api git://git.openstack.org/openstack/ec2-api
Sean Dague2c65e712014-12-18 09:44:56 -050069
Sean Dague0124e082015-06-19 08:26:45 -040070plugin.sh contract
71==================
Ian Wienanddb1152c2015-01-13 10:18:49 +110072
Sean Dague0124e082015-06-19 08:26:45 -040073``plugin.sh`` is a bash script that will be called at specific points
74during ``stack.sh``, ``unstack.sh``, and ``clean.sh``. It will be
75called in the following way::
Ian Wienanddb1152c2015-01-13 10:18:49 +110076
Sean Dague0124e082015-06-19 08:26:45 -040077 source $PATH/TO/plugin.sh <mode> [phase]
Ian Wienanddb1152c2015-01-13 10:18:49 +110078
Sean Dague0124e082015-06-19 08:26:45 -040079``mode`` can be thought of as the major mode being called, currently
80one of: ``stack``, ``unstack``, ``clean``. ``phase`` is used by modes
81which have multiple points during their run where it's necessary to
82be able to execute code. All existing ``mode`` and ``phase`` points
83are considered **strong contracts** and won't be removed without a
84reasonable deprecation period. Additional new ``mode`` or ``phase``
85points may be added at any time if we discover we need them to support
86additional kinds of plugins in devstack.
Ian Wienanddb1152c2015-01-13 10:18:49 +110087
Sean Dague0124e082015-06-19 08:26:45 -040088The current full list of ``mode`` and ``phase`` are:
Ian Wienanddb1152c2015-01-13 10:18:49 +110089
Sean Dague0124e082015-06-19 08:26:45 -040090- **stack** - Called by ``stack.sh`` four times for different phases
91 of its run:
Sean M. Collins09e550c2014-10-21 11:40:08 -040092
Sean Dague0124e082015-06-19 08:26:45 -040093 - **pre-install** - Called after system (OS) setup is complete and
94 before project source is installed.
95 - **install** - Called after the layer 1 and 2 projects source and
96 their dependencies have been installed.
97 - **post-config** - Called after the layer 1 and 2 services have
98 been configured. All configuration files for enabled services
99 should exist at this point.
100 - **extra** - Called near the end after layer 1 and 2 services have
101 been started.
Sean M. Collins09e550c2014-10-21 11:40:08 -0400102
Sean Dague0124e082015-06-19 08:26:45 -0400103- **unstack** - Called by ``unstack.sh`` before other services are shut
104 down.
105- **clean** - Called by ``clean.sh`` before other services are cleaned,
106 but after ``unstack.sh`` has been called.
Sean M. Collins09e550c2014-10-21 11:40:08 -0400107
Sean Dague0124e082015-06-19 08:26:45 -0400108Example plugin
109====================
110
111An example plugin would look something as follows.
112
113``devstack/settings``::
114
115 # settings file for template
116 enable_service template
117
118
119``devstack/plugin.sh``::
120
121 # plugin.sh - DevStack plugin.sh dispatch script template
122
123 function install_template {
124 ...
125 }
126
127 function init_template {
128 ...
129 }
130
131 function configure_template {
132 ...
133 }
134
135 # check for service enabled
136 if is_service_enabled template; then
137
138 if [[ "$1" == "stack" && "$2" == "pre-install" ]]; then
139 # Set up system services
140 echo_summary "Configuring system services Template"
141 install_package cowsay
142
143 elif [[ "$1" == "stack" && "$2" == "install" ]]; then
144 # Perform installation of service source
145 echo_summary "Installing Template"
146 install_template
147
148 elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
149 # Configure after the other layer 1 and 2 services have been configured
150 echo_summary "Configuring Template"
151 configure_template
152
153 elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
154 # Initialize and start the template service
155 echo_summary "Initializing Template"
156 init_template
157 fi
158
159 if [[ "$1" == "unstack" ]]; then
160 # Shut down template services
161 # no-op
162 :
163 fi
164
165 if [[ "$1" == "clean" ]]; then
166 # Remove state and transient data
167 # Remember clean.sh first calls unstack.sh
168 # no-op
169 :
170 fi
171 fi
172
173Plugin Execution Order
174======================
175
176Plugins are run after in tree services at each of the stages
177above. For example, if you need something to happen before Keystone
178starts, you should do that at the ``post-config`` phase.
179
180Multiple plugins can be specified in your ``local.conf``. When that
181happens the plugins will be executed **in order** at each phase. This
182allows plugins to conceptually depend on each other through
183documenting to the user the order they must be declared. A formal
184dependency mechanism is beyond the scope of the current work.
Adam Gandelman7ca90cd2015-03-04 17:25:07 -0800185
186System Packages
187===============
188
189Devstack provides a framework for getting packages installed at an early
dieterlybf9f9a52015-09-21 13:24:00 -0600190phase of its execution. These packages may be defined in a plugin as files
Adam Gandelman7ca90cd2015-03-04 17:25:07 -0800191that contain new-line separated lists of packages required by the plugin
192
193Supported packaging systems include apt and yum across multiple distributions.
194To enable a plugin to hook into this and install package dependencies, packages
195may be listed at the following locations in the top-level of the plugin
196repository:
197
198- ``./devstack/files/debs/$plugin_name`` - Packages to install when running
199 on Ubuntu, Debian or Linux Mint.
200
201- ``./devstack/files/rpms/$plugin_name`` - Packages to install when running
202 on Red Hat, Fedora, CentOS or XenServer.
203
204- ``./devstack/files/rpms-suse/$plugin_name`` - Packages to install when
205 running on SUSE Linux or openSUSE.
Sean Dague0124e082015-06-19 08:26:45 -0400206
207
208Using Plugins in the OpenStack Gate
209===================================
210
211For everyday use, DevStack plugins can exist in any git tree that's
212accessible on the internet. However, when using DevStack plugins in
213the OpenStack gate, they must live in projects in OpenStack's
Zhang Jinnan9f6b5422015-10-20 01:19:06 +0800214gerrit. This allows testing of the plugin as well as provides network
Sean Dague0124e082015-06-19 08:26:45 -0400215isolation against upstream git repository failures (which we see often
216enough to be an issue).
217
218Ideally a plugin will be included within the ``devstack`` directory of
Zhang Jinnan9f6b5422015-10-20 01:19:06 +0800219the project they are being tested. For example, the openstack/ec2-api
Atsushi SAKAI20401432015-07-27 20:42:44 +0900220project has its plugin support in its own tree.
Sean Dague0124e082015-06-19 08:26:45 -0400221
222However, some times a DevStack plugin might be used solely to
223configure a backend service that will be used by the rest of
224OpenStack, so there is no "project tree" per say. Good examples
225include: integration of back end storage (e.g. ceph or glusterfs),
226integration of SDN controllers (e.g. ovn, OpenDayLight), or
227integration of alternate RPC systems (e.g. zmq, qpid). In these cases
228the best practice is to build a dedicated
Zhang Jinnan9f6b5422015-10-20 01:19:06 +0800229``openstack/devstack-plugin-FOO`` project.
Sean Dague0124e082015-06-19 08:26:45 -0400230
231To enable a plugin to be used in a gate job, the following lines will
Chris Dentdcc8a302015-06-27 12:45:21 +0000232be needed in your ``jenkins/jobs/<project>.yaml`` definition in
233`project-config
234<http://git.openstack.org/cgit/openstack-infra/project-config/>`_::
Sean Dague0124e082015-06-19 08:26:45 -0400235
236 # Because we are testing a non standard project, add the
237 # our project repository. This makes zuul do the right
238 # reference magic for testing changes.
Zhang Jinnan9f6b5422015-10-20 01:19:06 +0800239 export PROJECTS="openstack/ec2-api $PROJECTS"
Sean Dague0124e082015-06-19 08:26:45 -0400240
241 # note the actual url here is somewhat irrelevant because it
242 # caches in nodepool, however make it a valid url for
243 # documentation purposes.
Zhang Jinnan9f6b5422015-10-20 01:19:06 +0800244 export DEVSTACK_LOCAL_CONFIG="enable_plugin ec2-api git://git.openstack.org/openstack/ec2-api"
Sean Dague0124e082015-06-19 08:26:45 -0400245
246See Also
247========
248
249For additional inspiration on devstack plugins you can check out the
250`Plugin Registry <plugin-registry.html>`_.