Developing for Bcfg2
While the Bcfg2 server provides a good interface for representing
general system configurations, its plugin interface offers the
ability to implement configuration interfaces and representation
tailored to problems encountered by a particular site. This
chapter describes what plugins are good for, what they can do, and
how to implement them.
Bcfg2 Plugins
Bcfg2 plugins are loadable python modules that the Bcfg2 server
loads at initialization time. These plugins can contribute to
the functions already offered by the Bcfg2 server or can extend
its functionality. In general, plugins will provide some portion
of the configuration for clients, with a data representation
that is tuned for a set of common tasks. Much of the core
functionality of Bcfg2 is implemented by several plugins,
however, they are not special in any way; new plugins could
easily supplant one or all of them.
Bcfg2 Plugin Functions
NameDescription
ProbesPlugins can send executable
code to clients, where local contributions to configuration
state can be gathered.
Abstract Configuration Structures
A plugin can define new groups of interdependent
and independent configuration entities
Literal Configuration Entities
Plugins can provide literal configuration entity
information.
XML-RPC Functions
Plugins can expose a set of functions through the
Bcfg2 server's authenticated XML-RPC interface.
Writing Bcfg2 Plugins
Bcfg2 plugins are python classes that subclass from
Bcfg2.Server.Plugin.Plugin. Several plugin-specific values must
be set in the new plugin. These values dictate how the new
plugin will behave with respect to the above four functions.
Bcfg2 Plugin Members
NameDescriptionFormat
__name__The name of the
pluginstring
__version__
The plugin version (generally tied to revctl
keyword expansion).string
__author__
The plugin author.string
__rmi__
Set of functions to be exposed as XML-RPC
functions
List of function names (strings)
EntriesMultidimentional
dictionary of keys that point to the function used to bind
literal contents for a given configuration
entity.Dictionary of
ConfigurationEntityType, Name keys and function reference
values
BuildStructuresFunction that
returns a list of the structures for a given
clientMember function
GetProbesFunction that returns a
list of probes that a given client should
executeMember function
ReceiveDataFunction that accepts
the probe results for a given client.Member
function
An Example Plugin
A Simple Plugin
import socket, Bcfg2.Server.Plugin
class Chiba(Bcfg2.Server.Plugin.Plugin):
'''the Chiba plugin builds the following files:
-> /etc/network/interfaces'''
__name__ = 'Chiba'
__version__ = '$Id: chiba.py 1702 2006-01-19 20:20:51Z desai '
__author__ = 'bcfg-dev@mcs.anl.gov'
Entries = {'ConfigFile':{}}
def __init__(self, core, datastore):
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
self.repo = Bcfg2.Server.Plugin.DirectoryBacked(self.data,
self.core.fam)
self.Entries['ConfigFile']['/etc/network/interfaces'] \
= self.build_interfaces
def build_interfaces(self, entry, metadata):
'''build network configs for clients'''
entry.attrib['owner'] = 'root'
entry.attrib['group'] = 'root'
entry.attrib['perms'] = '0644'
try:
myriaddr = socket.gethostbyname("%s-myr" % \
metadata.hostname)
except socket.gaierror:
self.LogError("Failed to resolve %s-myr"% metadata.hostname)
raise Bcfg2.Server.Plugin.PluginExecutionError, ("%s-myr" \
% metadata.hostname, 'lookup')
entry.text = self.repo.entries['interfaces-template'].data % \
myriaddr
Bcfg2 server plugins must subclass the
Bcfg2.Server.Plugin.Plugin class. Plugin constructors must
take two arguments: an instance of a Bcfg2.Core object, and a
location for a datastore. __name__, __version__, __author__,
and Entries are used to describe what the plugin is and how it
works. Entries describes a set of configuration entries that
can be provided by the generator, and a set of handlers that
can bind in the proper data. build_interfaces is an example of
a handler. It gets client metadata and an configuration entry
passed in, and binds data into entry as appropriate. This
results in a /etc/network/interfaces file
that has static information derived from DNS for a given host.