<!--
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
#              C E D A R
#          S O L U T I O N S       "Software done right."
#           S O F T W A R E
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Copyright (c) 2005-2007,2010,2015 Kenneth J. Pronovici.
# All rights reserved.
#
# This work is free; you can redistribute it and/or modify it
# under the terms of the GNU General Public License, Version 2,
# as published by the Free Software Foundation.
#
# This work is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# Copies of the GNU General Public License are available from
# the Free Software Foundation website, http://www.gnu.org/.
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Author   : Kenneth J. Pronovici <pronovic@ieee.org>
# Language : O'Reilly DocBook Lite XML DTD
# Project  : Cedar Backup, release 2
# Purpose  : Cedar Backup Software Manual, extensions appendix.
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-->

<appendix id="cedar-extenspec">

   <title>Extension Architecture Interface</title>

   <simplesect>

      <para>
         The Cedar Backup <firstterm>Extension Architecture
         Interface</firstterm> is the application programming interface used by
         third-party developers to write Cedar Backup extensions.  This
         appendix briefly specifies the interface in enough detail for
         someone to succesfully implement an extension.
      </para>

      <para>
         You will recall that Cedar Backup extensions are third-party pieces of
         code which extend Cedar Backup's functionality.  Extensions can be
         invoked from the Cedar Backup command line and are allowed to place
         their configuration in Cedar Backup's configuration file.
      </para>

      <para>
         There is a one-to-one mapping between a command-line extended action
         and an extension function.  The mapping is configured in the Cedar
         Backup configuration file using a section something like this:
      </para>

      <programlisting>
&lt;extensions&gt;
   &lt;action&gt;
      &lt;name&gt;database&lt;/name&gt;
      &lt;module&gt;foo&lt;/module&gt;
      &lt;function&gt;bar&lt;/function&gt;
      &lt;index&gt;101&lt;/index&gt;
   &lt;/action&gt; 
&lt;/extensions&gt;
      </programlisting>

      <para>
         In this case, the action <quote>database</quote> has been mapped to
         the extension function <literal>foo.bar()</literal>.  
      </para>

      <para>
         Extension functions can take any actions they would like to once they
         have been invoked, but must abide by these rules:
      </para>

      <orderedlist>

         <listitem>
            <para>
               Extensions may not write to <filename>stdout</filename> or
               <filename>stderr</filename> using functions such as
               <literal>print</literal> or <literal>sys.write</literal>.
            </para>
         </listitem>

         <listitem>
            <para>
               All logging must take place using the Python logging
               facility.  Flow-of-control logging should happen on the
               <literal>CedarBackup2.log</literal> topic.  Authors can assume
               that ERROR will always go to the terminal, that INFO and WARN
               will always be logged, and that DEBUG will be ignored unless
               debugging is enabled.
            </para>
         </listitem>

         <listitem>
            <para>
               Any time an extension invokes a command-line utility, it must be
               done through the <literal>CedarBackup2.util.executeCommand</literal>
               function.  This will help keep Cedar Backup safer from
               format-string attacks, and will make it easier to consistently
               log command-line process output.
            </para>
         </listitem>

         <listitem>
            <para>
               Extensions may not return any value.  
            </para>
         </listitem>

         <listitem>
            <para>
               Extensions must throw a Python exception containing a
               descriptive message if processing fails.  Extension authors can
               use their judgement as to what constitutes failure; however, any
               problems during execution should result in either a thrown
               exception or a logged message.
            </para>
         </listitem>

         <listitem>
            <para>
               Extensions may rely only on Cedar Backup functionality that is
               advertised as being part of the public interface.  This means
               that extensions cannot directly make use of methods, functions
               or values starting with with the <literal>_</literal> character.
               Furthermore, extensions should only rely on parts of the public
               interface that are documented in the online Epydoc
               documentation.
            </para>
         </listitem>

         <listitem>
            <para>
               Extension authors are encouraged to extend the Cedar Backup
               public interface through normal methods of inheritence.
               However, no extension is allowed to directly change Cedar Backup
               code in a way that would affect how Cedar Backup itself executes
               when the extension has not been invoked.  For instance,
               extensions would not be allowed to add new command-line options
               or new writer types.
            </para>
         </listitem>

         <listitem>
            <para>
               Extensions must be written to assume an empty locale set (no
               <literal>$LC_*</literal> settings) and
               <literal>$LANG=C</literal>.  For the typical open-source
               software project, this would imply writing output-parsing code
               against the English localization (if any).  The
               <literal>executeCommand</literal> function does sanitize the
               environment to enforce this configuration.
            </para>
         </listitem>


      </orderedlist>
    
      <para>
         Extension functions take three arguments: the path to configuration on
         disk, a <literal>CedarBackup2.cli.Options</literal> object
         representing the command-line options in effect, and a
         <literal>CedarBackup2.config.Config</literal> object representing
         parsed standard configuration.   
      </para>

      <programlisting>
def function(configPath, options, config):
   """Sample extension function."""
   pass
      </programlisting>

      <para>
         This interface is structured so that simple extensions can use
         standard configuration without having to parse it for themselves, but
         more complicated extensions can get at the configuration file on disk
         and parse it again as needed.
      </para>

      <para>
         The interface to the <literal>CedarBackup2.cli.Options</literal> and
         <literal>CedarBackup2.config.Config</literal> classes has been
         thoroughly documented using Epydoc, and the documentation is available
         on the Cedar Backup website.  The interface is guaranteed to change
         only in backwards-compatible ways unless the Cedar Backup major
         version number is bumped (i.e. from 2 to 3).
      </para>
         
      <para>
         If an extension needs to add its own configuration information to the
         Cedar Backup configuration file, this extra configuration must be
         added in a new configuration section using a name that does not
         conflict with standard configuration or other known extensions.
      </para>

      <para>
         For instance, our hypothetical database extension might require
         configuration indicating the path to some repositories to back up.
         This information might go into a section something like this:
      </para>

      <programlisting>
&lt;database&gt;
   &lt;repository&gt;/path/to/repo1&lt;/repository&gt;
   &lt;repository&gt;/path/to/repo2&lt;/repository&gt;
&lt;/database&gt;
      </programlisting>

      <para>
         In order to read this new configuration, the extension code can either
         inherit from the <literal>Config</literal> object and create a
         subclass that knows how to parse the new <literal>database</literal>
         config section, or can write its own code to parse whatever it needs
         out of the file.  Either way, the resulting code is completely
         independent of the standard Cedar Backup functionality.
      </para>

   </simplesect>

</appendix>

