=======
Plugins
=======

DevStack has a couple of plugin mechanisms to allow easily adding
support for additional projects and features.

Extras.d Hooks
==============

These hooks are an extension of the service calls in
``stack.sh`` at specific points in its run, plus ``unstack.sh`` and
``clean.sh``. A number of the higher-layer projects are implemented in
DevStack using this mechanism.

The script in ``extras.d`` is expected to be mostly a dispatcher to
functions in a ``lib/*`` script. The scripts are named with a
zero-padded two digits sequence number prefix to control the order that
the scripts are called, and with a suffix of ``.sh``. DevStack reserves
for itself the sequence numbers 00 through 09 and 90 through 99.

Below is a template that shows handlers for the possible command-line
arguments:

::

    # template.sh - DevStack extras.d dispatch script template

    # check for service enabled
    if is_service_enabled template; then

        if [[ "$1" == "source" ]]; then
            # Initial source of lib script
            source $TOP_DIR/lib/template
        fi

        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

The arguments are:

-  **source** - Called by each script that utilizes ``extras.d`` hooks;
   this replaces directly sourcing the ``lib/*`` script.
-  **stack** - Called by ``stack.sh`` three 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. This is the existing hook and has not otherwise
      changed.

-  **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.


Externally Hosted Plugins
=========================

Based on the extras.d hooks, DevStack supports a standard mechansim
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 2 files.

- ``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 will be executed by devstack
  during it's run. The run order will be done in the registration
  order for these plugins, and will occur immediately after all in
  tree extras.d dispatch at the phase in question.  The plugin.sh
  looks like the extras.d dispatcher above.

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: glustfs, 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 ec2api git://git.openstack.org/stackforge/ec2api

Plugins for gate jobs
---------------------

All OpenStack plugins that wish to be used as gate jobs need to exist
in OpenStack's gerrit. Both ``openstack`` namespace and ``stackforge``
namespace are fine. 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 plugins will be implemented as ``devstack`` directory inside
the project they are testing. For example, the stackforge/ec2-api
project has it's pluggin support in it's tree.

In the cases where there is no "project tree" per say (like
integrating a backend storage configuration such as ceph or glusterfs)
it's also allowed to build a dedicated
``stackforge/devstack-plugin-FOO`` project to house the plugin.

Note jobs must not require cloning of repositories during tests.
Tests must list their repository in the ``PROJECTS`` variable for
`devstack-gate
<https://git.openstack.org/cgit/openstack-infra/devstack-gate/tree/devstack-vm-gate-wrap.sh>`_
for the repository to be available to the test.  Further information
is provided in the project creator's guide.

Hypervisor
==========

Hypervisor plugins are fairly new and condense most hypervisor
configuration into one place.

The initial plugin implemented was for Docker support and is a useful
template for the required support. Plugins are placed in
``lib/nova_plugins`` and named ``hypervisor-<name>`` where ``<name>`` is
the value of ``VIRT_DRIVER``. Plugins must define the following
functions:

-  ``install_nova_hypervisor`` - install any external requirements
-  ``configure_nova_hypervisor`` - make configuration changes, including
   those to other services
-  ``start_nova_hypervisor`` - start any external services
-  ``stop_nova_hypervisor`` - stop any external services
-  ``cleanup_nova_hypervisor`` - remove transient data and cache

System Packages
===============

Devstack provides a framework for getting packages installed at an early
phase of its execution. This 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.
