 8e0fc9dc8e
			
		
	
	8e0fc9dc8e
	
	
	
		
			
			Fix formating issue in the doc/source/plugin.rst Trivial fix. Change-Id: Ifc9a43aebdab0c15c83485cf0b6d4133d7194a9d
		
			
				
	
	
		
			253 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			253 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| =======
 | |
| Plugins
 | |
| =======
 | |
| 
 | |
| The OpenStack ecosystem is wide and deep, and only growing more so
 | |
| every day. The value of DevStack is that it's simple enough to
 | |
| understand what it's doing clearly. And yet we'd like to support as
 | |
| much of the OpenStack Ecosystem as possible. We do that with plugins.
 | |
| 
 | |
| DevStack plugins are bits of bash code that live outside the DevStack
 | |
| tree. They are called through a strong contract, so these plugins can
 | |
| be sure that they will continue to work in the future as DevStack
 | |
| evolves.
 | |
| 
 | |
| Plugin Interface
 | |
| ================
 | |
| 
 | |
| DevStack supports a standard mechanism for including plugins from
 | |
| external repositories. The plugin interface assumes the following:
 | |
| 
 | |
| An external git repository that includes a ``devstack/`` top level
 | |
| directory. Inside this directory there can be 3 files.
 | |
| 
 | |
| - ``override-defaults`` - a file containing global variables that
 | |
