======
Hooks
======

Custom scripts can be run at certain points in the Bonding startup and
shutdown procedure. This is useful for bonders that have additional
roles, such as running a DHCP or DNS server, or for aggregators with
custom routing rules.

.. toctree::
    :glob:
    :maxdepth: 1
    :caption: Types of hooks:

    *

Hook locations, arguments, and environments
--------------------------------------------

Each object (i.e. bond, leg, connected IP, CPE NAT IP, route, tunnel, or space)
uses hooks in two locations. After an object is configured, the
following occurs:

#. Each script in the appropriate ``all`` directory is executed with the
   argument ``start`` and environmental variables specific to the object.
#. Each script in the appropriate directory with the object's ID is
   executed with the argument ``start``. If that directory doesn't exist,
   then each script in the appropriate ``default`` directory is
   executed.
#. Private WAN router space hooks use the space key rather than ID to specify
   the appropriate directory. For example, if the hook ``20_fizz`` should run
   for a space and its key is "ocean", then the hook should be placed
   in the directory ``/etc/bonding/privatewan-router-space.d/ocean/20_fizz``.

When the leg is deconfigured, the scripts are run with the argument
``stop`` in the reverse order from the object-specific or ``default``
directory and then in the reverse order from the ``all`` directory.

For example, suppose the leg with ID 55 is started by a bonder. The
folder ``/etc/bonding/leg.d/55`` exists. The following scripts would be
executed when the leg is configured:

#. ``/etc/bonding/leg.d/all/10_foo start``

#. ``/etc/bonding/leg.d/all/20_bar start``

#. ``/etc/bonding/leg.d/55/01_baz start``

#. ``/etc/bonding/leg.d/55/60_boo start``

The scripts in ``/etc/bonding/leg.d/default`` would not be executed,
because ``/etc/bonding/leg.d/55 exists``. The default scripts would not
be run even if ``/etc/bonding/leg.d/55`` was empty.

Before the leg is deconfigured, the scripts would be run as:

#. ``/etc/bonding/leg.d/55/60_boo stop``

#. ``/etc/bonding/leg.d/55/01_baz stop``

#. ``/etc/bonding/leg.d/all/20_bar stop``

#. ``/etc/bonding/leg.d/all/10_foo stop``

Or suppose the connected IP with ID 23 is started by a bonder. The
folder ``/etc/bonding/connectedip.d/23`` does *not* exist. The following
scripts would be executed when the Connected IP is configured:

#. ``/etc/bonding/connectedip.d/all/10_foo start``

#. ``/etc/bonding/connectedip.d/all/20_bar start``

#. ``/etc/bonding/connectedip.d/default/01_baz start``

#. ``/etc/bonding/connectedip.d/default/60_boo start``

Before the connected IP is deconfigured, the scripts would be run as:

#. ``/etc/bonding/connectedip.d/default/60_boo stop``

#. ``/etc/bonding/connectedip.d/default/01_baz stop``

#. ``/etc/bonding/connectedip.d/all/20_bar stop``

#. ``/etc/bonding/connectedip.d/all/10_foo stop``

Please consider the following notes:

#. Script names must use only upper and lower case letters, digits,
   underscores, and hyphens. Note that the dot character is forbidden.
#. Scripts in each directory are run in the order of their names. For
   example, a script named ``a`` would come before ``b`` but after ``00_z``.
#. Hooks are executed only if the object is configured successfully. For
   example, if a leg cannot be configured because its interface doesn't
   exist, that hook will not be run.
#. Except where noted, the value of an environmental variable is the
   value provided in the management server.
#. Hook script output to standard error is logged to the bonding log
   file.
#. Hook scripts must be marked as executable in order to be run.
   For example, if the script path was ``/etc/bonding/leg.d/all/10_foo``,
   the command is ``chmod +x /etc/bonding/leg.d/all/10_foo``.

Timeouts
---------

Hooks in a single directory must together run in one second or less, or
a failure will be logged and the object will be deconfigured. If a hook
or group of hooks needs more than one second to run, the hook should
daemonize itself.

The ``daemon`` program
+++++++++++++++++++++++

The ``daemon`` program offers an easy way to ensure a command will return
immediately but continue running in the background.

``Daemon`` can be used to make a long-running hook exit immediately-just
add ``daemon`` to the beginning of the long-running command. For
example, a hook containing the following command:

::

    service isc-dhcp-server restart

could be changed to:

::

    daemon service isc-dhcp-server restart

to ensure it returns within the one second limit.
