[yum-cvs] yum PLUGINS,NONE,1.1

Menno Smits mjs at login.linux.duke.edu
Sun Jul 17 02:10:02 UTC 2005

Update of /home/groups/yum/cvs/yum
In directory login:/tmp/cvs-serv3152

Added Files:
Log Message:
Initial add of developer docs for plugins.

Writing Yum Plugins

**Note to Reader:** This document has been written using the ReStructuredText
markup system. Although it will be fine to read as-is, you may prefer to
convert it to HTML first using the rst2html tool from Docutils. The required
command is ``rst2html PLUGINS PLUGINS.html``.

Yum has a simple but powerful plugin architecture which allows external modules
to add new features and/or modify Yum's behaviour. Yum plugins are Python
modules (.py files) which are loaded when Yum starts.

This document explains how to create plugins for Yum. See the yum(8) and
yum.conf(5) man pages for information on how to install and configure
pre-existing plugins.

A Basic Plugin
The following example shows a minimal Yum plugin::

    from yum.plugins import PluginYumExit, TYPE_CORE, TYPE_INTERFACE

    requires_api_version = '2.1'
    plugin_type = (TYPE_CORE, TYPE_INTERFACE)

    def init_hook(conduit):
        conduit.info(2, 'Hello world')

    def postreposetup_hook(conduit):
        raise PluginYumExit('Goodbye')

This plugin will display "Hello world" as it loads and then will cause Yum to
quit with a "Goodbye" message once it has finished initialising its

Slots and Hooks
Plugins integrate with Yum by registering a 'hook' function that corresponds to
a given 'slot'. A slot is simply a point in Yum's execution. All plugin hook
functions for a given slot are called as Yum reaches that slot.

Registration of hook functions is automatic. The plugin module is inspected for
functions named "<slotname>_hook". If a function matching a valid slot name is
found then that function is automatically registered as a hook function.

Hook functions all take one argument, for a 'conduit' instance. Conduits are
explained below.

The following slots exist:

    Called first as plugins are initialised. Plugins that need to extend Yum's
    configuration files or command line options should do so during this slot.

    Called early in Yum's initialisation. May be used for general plugin
    related initialisation.

    Called just before Yum starts downloads of packages.

    Called just before Yum starts downloads of packages. Plugins may access
    information about the packages to be downloaded here.

    Called just after Yum finishes package downloads. Plugins may access
    error information about the packages just downloaded.

    Called just before Yum initialises its repository information.

    Called just after Yum initialises its repository information.

    Called after package inclusion and exclusions are processed. Plugins
    may modify package exclusions here.

    Called before Yum begins package resolution.

    Called just after Yum finishes package resolution.

    Called before Yum begins the RPM update transation.

    Called just after Yum has finished the RPM update transation.

    Called as Yum is performing a normal exit. Plugins may wish to
    perform cleanup functions here.

An object known as a conduit is passed into hook functions when they are
called. This object provides methods and attributes that should be used for all
interaction that the plugin has with the rest of Yum. 

The conduit varies depending on the plugin slot. Different methods and
attributes are available as appropriate for the slot. See the
``yum.plugins.SLOT_TO_CONDUIT`` dictionary for details on the conduit class
used for a particular slot. All conduits are subclassed from the PluginConduit

API Dependencies
The plugin API and general Yum API are subject to change. For this reason,
plugins must state which API they were written for via the
``requires_api_version`` attribute. Yum will exit with a useful error if it
tries to load to plugin which is not compatible with its API version.

In general, a plugin author should set ``requires_api_version`` to the API
version at the time that the plugin is written. The current API version can be
found at ``yum.plugins.API_VERSION``. 

The ``yum.plugins`` module documents how the API version is incremented and the
rules for compatibility tests.

Plugin Types
Plugins must advertise what type of plugin they are via the ``plugin_type``
tuple. The advertised type(s) can be used by software using the Yum libraries
to control the types of plugins that will be loaded. Yum itself will always
load all types of plugins.

A plugin may have more than one type. Two plugin types currently exist. 

    A core plugin modifies Yum's base functionality. For example, a core plugin
    might modify package exclusions, dependency resolving or repository loading.

    An interface plugin modifies Yum's user interface. For example, an
    interface plugin might display extra information to the user or terminate
    Yum early in some conditions.

