summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNarayan Desai <desai@mcs.anl.gov>2009-01-05 03:24:50 +0000
committerNarayan Desai <desai@mcs.anl.gov>2009-01-05 03:24:50 +0000
commita9388f7859586d5d98e815efdcf8d6a85b973bef (patch)
tree8adaf09fbd9cc5d4e3cd0dbf69ebcaade4577f76
parentd3f79b55f57787a75773459dbc70a5504c7ddcf3 (diff)
downloadbcfg2-a9388f7859586d5d98e815efdcf8d6a85b973bef.tar.gz
bcfg2-a9388f7859586d5d98e815efdcf8d6a85b973bef.tar.bz2
bcfg2-a9388f7859586d5d98e815efdcf8d6a85b973bef.zip
This patch is stage 1 of the plugin capabilities rework
- define new plugin base classes - switch Plugin.__name__ => Plugin.name git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@5004 ce84e21b-d406-0410-9b95-82705330c041
-rw-r--r--src/lib/Server/Core.py19
-rw-r--r--src/lib/Server/Plugin.py43
-rw-r--r--src/lib/Server/Plugins/Account.py6
-rw-r--r--src/lib/Server/Plugins/BB.py28
-rw-r--r--src/lib/Server/Plugins/Base.py16
-rw-r--r--src/lib/Server/Plugins/Bundler.py6
-rw-r--r--src/lib/Server/Plugins/Cfg.py2
-rw-r--r--src/lib/Server/Plugins/DBStats.py22
-rw-r--r--src/lib/Server/Plugins/Decisions.py9
-rw-r--r--src/lib/Server/Plugins/Deps.py2
-rw-r--r--src/lib/Server/Plugins/Editor.py7
-rw-r--r--src/lib/Server/Plugins/Hostbase.py48
-rw-r--r--src/lib/Server/Plugins/Metadata.py8
-rw-r--r--src/lib/Server/Plugins/NagiosGen.py6
-rw-r--r--src/lib/Server/Plugins/Pkgmgr.py2
-rw-r--r--src/lib/Server/Plugins/Probes.py16
-rw-r--r--src/lib/Server/Plugins/Rules.py4
-rw-r--r--src/lib/Server/Plugins/SGenshi.py7
-rw-r--r--src/lib/Server/Plugins/SSHbase.py25
-rw-r--r--src/lib/Server/Plugins/Statistics.py42
-rw-r--r--src/lib/Server/Plugins/Svcmgr.py2
-rw-r--r--src/lib/Server/Plugins/TCheetah.py2
-rw-r--r--src/lib/Server/Plugins/TGenshi.py2
-rwxr-xr-xsrc/sbin/bcfg2-info2
-rwxr-xr-xsrc/sbin/bcfg2-server2
25 files changed, 172 insertions, 156 deletions
diff --git a/src/lib/Server/Core.py b/src/lib/Server/Core.py
index 3c8a8c429..d4f9b9f6e 100644
--- a/src/lib/Server/Core.py
+++ b/src/lib/Server/Core.py
@@ -63,7 +63,7 @@ class Core(object):
while True:
try:
plugin = chk_plugins.pop()
- if isinstance(plugin, Bcfg2.Server.Plugin.MetadataPlugin):
+ if isinstance(plugin, Bcfg2.Server.Plugin.Metadata):
self.metadata = plugin
break
except:
@@ -77,7 +77,7 @@ class Core(object):
while True:
try:
plugin = chk_plugins.pop()
- if isinstance(plugin, Bcfg2.Server.Plugin.StatisticsPlugin):
+ if isinstance(plugin, Bcfg2.Server.Plugin.Statistics):
self.stats = plugin
break
except:
@@ -88,11 +88,11 @@ class Core(object):
break
for plug_names, plug_tname, plug_type, collection in \
- [(structures, 'structure', Bcfg2.Server.Plugin.StructurePlugin,
+ [(structures, 'structure', Bcfg2.Server.Plugin.Structure,
self.structures),
- (generators, 'generator', Bcfg2.Server.Plugin.GeneratorPlugin,
+ (generators, 'generator', Bcfg2.Server.Plugin.Generator,
self.generators),
- (connectors, 'connector', Bcfg2.Server.Plugin.MetadataConnectorPlugin,
+ (connectors, 'connector', Bcfg2.Server.Plugin.Connector,
self.connectors),
]:
for plugin in plug_names:
@@ -170,7 +170,7 @@ class Core(object):
if len(glist) == 1:
return glist[0].Entries[entry.tag][entry.get('name')](entry, metadata)
elif len(glist) > 1:
- generators = ", ".join([gen.__name__ for gen in glist])
+ generators = ", ".join([gen.name for gen in glist])
logger.error("%s %s served by multiple generators: %s" % \
(entry.tag, entry.get('name'), generators))
g2list = [gen for gen in self.generators if gen.HandlesEntry(entry)]
@@ -246,17 +246,16 @@ class Core(object):
result = []
for plugin in self.plugins.values():
try:
- if isinstance(plugin, Bcfg2.Server.Plugin.DecisionPlugin):
+ if isinstance(plugin, Bcfg2.Server.Plugin.Decision):
result += plugin.GetDecisions(metadata, mode)
except:
- logger.error("Plugin: %s failed to generate decision list" % plugin.__name__, exc_info=1)
+ logger.error("Plugin: %s failed to generate decision list" % plugin.name, exc_info=1)
return result
def build_metadata(self, client_name):
imd = self.metadata.get_initial_metadata(client_name)
for conn in self.connectors:
grps, data = conn.get_additional_metadata(imd)
- self.metadata.merge_additional_metadata(imd, conn.__name__,
- grps, data)
+ self.metadata.merge_additional_metadata(imd, conn.name, grps, data)
return imd
diff --git a/src/lib/Server/Plugin.py b/src/lib/Server/Plugin.py
index 5a8731606..49f498a5e 100644
--- a/src/lib/Server/Plugin.py
+++ b/src/lib/Server/Plugin.py
@@ -26,7 +26,7 @@ class PluginExecutionError(Exception):
class Plugin(object):
'''This is the base class for all Bcfg2 Server plugins. Several attributes must be defined
in the subclass:
- __name__ : the name of the plugin
+ name : the name of the plugin
__version__ : a version string
__author__ : the author/contact for the plugin
@@ -35,7 +35,7 @@ class Plugin(object):
- Configuration entry binding (overloading HandlesEntry, or loads the Entries table)
- Data collection (overloading GetProbes/ReceiveData)
'''
- __name__ = 'Plugin'
+ name = 'Plugin'
__version__ = '$Id$'
__author__ = 'bcfg-dev@mcs.anl.gov'
__rmi__ = []
@@ -45,10 +45,10 @@ class Plugin(object):
object.__init__(self)
self.Entries = {}
self.core = core
- self.data = "%s/%s" % (datastore, self.__name__)
- self.logger = logging.getLogger('Bcfg2.Plugins.%s' % (self.__name__))
+ self.data = "%s/%s" % (datastore, self.name)
+ self.logger = logging.getLogger('Bcfg2.Plugins.%s' % (self.name))
-class GeneratorPlugin(Plugin):
+class Generator(object):
'''Generator plugins contribute to literal client configurations'''
def HandlesEntry(self, entry):
'''This is the slow path method for routing configuration binding requests'''
@@ -66,18 +66,13 @@ class GeneratorPlugin(Plugin):
of bcfg2-admin pull'''
raise PluginExecutionError
- def CommitChanges(self):
- '''Handle revctl commits, if needed'''
- # not implemented yet
- pass
-
-class StructurePlugin(Plugin):
+class Structure(object):
'''Structure Plugins contribute to abstract client configurations'''
def BuildStructures(self, metadata):
'''return a list of abstract goal structures for client'''
raise PluginExecutionError
-class MetadataPlugin(Plugin):
+class Metadata(object):
'''Signal metadata capabilities for this plugin'''
def add_client(self, client_name, attribs):
'''add client'''
@@ -95,13 +90,13 @@ class MetadataPlugin(Plugin):
def merge_additional_metadata(self, imd, source, groups, data):
raise PluginExecutionError
-class MetadataConnectorPlugin(Plugin):
+class Connector(object):
'''MetadataConnectorPlugins augment client metadata instances'''
def get_additional_metadata(self, metadata):
'''determine additional ([groups], {k:v}) for metadata'''
return (list(), dict())
-class ProbingPlugin(Plugin):
+class Probing(object):
'''Signal probe capability for this plugin'''
def GetProbes(self, _):
'''Return a set of probes for execution on client'''
@@ -111,7 +106,7 @@ class ProbingPlugin(Plugin):
'''Receive probe results pertaining to client'''
pass
-class StatisticsPlugin(Plugin):
+class Statistics(object):
'''Signal statistics handling capability'''
def StoreStatistics(self, client, xdata):
pass
@@ -119,13 +114,15 @@ class StatisticsPlugin(Plugin):
def WriteBack(self):
pass
+
+class PullSource(object):
def GetExtra(self, client):
return []
def GetCurrentEntry(self, client, e_type, e_name):
raise PluginExecutionError
-class DecisionPlugin(Plugin):
+class Decision(object):
'''Signal decision handling capability'''
def GetDecisions(self, metadata, mode):
return []
@@ -381,17 +378,18 @@ class XMLDirectoryBacked(DirectoryBacked):
'''Directorybacked for *.xml'''
patterns = re.compile('.*\.xml')
-class PrioDir(GeneratorPlugin, XMLDirectoryBacked):
+class PrioDir(Plugin, Generator, XMLDirectoryBacked):
'''This is a generator that handles package assignments'''
- __name__ = 'PrioDir'
+ name = 'PrioDir'
__child__ = XMLSrc
def __init__(self, core, datastore):
Plugin.__init__(self, core, datastore)
+ Generator.__init__(self)
try:
XMLDirectoryBacked.__init__(self, self.data, self.core.fam)
except OSError:
- self.logger.error("Failed to load %s indices" % (self.__name__))
+ self.logger.error("Failed to load %s indices" % (self.name))
raise PluginInitError
def HandleEvent(self, event):
@@ -653,9 +651,9 @@ class FakeProperties:
def __init__(self):
self.properties = lxml.etree.Element("Properties")
-class GroupSpool(GeneratorPlugin):
+class GroupSpool(Plugin, Generator):
'''The TGenshi generator implements a templating mechanism for configuration files'''
- __name__ = 'GroupSpool'
+ name = 'GroupSpool'
__version__ = '$Id$'
__author__ = 'bcfg-dev@mcs.anl.gov'
use_props = False
@@ -665,6 +663,7 @@ class GroupSpool(GeneratorPlugin):
def __init__(self, core, datastore):
Plugin.__init__(self, core, datastore)
+ Generator.__init__(self)
if self.data[-1] == '/':
self.data = self.data[:-1]
self.Entries['ConfigFile'] = {}
@@ -678,7 +677,7 @@ class GroupSpool(GeneratorPlugin):
'%s/../etc/properties.xml' % (self.data), self.core.fam)
except:
self.properties = FakeProperties()
- self.logger.info("%s properties disabled" % self.__name__)
+ self.logger.info("%s properties disabled" % self.name)
else:
self.properties = FakeProperties()
diff --git a/src/lib/Server/Plugins/Account.py b/src/lib/Server/Plugins/Account.py
index dd44390e1..86892dcaf 100644
--- a/src/lib/Server/Plugins/Account.py
+++ b/src/lib/Server/Plugins/Account.py
@@ -3,7 +3,8 @@ __revision__ = '$Revision$'
import Bcfg2.Server.Plugin
-class Account(Bcfg2.Server.Plugin.GeneratorPlugin):
+class Account(Bcfg2.Server.Plugin.Plugin,
+ Bcfg2.Server.Plugin.Generator):
'''This module generates account config files,
based on an internal data repo:
static.(passwd|group|limits.conf) -> static entries
@@ -12,12 +13,13 @@ class Account(Bcfg2.Server.Plugin.GeneratorPlugin):
superusers -> users to be granted root privs on all hosts
rootlike -> users to be granted root privs on some hosts
'''
- __name__ = 'Account'
+ name = 'Account'
__version__ = '$Id$'
__author__ = 'bcfg-dev@mcs.anl.gov'
def __init__(self, core, datastore):
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
+ Bcfg2.Server.Plugin.Generator.__init__(self)
self.Entries = {'ConfigFile':{'/etc/passwd':self.from_yp_cb,
'/etc/group':self.from_yp_cb,
'/etc/security/limits.conf':self.gen_limits_cb,
diff --git a/src/lib/Server/Plugins/BB.py b/src/lib/Server/Plugins/BB.py
index 70b90016b..1e5166500 100644
--- a/src/lib/Server/Plugins/BB.py
+++ b/src/lib/Server/Plugins/BB.py
@@ -19,18 +19,16 @@ DOMAIN_SUFFIX = ".mcs.anl.gov" # default is .mcs.anl.gov
PXE_CONFIG = "pxelinux.0" # default is pxelinux.0
-class BB(Bcfg2.Server.Plugin.GeneratorPlugin,
- Bcfg2.Server.Plugin.StructurePlugin,
- Bcfg2.Server.Plugins.Metadata.Metadata,
+class BB(Bcfg2.Server.Plugins.Metadata.Metadata,
Bcfg2.Server.Plugin.DirectoryBacked):
'''BB Plugin handles bb node configuration'''
- __name__ = 'BB'
+ name = 'BB'
experimental = True
write_to_disk = True
def __init__(self, core, datastore):
- Bcfg2.Server.Plugin.GeneratorPlugin.__init__(self, core, datastore)
+ Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
try:
Bcfg2.Server.Plugin.DirectoryBacked.__init__(self, self.data, self.core.fam)
except OSError, ioerr:
@@ -43,8 +41,8 @@ class BB(Bcfg2.Server.Plugin.GeneratorPlugin,
'/etc/sudoers':self.gen_sudoers,
'/etc/dhcp3/dhcpd.conf':self.gen_dhcpd}}
self.nodes = {}
- self.dhcpd_loaded = False
- self.need_update = False
+ self.dhcpd_loaded = False
+ self.need_update = False
def viz(self, hosts, bundles, key, colors):
'''admin mode viz support'''
@@ -266,11 +264,11 @@ class BB(Bcfg2.Server.Plugin.GeneratorPlugin,
'''Handle events'''
Bcfg2.Server.Plugin.DirectoryBacked.HandleEvent(self, event)
# static.dhcpd.conf hack
- if 'static.dhcpd.conf' in self.entries:
- self.dhcpd_loaded = True
- if self.need_update and self.dhcpd_loaded:
- self.update_dhcpd()
- self.need_update = False
+ if 'static.dhcpd.conf' in self.entries:
+ self.dhcpd_loaded = True
+ if self.need_update and self.dhcpd_loaded:
+ self.update_dhcpd()
+ self.need_update = False
# send events to groups.xml back to Metadata plugin
if event and "groups.xml" == event.filename:
Bcfg2.Server.Plugins.Metadata.Metadata.HandleEvent(self, event)
@@ -331,6 +329,6 @@ class BB(Bcfg2.Server.Plugin.GeneratorPlugin,
except OSError:
self.logger.error("failed to find link for mac address %s" % mac)
if self.dhcpd_loaded:
- self.update_dhcpd()
- else:
- self.need_update = True
+ self.update_dhcpd()
+ else:
+ self.need_update = True
diff --git a/src/lib/Server/Plugins/Base.py b/src/lib/Server/Plugins/Base.py
index 8cd1e4fa8..223e4de43 100644
--- a/src/lib/Server/Plugins/Base.py
+++ b/src/lib/Server/Plugins/Base.py
@@ -5,10 +5,12 @@ import Bcfg2.Server.Plugin
import copy
import lxml.etree
-class Base(Bcfg2.Server.Plugin.StructurePlugin,
+class Base(Bcfg2.Server.Plugin.Plugin,
+ Bcfg2.Server.Plugin.Structure,
Bcfg2.Server.Plugin.XMLDirectoryBacked):
- '''This Structure is good for the pile of independent configs needed for most actual systems'''
- __name__ = 'Base'
+ '''This Structure is good for the pile of independent configs
+ needed for most actual systems'''
+ name = 'Base'
__version__ = '$Id$'
__author__ = 'bcfg-dev@mcs.anl.gov'
__child__ = Bcfg2.Server.Plugin.StructFile
@@ -16,8 +18,11 @@ class Base(Bcfg2.Server.Plugin.StructurePlugin,
'''base creates independent clauses based on client metadata'''
def __init__(self, core, datastore):
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
+ Bcfg2.Server.Plugin.Structure.__init__(self)
try:
- Bcfg2.Server.Plugin.XMLDirectoryBacked.__init__(self, self.data, self.core.fam)
+ Bcfg2.Server.Plugin.XMLDirectoryBacked.__init__(self,
+ self.data,
+ self.core.fam)
except OSError:
self.logger.error("Failed to load Base repository")
raise Bcfg2.Server.Plugin.PluginInitError
@@ -26,6 +31,7 @@ class Base(Bcfg2.Server.Plugin.StructurePlugin,
'''Build structures for client described by metadata'''
ret = lxml.etree.Element("Independant", version='2.0')
fragments = reduce(lambda x, y: x+y,
- [base.Match(metadata) for base in self.entries.values()], [])
+ [base.Match(metadata) for base
+ in self.entries.values()], [])
[ret.append(copy.deepcopy(frag)) for frag in fragments]
return [ret]
diff --git a/src/lib/Server/Plugins/Bundler.py b/src/lib/Server/Plugins/Bundler.py
index 5cc881167..fe73ab453 100644
--- a/src/lib/Server/Plugins/Bundler.py
+++ b/src/lib/Server/Plugins/Bundler.py
@@ -3,16 +3,18 @@ __revision__ = '$Revision$'
import copy, lxml.etree, Bcfg2.Server.Plugin
-class Bundler(Bcfg2.Server.Plugin.StructurePlugin,
+class Bundler(Bcfg2.Server.Plugin.Plugin,
+ Bcfg2.Server.Plugin.Structure,
Bcfg2.Server.Plugin.XMLDirectoryBacked):
'''The bundler creates dependent clauses based on the bundle/translation scheme from bcfg1'''
- __name__ = 'Bundler'
+ name = 'Bundler'
__version__ = '$Id$'
__author__ = 'bcfg-dev@mcs.anl.gov'
__child__ = Bcfg2.Server.Plugin.StructFile
def __init__(self, core, datastore):
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
+ Bcfg2.Server.Plugin.Structure.__init__(self)
try:
Bcfg2.Server.Plugin.XMLDirectoryBacked.__init__(self, self.data, self.core.fam)
except OSError:
diff --git a/src/lib/Server/Plugins/Cfg.py b/src/lib/Server/Plugins/Cfg.py
index 864d4a8d4..02d912206 100644
--- a/src/lib/Server/Plugins/Cfg.py
+++ b/src/lib/Server/Plugins/Cfg.py
@@ -127,7 +127,7 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet):
class Cfg(Bcfg2.Server.Plugin.GroupSpool):
'''This generator in the configuration file repository for bcfg2'''
- __name__ = 'Cfg'
+ name = 'Cfg'
__version__ = '$Id$'
__author__ = 'bcfg-dev@mcs.anl.gov'
use_props = False
diff --git a/src/lib/Server/Plugins/DBStats.py b/src/lib/Server/Plugins/DBStats.py
index eb5e89282..24a030b64 100644
--- a/src/lib/Server/Plugins/DBStats.py
+++ b/src/lib/Server/Plugins/DBStats.py
@@ -1,19 +1,23 @@
import Bcfg2.Server.Plugin
import Bcfg2.Server.Reports.importscript
-from Bcfg2.Server.Reports.reports.models import Client, Entries
-import difflib, lxml.etree, time, logging, datetime
+from Bcfg2.Server.Reports.reports.models import Client
+import difflib, lxml.etree, time, logging
import Bcfg2.Server.Reports.settings
from Bcfg2.Server.Reports.updatefix import update_database
-import traceback
# for debugging output only
logger = logging.getLogger('Bcfg2.Plugins.DBStats')
-class DBStats(Bcfg2.Server.Plugin.StatisticsPlugin):
- __name__ = 'DBStats'
+class DBStats(Bcfg2.Server.Plugin.Plugin,
+ Bcfg2.Server.Plugin.Statistics,
+ Bcfg2.Server.Plugin.PullSource):
+ name = 'DBStats'
__version__ = '$Id$'
def __init__(self, core, datastore):
+ Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
+ Bcfg2.Server.Plugin.Statistics.__init__(self)
+ Bcfg2.Server.Plugin.PullSource.__init__(self)
self.cpath = "%s/Metadata/clients.xml" % datastore
self.core = core
logger.debug("Searching for new models to add to the statistics database")
@@ -34,17 +38,19 @@ class DBStats(Bcfg2.Server.Plugin.StatisticsPlugin):
# FIXME need to build a metadata interface to expose a list of clients
# FIXME Server processing the request should be mentionned here
start = time.time()
- for i in [1,2,3]:
+ for i in [1, 2, 3]:
try:
Bcfg2.Server.Reports.importscript.load_stats(
self.core.metadata.clientdata, container, 0, True)
break
except:
- logger.error("DBStats: Failed to write data to database due to lock; retrying", exc_info=1)
+ logger.error("DBStats: Failed to write to db (lock); retrying",
+ exc_info=1)
if i == 3:
logger.error("DBStats: Retry limit failed; aborting operation")
return
- logger.info("Imported data in the reason fast path in %s second" % (time.time() - start))
+ logger.info("Imported data in the reason fast path in %s second" \
+ % (time.time() - start))
def GetExtra(self, client):
c_inst = Client.objects.filter(name=client)[0]
diff --git a/src/lib/Server/Plugins/Decisions.py b/src/lib/Server/Plugins/Decisions.py
index 890101f24..db9754ee3 100644
--- a/src/lib/Server/Plugins/Decisions.py
+++ b/src/lib/Server/Plugins/Decisions.py
@@ -34,8 +34,10 @@ class DecisionSet(Bcfg2.Server.Plugin.EntrySet):
ret += c.get_decisions()
return ret
-class Decisions(DecisionSet, Bcfg2.Server.Plugin.DecisionPlugin):
- __name__ = 'Decisions'
+class Decisions(Bcfg2.Server.Plugin.Plugin,
+ Bcfg2.Server.Plugin.Decision,
+ DecisionSet):
+ name = 'Decisions'
__version__ = '$Id$'
__author__ = 'bcfg-dev@mcs.anl.gov'
@@ -46,6 +48,7 @@ class Decisions(DecisionSet, Bcfg2.Server.Plugin.DecisionPlugin):
- `core`: Bcfg2.Core instance
- `datastore`: File repository location
"""
- Bcfg2.Server.Plugin.DecisionPlugin.__init__(self, core, datastore)
+ Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
+ Bcfg2.Server.Plugin.Decision.__init__(self)
DecisionSet.__init__(self, self.data, core.fam, core.encoding)
diff --git a/src/lib/Server/Plugins/Deps.py b/src/lib/Server/Plugins/Deps.py
index 8749f2a31..cd9c4b79f 100644
--- a/src/lib/Server/Plugins/Deps.py
+++ b/src/lib/Server/Plugins/Deps.py
@@ -35,7 +35,7 @@ class DepXMLSrc(Bcfg2.Server.Plugin.XMLSrc):
__node__ = DNode
class Deps(Bcfg2.Server.Plugin.PrioDir):
- __name__ = 'Deps'
+ name = 'Deps'
__version__ = '$Id:$'
__author__ = 'bcfg-dev@mcs.anl.gov'
__child__ = DepXMLSrc
diff --git a/src/lib/Server/Plugins/Editor.py b/src/lib/Server/Plugins/Editor.py
index ff89d90fd..6e2204e42 100644
--- a/src/lib/Server/Plugins/Editor.py
+++ b/src/lib/Server/Plugins/Editor.py
@@ -50,9 +50,10 @@ class EditEntrySet(Bcfg2.Server.Plugin.EntrySet):
return self.inputs[client]
-class Editor(Bcfg2.Server.Plugin.GroupSpool,Bcfg2.Server.Plugin.ProbingPlugin):
- __name__ = 'Editor'
- __version__ = '1'
+class Editor(Bcfg2.Server.Plugin.GroupSpool,
+ Bcfg2.Server.Plugin.Probing):
+ name = 'Editor'
+ __version__ = '$Id: $'
__author__ = 'bcfg2-dev@mcs.anl.gov'
filename_pattern = 'edits'
es_child_cls = EditDirectives
diff --git a/src/lib/Server/Plugins/Hostbase.py b/src/lib/Server/Plugins/Hostbase.py
index b08e847da..c61fdace3 100644
--- a/src/lib/Server/Plugins/Hostbase.py
+++ b/src/lib/Server/Plugins/Hostbase.py
@@ -1,11 +1,11 @@
'''This file provides the Hostbase plugin. It manages dns/dhcp/nis host information'''
__revision__ = '$Revision$'
-import sys, os
+import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'Bcfg2.Server.Hostbase.settings'
from lxml.etree import Element, SubElement
-from syslog import syslog, LOG_INFO
-from Bcfg2.Server.Plugin import StructurePlugin, PluginExecutionError, PluginInitError, DirectoryBacked, GeneratorPlugin
+import Bcfg2.Server.Plugin
+from Bcfg2.Server.Plugin import PluginExecutionError, PluginInitError
from time import strftime
from sets import Set
from django.template import Context, loader
@@ -13,49 +13,23 @@ from django.db import connection
import re
import cStringIO
-## class DataNexus(DirectoryBacked):
-## '''DataNexus is an object that watches multiple files and
-## handles changes in an intelligent fashion.'''
-## __name__ = 'DataNexus'
-
-## def __init__(self, path, filelist, fam):
-## self.files = filelist
-## DirectoryBacked.__init__(self, path, fam)
-
-## def HandleEvent(self, event):
-## '''Trap adds and updates, else call baseclass HandleEvent'''
-## action = event.code2str()
-## if action in ['exists', 'created']:
-## if (event.filename != self.name) and (event.filename not in self.files):
-## syslog(LOG_INFO, "%s:Got event for unexpected file %s" % (self.__name__, event.filename))
-## return
-## DirectoryBacked.HandleEvent(self, event)
-## if action != 'endExist' and event.filename != self.name:
-## self.rebuildState(event)
-
-## def rebuildState(self, event):
-## '''This function is called when underlying data has changed'''
-## pass
-
-class Hostbase(StructurePlugin,GeneratorPlugin):
+class Hostbase(Bcfg2.Server.Plugin.Plugin,
+ Bcfg2.Server.Plugin.Structure,
+ Bcfg2.Server.Plugin.Generator):
'''The Hostbase plugin handles host/network info'''
- __name__ = 'Hostbase'
+ name = 'Hostbase'
__version__ = '$Id$'
__author__ = 'bcfg-dev@mcs.anl.gov'
filepath = '/my/adm/hostbase/files/bind'
def __init__(self, core, datastore):
-
+
self.ready = False
- StructurePlugin.__init__(self, core, datastore)
+ Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
+ Bcfg2.Server.Plugin.Structure.__init__(self)
+ Bcfg2.Server.Plugin.Generator.__init__(self)
files = ['zone.tmpl', 'reversesoa.tmpl', 'named.tmpl', 'reverseappend.tmpl',
'dhcpd.tmpl', 'hosts.tmpl', 'hostsappend.tmpl']
-## try:
-## self.repository = DataNexus(self.data + '/templates/',
-## files, self.core.fam)
-## except:
-## self.LogError("Failed to load data directory")
-## raise PluginInitError
self.filedata = {}
self.dnsservers = []
self.dhcpservers = []
diff --git a/src/lib/Server/Plugins/Metadata.py b/src/lib/Server/Plugins/Metadata.py
index bb5a34cca..355624ccc 100644
--- a/src/lib/Server/Plugins/Metadata.py
+++ b/src/lib/Server/Plugins/Metadata.py
@@ -49,16 +49,16 @@ class ClientMetadata(object):
if value == profile]
-class Metadata(Bcfg2.Server.Plugin.MetadataPlugin,
- ):
+class Metadata(Bcfg2.Server.Plugin.Plugin,
+ Bcfg2.Server.Plugin.Metadata):
'''This class contains data for bcfg2 server metadata'''
__version__ = '$Id$'
__author__ = 'bcfg-dev@mcs.anl.gov'
- __name__ = "Metadata"
+ name = "Metadata"
def __init__(self, core, datastore, watch_clients=True):
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
- #self.__name__ = 'Metadata'
+ Bcfg2.Server.Plugin.Metadata.__init__(self)
if watch_clients:
try:
core.fam.AddMonitor("%s/%s" % (self.data, "groups.xml"), self)
diff --git a/src/lib/Server/Plugins/NagiosGen.py b/src/lib/Server/Plugins/NagiosGen.py
index c3f03dc13..7dfaef125 100644
--- a/src/lib/Server/Plugins/NagiosGen.py
+++ b/src/lib/Server/Plugins/NagiosGen.py
@@ -14,15 +14,17 @@ alias %s
address %s
'''
-class NagiosGen(Bcfg2.Server.Plugin.GeneratorPlugin):
+class NagiosGen(Bcfg2.Server.Plugin.Plugin,
+ Bcfg2.Server.Plugin.Generator):
'''NagiosGen is a Bcfg2 plugin that dynamically generates
Nagios configuration file based on Bcfg2 data.'''
- __name__ = 'NagiosGen'
+ name = 'NagiosGen'
__version__ = '0.6'
__author__ = 'bcfg-dev@mcs.anl.gov'
def __init__(self, core, datastore):
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
+ Bcfg2.Server.Plugin.Generator.__init__(self)
self.Entries = {'ConfigFile':
{'/etc/nagiosgen.status' : self.createhostconfig,
'/etc/nagios/nagiosgen.cfg': self.createserverconfig}}
diff --git a/src/lib/Server/Plugins/Pkgmgr.py b/src/lib/Server/Plugins/Pkgmgr.py
index 61b153b2e..32a5bd400 100644
--- a/src/lib/Server/Plugins/Pkgmgr.py
+++ b/src/lib/Server/Plugins/Pkgmgr.py
@@ -124,7 +124,7 @@ class PkgSrc(Bcfg2.Server.Plugin.XMLSrc):
class Pkgmgr(Bcfg2.Server.Plugin.PrioDir):
'''This is a generator that handles package assignments'''
- __name__ = 'Pkgmgr'
+ name = 'Pkgmgr'
__version__ = '$Id$'
__author__ = 'bcfg-dev@mcs.anl.gov'
__child__ = PkgSrc
diff --git a/src/lib/Server/Plugins/Probes.py b/src/lib/Server/Plugins/Probes.py
index adc920257..c27f21def 100644
--- a/src/lib/Server/Plugins/Probes.py
+++ b/src/lib/Server/Plugins/Probes.py
@@ -46,19 +46,21 @@ class ProbeSet(Bcfg2.Server.Plugin.EntrySet):
ret.append(probe)
return ret
-class Probes(Bcfg2.Server.Plugin.MetadataConnectorPlugin,
- Bcfg2.Server.Plugin.ProbingPlugin):
- __name__ = 'Probes'
+class Probes(Bcfg2.Server.Plugin.Plugin,
+ Bcfg2.Server.Plugin.Probing,
+ Bcfg2.Server.Plugin.Connector):
+ name = 'Probes'
__version__ = '$Id: $'
__author__ = 'bcfg-dev@mcs.anl.gov'
def __init__(self, core, datastore):
- Bcfg2.Server.Plugin.MetadataConnectorPlugin.__init__(self, core,
- datastore)
- self.__name__ = 'Probes'
+ Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
+ Bcfg2.Server.Plugin.Connector.__init__(self)
+ Bcfg2.Server.Plugin.Probing.__init__(self)
+
try:
self.probes = ProbeSet(self.data, core.fam, core.encoding,
- self.__name__)
+ self.name)
except:
raise Bcfg2.Server.Plugin.PluginInitError
diff --git a/src/lib/Server/Plugins/Rules.py b/src/lib/Server/Plugins/Rules.py
index 8fc5bbd70..b23a52980 100644
--- a/src/lib/Server/Plugins/Rules.py
+++ b/src/lib/Server/Plugins/Rules.py
@@ -1,10 +1,10 @@
-'''This generator provides service mappings'''
+'''This generator provides rule-based entry mappings'''
__revision__ = '$Revision$'
import Bcfg2.Server.Plugin
class Rules(Bcfg2.Server.Plugin.PrioDir):
'''This is a generator that handles service assignments'''
- __name__ = 'Rules'
+ name = 'Rules'
__version__ = '$Id$'
__author__ = 'bcfg-dev@mcs.anl.gov'
diff --git a/src/lib/Server/Plugins/SGenshi.py b/src/lib/Server/Plugins/SGenshi.py
index 4fa95ff4e..7dd2f6865 100644
--- a/src/lib/Server/Plugins/SGenshi.py
+++ b/src/lib/Server/Plugins/SGenshi.py
@@ -44,14 +44,17 @@ class SGenshiEntrySet(Bcfg2.Server.Plugin.EntrySet):
logger.error("SGenshi: Failed to template file %s" % entry.name)
return ret
-class SGenshi(SGenshiEntrySet, Bcfg2.Server.Plugin.StructurePlugin):
+class SGenshi(Bcfg2.Server.Plugin.Plugin,
+ Bcfg2.Server.Plugin.Structure,
+ SGenshiEntrySet):
'''The SGenshi plugin provides templated structures'''
- __name__ = 'SGenshi'
+ name = 'SGenshi'
__version__ = '$Id$'
__author__ = 'bcfg-dev@mcs.anl.gov'
def __init__(self, core, datastore):
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
+ Bcfg2.Server.Plugin.Structure.__init__(self)
try:
SGenshiEntrySet.__init__(self, self.data, self.core.fam, core.encoding)
except:
diff --git a/src/lib/Server/Plugins/SSHbase.py b/src/lib/Server/Plugins/SSHbase.py
index 4910cb6f4..e3e0f739b 100644
--- a/src/lib/Server/Plugins/SSHbase.py
+++ b/src/lib/Server/Plugins/SSHbase.py
@@ -4,7 +4,9 @@ __revision__ = '$Revision$'
import binascii, os, socket, tempfile
import Bcfg2.Server.Plugin
-class SSHbase(Bcfg2.Server.Plugin.GeneratorPlugin, Bcfg2.Server.Plugin.DirectoryBacked):
+class SSHbase(Bcfg2.Server.Plugin.Plugin,
+ Bcfg2.Server.Plugin.Generator,
+ Bcfg2.Server.Plugin.DirectoryBacked):
'''The sshbase generator manages ssh host keys (both v1 and v2)
for hosts. It also manages the ssh_known_hosts file. It can
integrate host keys from other management domains and similarly
@@ -22,7 +24,7 @@ class SSHbase(Bcfg2.Server.Plugin.GeneratorPlugin, Bcfg2.Server.Plugin.Director
ssh_known_hosts -> the current known hosts file. this
is regenerated each time a new key is generated.
'''
- __name__ = 'SSHbase'
+ name = 'SSHbase'
__version__ = '$Id$'
__author__ = 'bcfg-dev@mcs.anl.gov'
@@ -31,14 +33,18 @@ class SSHbase(Bcfg2.Server.Plugin.GeneratorPlugin, Bcfg2.Server.Plugin.Director
hostkeys = ["ssh_host_dsa_key.H_%s",
"ssh_host_rsa_key.H_%s", "ssh_host_key.H_%s"]
keypatterns = ['ssh_host_dsa_key', 'ssh_host_rsa_key', 'ssh_host_key',
- 'ssh_host_dsa_key.pub', 'ssh_host_rsa_key.pub', 'ssh_host_key.pub']
+ 'ssh_host_dsa_key.pub', 'ssh_host_rsa_key.pub',
+ 'ssh_host_key.pub']
def __init__(self, core, datastore):
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
+ Bcfg2.Server.Plugin.Generator.__init__(self)
try:
- Bcfg2.Server.Plugin.DirectoryBacked.__init__(self, self.data, self.core.fam)
+ Bcfg2.Server.Plugin.DirectoryBacked.__init__(self, self.data,
+ self.core.fam)
except OSError, ioerr:
- self.logger.error("Failed to load SSHbase repository from %s" % (self.data))
+ self.logger.error("Failed to load SSHbase repository from %s" \
+ % (self.data))
self.logger.error(ioerr)
raise Bcfg2.Server.Plugin.PluginInitError
self.Entries = {'ConfigFile':
@@ -90,7 +96,7 @@ class SSHbase(Bcfg2.Server.Plugin.GeneratorPlugin, Bcfg2.Server.Plugin.Director
self.skn = False
if not self.skn:
if (len(self.entries.keys())) > (0.95 * len(os.listdir(self.data))):
- a = self.skn
+ _ = self.skn
def HandlesEntry(self, entry):
'''Handle key entries dynamically'''
@@ -120,7 +126,8 @@ class SSHbase(Bcfg2.Server.Plugin.GeneratorPlugin, Bcfg2.Server.Plugin.Director
self.ipcache[client] = (ipaddr, client)
return (ipaddr, client)
except socket.gaierror:
- ipaddr = os.popen("getent hosts %s" % client).read().strip().split()
+ cmd = "getent hosts %s" % client
+ ipaddr = os.popen(cmd).read().strip().split()
if ipaddr:
self.ipcache[client] = (ipaddr, client)
return (ipaddr, client)
@@ -175,7 +182,9 @@ class SSHbase(Bcfg2.Server.Plugin.GeneratorPlugin, Bcfg2.Server.Plugin.Director
if hostkey not in self.entries.keys():
fileloc = "%s/%s" % (self.data, hostkey)
- publoc = self.data + '/' + ".".join([hostkey.split('.')[0]]+['pub', "H_%s" % client])
+ publoc = self.data + '/' + ".".join([hostkey.split('.')[0],
+ 'pub',
+ "H_%s" % client])
tempdir = tempfile.mkdtemp()
temploc = "%s/%s" % (tempdir, hostkey)
os.system('ssh-keygen -q -f %s -N "" -t %s -C root@%s < /dev/null' %
diff --git a/src/lib/Server/Plugins/Statistics.py b/src/lib/Server/Plugins/Statistics.py
index 7c5394a51..ca7a3c5b0 100644
--- a/src/lib/Server/Plugins/Statistics.py
+++ b/src/lib/Server/Plugins/Statistics.py
@@ -24,7 +24,6 @@ class StatisticsStore(object):
'''Write statistics changes back to persistent store'''
if (self.dirty and (self.lastwrite + self.__min_write_delay__ <= time()) ) \
or force:
- #syslog(LOG_INFO, "Statistics: Updated statistics.xml")
try:
fout = open(self.filename + '.new', 'w')
except IOError, ioerr:
@@ -44,7 +43,6 @@ class StatisticsStore(object):
fin.close()
self.element = XML(data)
self.dirty = 0
- #syslog(LOG_INFO, "Statistics: Read in statistics.xml")
except (IOError, XMLSyntaxError):
self.logger.error("Creating new statistics file %s"%(self.filename))
self.element = Element('ConfigStatistics')
@@ -68,7 +66,8 @@ class StatisticsStore(object):
# Find correct node entry in stats data
# The following list comprehension should be guarenteed to return at
# most one result
- nodes = [elem for elem in self.element.findall('Node') if elem.get('name') == client]
+ nodes = [elem for elem in self.element.findall('Node') \
+ if elem.get('name') == client]
nummatch = len(nodes)
if nummatch == 0:
# Create an entry for this node
@@ -76,11 +75,14 @@ class StatisticsStore(object):
elif nummatch == 1 and not node_dirty:
# Delete old instance
node = nodes[0]
- [node.remove(elem) for elem in node.findall('Statistics') if self.isOlderThan24h(elem.get('time'))]
+ [node.remove(elem) for elem in node.findall('Statistics') \
+ if self.isOlderThan24h(elem.get('time'))]
elif nummatch == 1 and node_dirty:
# Delete old dirty statistics entry
node = nodes[0]
- [node.remove(elem) for elem in node.findall('Statistics') if (elem.get('state') == 'dirty' and self.isOlderThan24h(elem.get('time')))]
+ [node.remove(elem) for elem in node.findall('Statistics') \
+ if (elem.get('state') == 'dirty' \
+ and self.isOlderThan24h(elem.get('time')))]
else:
# Shouldn't be reached
self.logger.error("Duplicate node entry for %s"%(client))
@@ -93,7 +95,7 @@ class StatisticsStore(object):
# Set dirty
self.dirty = 1
- self.WriteBack()
+ self.WriteBack(force=1)
def isOlderThan24h(self, testTime):
@@ -104,27 +106,35 @@ class StatisticsStore(object):
return (now-utime) > secondsPerDay
-class Statistics(Bcfg2.Server.Plugin.StatisticsPlugin):
- __name__ = 'Statistics'
+class Statistics(Bcfg2.Server.Plugin.Plugin,
+ Bcfg2.Server.Plugin.Statistics,
+ Bcfg2.Server.Plugin.PullSource):
+ name = 'Statistics'
__version__ = '$Id$'
- def __init__(self, _, datastore):
+ def __init__(self, core, datastore):
+ Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
+ Bcfg2.Server.Plugin.Statistics.__init__(self)
+ Bcfg2.Server.Plugin.PullSource.__init__(self)
fpath = "%s/etc/statistics.xml" % datastore
- self.data = StatisticsStore(fpath)
+ self.data_file = StatisticsStore(fpath)
def StoreStatistics(self, client, xdata):
- self.data.updateStats(xdata, client.hostname)
+ self.data_file.updateStats(xdata, client.hostname)
def WriteBack(self):
- self.data.WriteBack()
+ self.data_file.WriteBack()
def FindCurrent(self, client):
- rt = self.data.element.xpath('//Node[@name="%s"]' % client)[0]
- maxtime = max([strptime(stat.get('time')) for stat in rt.findall('Statistics')])
- return [stat for stat in rt.findall('Statistics') if strptime(stat.get('time')) == maxtime][0]
+ rt = self.data_file.element.xpath('//Node[@name="%s"]' % client)[0]
+ maxtime = max([strptime(stat.get('time')) for stat \
+ in rt.findall('Statistics')])
+ return [stat for stat in rt.findall('Statistics') \
+ if strptime(stat.get('time')) == maxtime][0]
def GetExtra(self, client):
- return [(entry.tag, entry.get('name')) for entry in self.FindCurrent(client).xpath('.//Extra/*')]
+ return [(entry.tag, entry.get('name')) for entry \
+ in self.FindCurrent(client).xpath('.//Extra/*')]
def GetCurrentEntry(self, client, e_type, e_name):
curr = self.FindCurrent(client)
diff --git a/src/lib/Server/Plugins/Svcmgr.py b/src/lib/Server/Plugins/Svcmgr.py
index 23f06b627..770871c18 100644
--- a/src/lib/Server/Plugins/Svcmgr.py
+++ b/src/lib/Server/Plugins/Svcmgr.py
@@ -5,6 +5,6 @@ import Bcfg2.Server.Plugin
class Svcmgr(Bcfg2.Server.Plugin.PrioDir):
'''This is a generator that handles service assignments'''
- __name__ = 'Svcmgr'
+ name = 'Svcmgr'
__version__ = '$Id$'
__author__ = 'bcfg-dev@mcs.anl.gov'
diff --git a/src/lib/Server/Plugins/TCheetah.py b/src/lib/Server/Plugins/TCheetah.py
index b9381268b..c2e632351 100644
--- a/src/lib/Server/Plugins/TCheetah.py
+++ b/src/lib/Server/Plugins/TCheetah.py
@@ -57,7 +57,7 @@ class TemplateFile:
class TCheetah(Bcfg2.Server.Plugin.GroupSpool):
'''The TCheetah generator implements a templating mechanism for configuration files'''
- __name__ = 'TCheetah'
+ name = 'TCheetah'
__version__ = '$Id$'
__author__ = 'bcfg-dev@mcs.anl.gov'
filename_pattern = 'template'
diff --git a/src/lib/Server/Plugins/TGenshi.py b/src/lib/Server/Plugins/TGenshi.py
index f453b0450..1dfe2f3c5 100644
--- a/src/lib/Server/Plugins/TGenshi.py
+++ b/src/lib/Server/Plugins/TGenshi.py
@@ -96,7 +96,7 @@ class TGenshi(Bcfg2.Server.Plugin.GroupSpool):
The TGenshi generator implements a templating
mechanism for configuration files
'''
- __name__ = 'TGenshi'
+ name = 'TGenshi'
__version__ = '$Id$'
__author__ = 'jeff@ocjtech.us'
use_props = True
diff --git a/src/sbin/bcfg2-info b/src/sbin/bcfg2-info
index bf88b1bfe..5c689489b 100755
--- a/src/sbin/bcfg2-info
+++ b/src/sbin/bcfg2-info
@@ -260,7 +260,7 @@ Usage: [quit|exit]"""
for etype, names in interested:
for name in [name for name in names if name in \
generator.Entries.get(etype, {})]:
- data.append((generator.__name__, etype, name))
+ data.append((generator.name, etype, name))
printTabular(data)
def do_event_debug(self, args):
diff --git a/src/sbin/bcfg2-server b/src/sbin/bcfg2-server
index b190a6e16..fed02bf6b 100755
--- a/src/sbin/bcfg2-server
+++ b/src/sbin/bcfg2-server
@@ -109,7 +109,7 @@ class Bcfg2Serv(Bcfg2.Component.Component):
meta = self.Core.build_metadata(name)
for plugin in [p for p in self.Core.plugins.values() \
- if isinstance(p, Bcfg2.Server.Plugin.ProbingPlugin)]:
+ if isinstance(p, Bcfg2.Server.Plugin.Probing)]:
for probe in plugin.GetProbes(meta):
resp.append(probe)
return tostring(resp, encoding='UTF-8', xml_declaration=True)