.. -*- mode: rst -*-

.. _development-client-driver:

==============================
 Writing A Client Tool Driver
==============================

This page describes the step-by-step process of writing a client tool
driver for a configuration element type. The included example describes
an existing driver, and the process that was used to create it.

#. Pick a name for the driver. In this case, we picked the name RPM.
#. Create a file in ``src/lib/Bcfg2/Client/Tools`` with the same name
   (RPM.py)
#. Create a class in this file with the same name (``class RPM``)

   * If it handles **Package** entries, subclass
     :class:`Bcfg2.Client.Tools.PkgTool`
   * If it handles **Service** entries, subclass
     :class:`Bcfg2.Client.Tools.SvcTool`
   * Otherwise, subclass :class:`Bcfg2.Client.Tools.Tool`.

#. Add any required executable programs to
   :attr:`Bcfg2.Client.Tools.Tool.__execs__`
#. Set :attr:`Bcfg2.Client.Tools.Tool.__handles__` to a list of
   ``(<tag>, <type>)`` tuples. This determines which entries the Tool
   module can be used on. In this case, we set ``__handles__ =
   [('Package', 'rpm')]``.
#. Add verification support by defining a method named
   ``Verify<tag>``. See :func:`Bcfg2.Client.Tools.Tool.Inventory` for
   details. This method should return True/False depending on current
   entry installation status. In the failure path, the current state
   of failing entry attributes should be set in the entry, to aid in
   auditing.  (For example, if a file should be mode 644, and is
   currently mode 600, then set attribute current_mode='600' in the
   input entry)
#. Add installation support by defining a method named
   ``Install<tag``.  See :func:`Bcfg2.Client.Tools.Tool.Install` for
   details. This method should return True/False depending on the
   results of the installation process.

   If you are writing a tool to handle Package entries, PkgTool class
   has a generic mechanism for performing all-at-once installations,
   followed, in the case of failures, by single installations. See
   :func:`Bcfg2.Client.Tools.PkgTool.Install` for details.
#. Optionally, add support for removing extra entries by defining a
   :func:`Bcfg2.Client.Tools.Tool.Remove` method.
#. Optionally, add a :func:`Bcfg2.Client.Tools.Tool.FindExtra` method
   that locates entries not included in the configuration.
#. Package drivers require a
   :func:`Bcfg2.Client.Tools.PkgTool.RefreshPackages` method that
   updates the internal representation of the package database.

Client Tool API
===============

Base Classes
------------

.. autoclass:: Bcfg2.Client.Tools.Tool
.. autoclass:: Bcfg2.Client.Tools.PkgTool
.. autoclass:: Bcfg2.Client.Tools.SvcTool

Helper Classes
--------------

.. autoclass:: Bcfg2.Client.Tools.ToolInstantiationError

See Also
--------

* :ref:`development-compat`
* :ref:`development-utils`