Stopping Yum
A plugin may stop Yum's execution at any point by raising the
``yum.plugins.PluginYumExit`` exception. The argument of the exception will be
displayed to the user as Yum terminates.

Reading Private Plugin Options
Each plugin has its own configuration file in ``/etc/yum/pluginconf.d/``. These
configuration files follow standard INI file conventions like Yum's own
configuration files. Arbitrary options can be read from a plugin's
configuration file at any time by using the following methods are available on
any conduit instance::

    def confString(self, section, opt, default=None)

    def confInt(self, section, opt, default=None)

    def confFloat(self, section, opt, default=None)

    def confBool(self, section, opt, default=None)

If the option is missing from the configuration file then the default value
passed to method will be returned. See ``yum.plugins`` for more documentation
on these methods and see the yum(8) and yum.conf(5) man pages for general
information on plugin configuration files.

Extending Yum's Configuration Options
In addition to having their own configuration file, plugins may add extra
options to Yum's main configuration files. A plugin must register new options
in the ``config`` slot using the ``registerOpt()`` conduit method::

    registerOpt(name, valuetype, where, default)

where the arguments are...

    The name of the new option.

    The type of the option. Valid values are PLUG_OPT_STRING, PLUG_OPT_INT,
    PLUG_OPT_FLOAT and PLUG_OPT_BOOL (defined in ``yum.constants``). The value
    returned for the option will be automatically parsed according to the type.

    Defines where the option should be available in configuration files. Valid
    values are: 
        - PLUG_OPT_WHERE_MAIN: the option only exists in the [main] section
        - PLUG_OPT_WHERE_REPO: the option only exists in repository sections
        - PLUG_OPT_WHERE_ALL: the option exists in both [main] and repository

    The default value returned for the option if it isn't present.

The option values defined in the [main] section may be read by calling the
getConf() repository method. The options will be available as attributes of the returned object.

New repository options are be available as attributes of the repository objects returned via the getRepos() conduit method.

The following example plugin shows a how a custom option may be defined and

    from yum.constants import *
    from yum.plugins import TYPE_INTERFACE

    requires_api_version = '2.1'
    plugin_type = (TYPE_INTERFACE,)

    def config_hook(conduit):
        conduit.registerOpt('foo', PLUG_OPT_BOOL, PLUG_OPT_WHERE_ALL, False)

    def init_hook(conduit):
        conduit.info(2, "[main] foo=%r" % conduit.getConf().foo)

    def exclude_hook(conduit):
        for repo in conduit.getRepos().listEnabled():
            conduit.info(2, "[%s] foo=%r" % (repo.id, repo.foo))

Extending Yum's Command Line Options
A plugin may add extra command line options to Yum. To do this the plugin
should call the ``getOptParser()`` conduit method during the ``config`` or
``init`` slot. This will return an ``OptionParser`` instance which the plugin
may modify.  See the Python standard library ``optparse`` module documentation
for information on how to manipulation this object.

The parsed command line options may be read in any slot after the ``init``
slot. The values returned are as for ``OptionParser.parse_args()``.

Options added by plugins will show up in Yum's command line help output (ie.
``yum --help``)

The following plugin demonstrates the addition of new command line options by adding a ``--downloadonly`` option::

    from yum.plugins import PluginYumExit, TYPE_INTERFACE

    requires_api_version = '2.0'
    plugin_type = (TYPE_INTERFACE,)

    def config_hook(conduit):
        parser = conduit.getOptParser()
        parser.add_option('', '--downloadonly', dest='dlonly', 
                action='store_true', default=False, 
                help="don't update, just download")

    def postdownload_hook(conduit):
        opts, commands = conduit.getCmdLine()
        if opts.dlonly:
            raise PluginYumExit('exiting because --downloadonly specified ')

More Examples
The easiest way to get started writing Yum plugins is to look at some examples.
The yum-utils package contains a number of useful plugins which will act as a
useful starting point. The yum-utils CVS tree can be viewed here: http://devel.linux.duke.edu/cgi-bin/viewcvs.cgi/yum-utils/

More information about the Yum-cvs-commits mailing list