blob: 8bd3797cd2ee1267a2efc4f58a78033cdfa8ed83 [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
22directory. Inside this directory there can be 2 files.
23
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.
Sean Dague33127a12015-02-09 15:17:27 -050028
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.
33
Ian Wienand51c48d42015-03-25 06:26:03 +110034 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}``.
38
Sean Dague0124e082015-06-19 08:26:45 -040039- ``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.
42
Sean Dague2c65e712014-12-18 09:44:56 -050043
44Plugins are registered by adding the following to the localrc section
45of ``local.conf``.
46
47They are added in the following format::
48
Sean Dague33127a12015-02-09 15:17:27 -050049 [[local|localrc]]
Sean Dague2c65e712014-12-18 09:44:56 -050050 enable_plugin <NAME> <GITURL> [GITREF]
51
Atsushi SAKAI20401432015-07-27 20:42:44 +090052- ``name`` - an arbitrary name. (ex: glusterfs, docker, zaqar, congress)
Sean Dague2c65e712014-12-18 09:44:56 -050053- ``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.
56
57An example would be as follows::
58
Zhang Jinnan9f6b5422015-10-20 01:19:06 +080059 enable_plugin ec2-api git://git.openstack.org/openstack/ec2-api
Sean Dague2c65e712014-12-18 09:44:56 -050060
Sean Dague0124e082015-06-19 08:26:45 -040061plugin.sh contract
62==================
Ian Wienanddb1152c2015-01-13 10:18:49 +110063
Sean Dague0124e082015-06-19 08:26:45 -040064``plugin.sh`` is a bash script that will be called at specific points
65during ``stack.sh``, ``unstack.sh``, and ``clean.sh``. It will be
66called in the following way::
Ian Wienanddb1152c2015-01-13 10:18:49 +110067
Sean Dague0124e082015-06-19 08:26:45 -040068 source $PATH/TO/plugin.sh <mode> [phase]
Ian Wienanddb1152c2015-01-13 10:18:49 +110069
Sean Dague0124e082015-06-19 08:26:45 -040070``mode`` can be thought of as the major mode being called, currently
71one of: ``stack``, ``unstack``, ``clean``. ``phase`` is used by modes
72which have multiple points during their run where it's necessary to
73be able to execute code. All existing ``mode`` and ``phase`` points
74are considered **strong contracts** and won't be removed without a
75reasonable deprecation period. Additional new ``mode`` or ``phase``
76points may be added at any time if we discover we need them to support
77additional kinds of plugins in devstack.
Ian Wienanddb1152c2015-01-13 10:18:49 +110078
Sean Dague0124e082015-06-19 08:26:45 -040079The current full list of ``mode`` and ``phase`` are:
Ian Wienanddb1152c2015-01-13 10:18:49 +110080
Sean Dague0124e082015-06-19 08:26:45 -040081- **stack** - Called by ``stack.sh`` four times for different phases
82 of its run:
Sean M. Collins09e550c2014-10-21 11:40:08 -040083
Sean Dague0124e082015-06-19 08:26:45 -040084 - **pre-install** - Called after system (OS) setup is complete and
85 before project source is installed.
86 - **install** - Called after the layer 1 and 2 projects source and
87 their dependencies have been installed.
88 - **post-config** - Called after the layer 1 and 2 services have
89 been configured. All configuration files for enabled services
90 should exist at this point.
91 - **extra** - Called near the end after layer 1 and 2 services have
92 been started.
Sean M. Collins09e550c2014-10-21 11:40:08 -040093
Sean Dague0124e082015-06-19 08:26:45 -040094- **unstack** - Called by ``unstack.sh`` before other services are shut
95 down.
96- **clean** - Called by ``clean.sh`` before other services are cleaned,
97 but after ``unstack.sh`` has been called.
Sean M. Collins09e550c2014-10-21 11:40:08 -040098
Sean Dague0124e082015-06-19 08:26:45 -040099Example plugin
100====================
101
102An example plugin would look something as follows.
103
104``devstack/settings``::
105
106 # settings file for template
107 enable_service template
108
109
110``devstack/plugin.sh``::
111
112 # plugin.sh - DevStack plugin.sh dispatch script template
113
114 function install_template {
115 ...
116 }
117
118 function init_template {
119 ...
120 }
121
122 function configure_template {
123 ...
124 }
125
126 # check for service enabled
127 if is_service_enabled template; then
128
129 if [[ "$1" == "stack" && "$2" == "pre-install" ]]; then
130 # Set up system services
131 echo_summary "Configuring system services Template"
132 install_package cowsay
133
134 elif [[ "$1" == "stack" && "$2" == "install" ]]; then
135 # Perform installation of service source
136 echo_summary "Installing Template"
137 install_template
138
139 elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
140 # Configure after the other layer 1 and 2 services have been configured
141 echo_summary "Configuring Template"
142 configure_template
143
144 elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
145 # Initialize and start the template service
146 echo_summary "Initializing Template"
147 init_template
148 fi
149
150 if [[ "$1" == "unstack" ]]; then
151 # Shut down template services
152 # no-op
153 :
154 fi
155
156 if [[ "$1" == "clean" ]]; then
157 # Remove state and transient data
158 # Remember clean.sh first calls unstack.sh
159 # no-op
160 :
161 fi
162 fi
163
164Plugin Execution Order
165======================
166
167Plugins are run after in tree services at each of the stages
168above. For example, if you need something to happen before Keystone
169starts, you should do that at the ``post-config`` phase.
170
171Multiple plugins can be specified in your ``local.conf``. When that
172happens the plugins will be executed **in order** at each phase. This
173allows plugins to conceptually depend on each other through
174documenting to the user the order they must be declared. A formal
175dependency mechanism is beyond the scope of the current work.
Adam Gandelman7ca90cd2015-03-04 17:25:07 -0800176
177System Packages
178===============
179
180Devstack provides a framework for getting packages installed at an early
dieterlybf9f9a52015-09-21 13:24:00 -0600181phase of its execution. These packages may be defined in a plugin as files
Adam Gandelman7ca90cd2015-03-04 17:25:07 -0800182that contain new-line separated lists of packages required by the plugin
183
184Supported packaging systems include apt and yum across multiple distributions.
185To enable a plugin to hook into this and install package dependencies, packages
186may be listed at the following locations in the top-level of the plugin
187repository:
188
189- ``./devstack/files/debs/$plugin_name`` - Packages to install when running
190 on Ubuntu, Debian or Linux Mint.
191
192- ``./devstack/files/rpms/$plugin_name`` - Packages to install when running
193 on Red Hat, Fedora, CentOS or XenServer.
194
195- ``./devstack/files/rpms-suse/$plugin_name`` - Packages to install when
196 running on SUSE Linux or openSUSE.
Sean Dague0124e082015-06-19 08:26:45 -0400197
198
199Using Plugins in the OpenStack Gate
200===================================
201
202For everyday use, DevStack plugins can exist in any git tree that's
203accessible on the internet. However, when using DevStack plugins in
204the OpenStack gate, they must live in projects in OpenStack's
Zhang Jinnan9f6b5422015-10-20 01:19:06 +0800205gerrit. This allows testing of the plugin as well as provides network
Sean Dague0124e082015-06-19 08:26:45 -0400206isolation against upstream git repository failures (which we see often
207enough to be an issue).
208
209Ideally a plugin will be included within the ``devstack`` directory of
Zhang Jinnan9f6b5422015-10-20 01:19:06 +0800210the project they are being tested. For example, the openstack/ec2-api
Atsushi SAKAI20401432015-07-27 20:42:44 +0900211project has its plugin support in its own tree.
Sean Dague0124e082015-06-19 08:26:45 -0400212
213However, some times a DevStack plugin might be used solely to
214configure a backend service that will be used by the rest of
215OpenStack, so there is no "project tree" per say. Good examples
216include: integration of back end storage (e.g. ceph or glusterfs),
217integration of SDN controllers (e.g. ovn, OpenDayLight), or
218integration of alternate RPC systems (e.g. zmq, qpid). In these cases
219the best practice is to build a dedicated
Zhang Jinnan9f6b5422015-10-20 01:19:06 +0800220``openstack/devstack-plugin-FOO`` project.
Sean Dague0124e082015-06-19 08:26:45 -0400221
222To enable a plugin to be used in a gate job, the following lines will
Chris Dentdcc8a302015-06-27 12:45:21 +0000223be needed in your ``jenkins/jobs/<project>.yaml`` definition in
224`project-config
225<http://git.openstack.org/cgit/openstack-infra/project-config/>`_::
Sean Dague0124e082015-06-19 08:26:45 -0400226
227 # Because we are testing a non standard project, add the
228 # our project repository. This makes zuul do the right
229 # reference magic for testing changes.
Zhang Jinnan9f6b5422015-10-20 01:19:06 +0800230 export PROJECTS="openstack/ec2-api $PROJECTS"
Sean Dague0124e082015-06-19 08:26:45 -0400231
232 # note the actual url here is somewhat irrelevant because it
233 # caches in nodepool, however make it a valid url for
234 # documentation purposes.
Zhang Jinnan9f6b5422015-10-20 01:19:06 +0800235 export DEVSTACK_LOCAL_CONFIG="enable_plugin ec2-api git://git.openstack.org/openstack/ec2-api"
Sean Dague0124e082015-06-19 08:26:45 -0400236
237See Also
238========
239
240For additional inspiration on devstack plugins you can check out the
241`Plugin Registry <plugin-registry.html>`_.