|   will be sourced before the lib/* files. This allows the plugin
 | |
|   to override the defaults that are otherwise set in the lib/*
 | |
|   files.
 | |
| 
 | |
|   For example, override-defaults may export CINDER_ENABLED_BACKENDS
 | |
|   to include the plugin-specific storage backend and thus be able
 | |
|   to override the default lvm only storage backend for Cinder.
 | |
| 
 | |
| - ``settings`` - a file containing global variables that will be
 | |
|   sourced very early in the process. This is helpful if other plugins
 | |
|   might depend on this one, and need access to global variables to do
 | |
|   their work.
 | |
| 
 | |
|   Your settings should include any ``enable_service`` lines required
 | |
|   by your plugin. This is especially important if you are kicking off
 | |
|   services using ``run_process`` as it only works with enabled
 | |
|   services.
 | |
| 
 | |
|   Be careful to allow users to override global-variables for
 | |
|   customizing their environment.  Usually it is best to provide a
 | |
|   default value only if the variable is unset or empty; e.g. in bash
 | |
|   syntax ``FOO=${FOO:-default}``.
 | |
| 
 | |
| - ``plugin.sh`` - the actual plugin. It is executed by devstack at
 | |
|   well defined points during a ``stack.sh`` run. The plugin.sh
 | |
|   internal structure is discussed below.
 | |
| 
 | |
| 
 | |
| Plugins are registered by adding the following to the localrc section
 | |
| of ``local.conf``.
 | |
| 
 | |
| They are added in the following format::
 | |
| 
 | |
|   [[local|localrc]]
 | |
|   enable_plugin <NAME> <GITURL> [GITREF]
 | |
| 
 | |
| - ``name`` - an arbitrary name. (ex: glusterfs, docker, zaqar, congress)
 | |
| - ``giturl`` - a valid git url that can be cloned
 | |
| - ``gitref`` - an optional git ref (branch / ref / tag) that will be
 | |
|   cloned. Defaults to master.
 | |
| 
 | |
| An example would be as follows::
 | |
| 
 | |
|   enable_plugin ec2-api git://git.openstack.org/openstack/ec2-api
 | |
| 
 | |
| plugin.sh contract
 | |
| ==================
 | |
| 
 | |
| ``plugin.sh`` is a bash script that will be called at specific points
 | |
| during ``stack.sh``, ``unstack.sh``, and ``clean.sh``. It will be
 | |
| called in the following way::
 | |
| 
 | |
|   source $PATH/TO/plugin.sh <mode> [phase]
 | |
| 
 | |
| ``mode`` can be thought of as the major mode being called, currently
 | |
| one of: ``stack``, ``unstack``, ``clean``. ``phase`` is used by modes
 | |
| which have multiple points during their run where it's necessary to
 | |
| be able to execute code. All existing ``mode`` and ``phase`` points
 | |
| are considered **strong contracts** and won't be removed without a
 | |
| reasonable deprecation period. Additional new ``mode`` or ``phase``
 | |
| points may be added at any time if we discover we need them to support
 | |
| additional kinds of plugins in devstack.
 | |
| 
 | |
| The current full list of ``mode`` and ``phase`` are:
 | |
| 
 | |
| -  **stack** - Called by ``stack.sh`` four times for different phases
 | |
|    of its run:
 | |
| 
 | |
|    -  **pre-install** - Called after system (OS) setup is complete and
 | |
|       before project source is installed.
 | |
|    -  **install** - Called after the layer 1 and 2 projects source and
 | |
|       their dependencies have been installed.
 | |
|    -  **post-config** - Called after the layer 1 and 2 services have
 | |
|       been configured. All configuration files for enabled services
 | |
|       should exist at this point.
 | |
|    -  **extra** - Called near the end after layer 1 and 2 services have
 | |
|       been started.
 | |
|    -  **test-config** - Called at the end of devstack used to configure tempest
 | |
|       or any other test environments
 | |
| 
 | |
| -  **unstack** - Called by ``unstack.sh`` before other services are shut
 | |
|    down.
 | |
| -  **clean** - Called by ``clean.sh`` before other services are cleaned,
 | |
|    but after ``unstack.sh`` has been called.
 | |
| 
 | |
| Example plugin
 | |
| ====================
 | |
| 
 | |
| An example plugin would look something as follows.
 | |
| 
 | |
| ``devstack/settings``::
 | |
| 
 | |
|     # settings file for template
 | |
|   enable_service template
 | |
| 
 | |
| 
 | |
| ``devstack/plugin.sh``::
 | |
| 
 | |
|     # plugin.sh - DevStack plugin.sh dispatch script template
 | |
| 
 | |
|     function install_template {
 | |
|         ...
 | |
|     }
 | |
| 
 | |
|     function init_template {
 | |
|         ...
 | |
|     }
 | |
| 
 | |
|     function configure_template {
 | |
|         ...
 | |
|     }
 | |
| 
 | |
|     # check for service enabled
 | |
|     if is_service_enabled template; then
 | |
| 
 | |
|         if [[ "$1" == "stack" && "$2" == "pre-install" ]]; then
 | |
|             # Set up system services
 | |
|             echo_summary "Configuring system services Template"
 | |
|             install_package cowsay
 | |
| 
 | |
|         elif [[ "$1" == "stack" && "$2" == "install" ]]; then
 | |
|             # Perform installation of service source
 | |
|             echo_summary "Installing Template"
 | |
|             install_template
 | |
| 
 | |
|         elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
 | |
|             # Configure after the other layer 1 and 2 services have been configured
 | |
|             echo_summary "Configuring Template"
 | |
|             configure_template
 | |
| 
 | |
|         elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
 | |
|             # Initialize and start the template service
 | |
|             echo_summary "Initializing Template"
 | |
|             init_template
 | |
|         fi
 | |
| 
 | |
|         if [[ "$1" == "unstack" ]]; then
 | |
|             # Shut down template services
 | |
|             # no-op
 | |
|             :
 | |
|         fi
 | |
| 
 | |
|         if [[ "$1" == "clean" ]]; then
 | |
|             # Remove state and transient data
 | |
|             # Remember clean.sh first calls unstack.sh
 | |
|             # no-op
 | |
|             :
 | |
|         fi
 | |
|     fi
 | |
| 
 | |
| Plugin Execution Order
 | |
| ======================
 | |
| 
 | |
| Plugins are run after in tree services at each of the stages
 | |
| above. For example, if you need something to happen before Keystone
 | |
| starts, you should do that at the ``post-config`` phase.
 | |
| 
 | |
| Multiple plugins can be specified in your ``local.conf``. When that
 | |
| happens the plugins will be executed **in order** at each phase. This
 | |
| allows plugins to conceptually depend on each other through
 | |
| documenting to the user the order they must be declared. A formal
 | |
| dependency mechanism is beyond the scope of the current work.
 | |
| 
 | |
| System Packages
 | |
| ===============
 | |
| 
 | |
| Devstack provides a framework for getting packages installed at an early
 | |
| phase of its execution. These packages may be defined in a plugin as files
 | |
| that contain new-line separated lists of packages required by the plugin
 | |
| 
 | |
| Supported packaging systems include apt and yum across multiple distributions.
 | |
| To enable a plugin to hook into this and install package dependencies, packages
 | |
| may be listed at the following locations in the top-level of the plugin
 | |
| repository:
 | |
| 
 | |
| - ``./devstack/files/debs/$plugin_name`` - Packages to install when running
 | |
|   on Ubuntu, Debian or Linux Mint.
 | |
| 
 | |
| - ``./devstack/files/rpms/$plugin_name`` - Packages to install when running
 | |
|   on Red Hat, Fedora, CentOS or XenServer.
 | |
| 
 | |
| - ``./devstack/files/rpms-suse/$plugin_name`` - Packages to install when
 | |
|   running on SUSE Linux or openSUSE.
 | |
| 
 | |
| 
 | |
| Using Plugins in the OpenStack Gate
 | |
| ===================================
 | |
| 
 | |
| For everyday use, DevStack plugins can exist in any git tree that's
 | |
| accessible on the internet. However, when using DevStack plugins in
 | |
| the OpenStack gate, they must live in projects in OpenStack's
 | |
| gerrit. This allows testing of the plugin as well as provides network
 | |
| isolation against upstream git repository failures (which we see often
 | |
| enough to be an issue).
 | |
| 
 | |
| Ideally a plugin will be included within the ``devstack`` directory of
 | |
| the project they are being tested. For example, the openstack/ec2-api
 | |
| project has its plugin support in its own tree.
 | |
| 
 | |
| However, some times a DevStack plugin might be used solely to
 | |
| configure a backend service that will be used by the rest of
 | |
| OpenStack, so there is no "project tree" per say. Good examples
 | |
| include: integration of back end storage (e.g. ceph or glusterfs),
 | |
| integration of SDN controllers (e.g. ovn, OpenDayLight), or
 | |
| integration of alternate RPC systems (e.g. zmq, qpid). In these cases
 | |
| the best practice is to build a dedicated
 | |
| ``openstack/devstack-plugin-FOO`` project.
 | |
| 
 | |
| To enable a plugin to be used in a gate job, the following lines will
 | |
| be needed in your ``jenkins/jobs/<project>.yaml`` definition in
 | |
| `project-config
 | |
| <http://git.openstack.org/cgit/openstack-infra/project-config/>`_::
 | |
| 
 | |
|   # Because we are testing a non standard project, add the
 | |
|   # our project repository. This makes zuul do the right
 | |
|   # reference magic for testing changes.
 | |
|   export PROJECTS="openstack/ec2-api $PROJECTS"
 | |
| 
 | |
|   # note the actual url here is somewhat irrelevant because it
 | |
|   # caches in nodepool, however make it a valid url for
 | |
|   # documentation purposes.
 | |
|   export DEVSTACK_LOCAL_CONFIG="enable_plugin ec2-api git://git.openstack.org/openstack/ec2-api"
 | |
| 
 | |
| See Also
 | |
| ========
 | |
| 
 | |
| For additional inspiration on devstack plugins you can check out the
 | |
| `Plugin Registry <plugin-registry.html>`_.
 |