From e3759d2a2e5fdb0e0a7f7dfa4f8244fdbb3ffe92 Mon Sep 17 00:00:00 2001 From: Narayan Desai Date: Wed, 25 Jan 2006 16:48:06 +0000 Subject: Introduce the new logging infrastructure and convert the server (and bcfg2-info) over to using it git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@1717 ce84e21b-d406-0410-9b95-82705330c041 --- src/lib/Server/Plugins/Account.py | 12 ++++---- src/lib/Server/Plugins/Base.py | 2 +- src/lib/Server/Plugins/Bundler.py | 10 +++--- src/lib/Server/Plugins/Cfg.py | 62 +++++++++++++++++--------------------- src/lib/Server/Plugins/Chiba.py | 21 ++++++------- src/lib/Server/Plugins/Hostbase.py | 15 +++++---- src/lib/Server/Plugins/Pkgmgr.py | 8 ++--- src/lib/Server/Plugins/SSHbase.py | 35 ++++++++++----------- src/lib/Server/Plugins/TCheetah.py | 10 +++--- 9 files changed, 84 insertions(+), 91 deletions(-) (limited to 'src/lib/Server/Plugins') diff --git a/src/lib/Server/Plugins/Account.py b/src/lib/Server/Plugins/Account.py index 05174486d..076afa032 100644 --- a/src/lib/Server/Plugins/Account.py +++ b/src/lib/Server/Plugins/Account.py @@ -1,9 +1,9 @@ '''This handles authentication setup''' __revision__ = '$Revision$' -from Bcfg2.Server.Plugin import Plugin, PluginInitError, DirectoryBacked +import Bcfg2.Server.Plugin -class Account(Plugin): +class Account(Bcfg2.Server.Plugin.Plugin): '''This module generates account config files, based on an internal data repo: static.(passwd|group|limits.conf) -> static entries @@ -17,16 +17,16 @@ class Account(Plugin): __author__ = 'bcfg-dev@mcs.anl.gov' def __init__(self, core, datastore): - Plugin.__init__(self, core, datastore) + Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) self.Entries = {'ConfigFile':{'/etc/passwd':self.from_yp_cb, '/etc/group':self.from_yp_cb, '/etc/security/limits.conf':self.gen_limits_cb, '/root/.ssh/authorized_keys':self.gen_root_keys_cb}} try: - self.repository = DirectoryBacked(self.data, self.core.fam) + self.repository = Bcfg2.Server.Plugin.DirectoryBacked(self.data, self.core.fam) except: - self.LogError("Failed to load repos: %s, %s" % (self.data, "%s/ssh" % (self.data))) - raise PluginInitError + self.logger.error("Failed to load repos: %s, %s" % (self.data, "%s/ssh" % (self.data))) + raise Bcfg2.Server.Plugin.PluginInitError def from_yp_cb(self, entry, metadata): '''Build password file from cached yp data''' diff --git a/src/lib/Server/Plugins/Base.py b/src/lib/Server/Plugins/Base.py index 3be30bc6a..5c32eb15a 100644 --- a/src/lib/Server/Plugins/Base.py +++ b/src/lib/Server/Plugins/Base.py @@ -19,7 +19,7 @@ class Base(Bcfg2.Server.Plugin.Plugin, Bcfg2.Server.Plugin.DirectoryBacked): try: Bcfg2.Server.Plugin.DirectoryBacked.__init__(self, self.data, self.core.fam) except OSError: - self.LogError("Failed to load Base repository") + self.logger.error("Failed to load Base repository") raise Bcfg2.Server.Plugin.PluginInitError def BuildStructures(self, metadata): diff --git a/src/lib/Server/Plugins/Bundler.py b/src/lib/Server/Plugins/Bundler.py index cbbb6c671..59b0dead4 100644 --- a/src/lib/Server/Plugins/Bundler.py +++ b/src/lib/Server/Plugins/Bundler.py @@ -1,9 +1,7 @@ '''This provides bundle clauses with translation functionality''' __revision__ = '$Revision$' -import Bcfg2.Server.Plugin -import copy -import lxml.etree +import copy, lxml.etree, Bcfg2.Server.Plugin class Bundler(Bcfg2.Server.Plugin.Plugin, Bcfg2.Server.Plugin.DirectoryBacked): '''The bundler creates dependent clauses based on the bundle/translation scheme from bcfg1''' @@ -17,7 +15,7 @@ class Bundler(Bcfg2.Server.Plugin.Plugin, Bcfg2.Server.Plugin.DirectoryBacked): try: Bcfg2.Server.Plugin.DirectoryBacked.__init__(self, self.data, self.core.fam) except OSError: - self.LogError("Failed to load Bundle repository") + self.logger.error("Failed to load Bundle repository") raise Bcfg2.Server.Plugin.PluginInitError def BuildStructures(self, metadata): @@ -25,8 +23,8 @@ class Bundler(Bcfg2.Server.Plugin.Plugin, Bcfg2.Server.Plugin.DirectoryBacked): bundleset = [] for bundlename in metadata.bundles: if not self.entries.has_key("%s.xml"%(bundlename)): - self.LogError("Client %s requested nonexistent bundle %s" % \ - (metadata.hostname, bundlename)) + self.logger.error("Client %s requested nonexistent bundle %s" % \ + (metadata.hostname, bundlename)) continue bundle = lxml.etree.Element('Bundle', name=bundlename) [bundle.append(copy.deepcopy(item)) diff --git a/src/lib/Server/Plugins/Cfg.py b/src/lib/Server/Plugins/Cfg.py index b325144e5..157243e50 100644 --- a/src/lib/Server/Plugins/Cfg.py +++ b/src/lib/Server/Plugins/Cfg.py @@ -1,29 +1,23 @@ '''This module implements a config file repository''' __revision__ = '$Revision$' -from os import stat -from re import compile as regcompile -from stat import S_ISDIR, ST_MODE -from syslog import syslog, LOG_INFO, LOG_ERR +import binascii, exceptions, logging, os, re, stat, Bcfg2.Server.Plugin -from Bcfg2.Server.Plugin import Plugin, PluginExecutionError, FileBacked +logger = logging.getLogger('Bcfg2.Plugins.Cfg') -import binascii -import exceptions - -specific = regcompile('(.*/)(?P[\S\-.]+)\.((H_(?P\S+))|' + +specific = re.compile('(.*/)(?P[\S\-.]+)\.((H_(?P\S+))|' + '(G(?P\d+)_(?P\S+)))$') class SpecificityError(Exception): '''Thrown in case of filename parse failure''' pass -class FileEntry(FileBacked): +class FileEntry(Bcfg2.Server.Plugin.FileBacked): '''The File Entry class pertains to the config files contained in a particular directory. This includes :info, all base files and deltas''' def __init__(self, myid, name): - FileBacked.__init__(self, name) + Bcfg2.Server.Plugin.FileBacked.__init__(self, name) self.name = name self.identity = myid self.all = False @@ -39,7 +33,7 @@ class FileEntry(FileBacked): else: data = specific.match(name) if not data: - syslog(LOG_ERR, "Cfg: Failed to match %s" % name) + logger.error("Failed to match %s" % name) raise SpecificityError if data.group('hostname') != None: self.hostname = data.group('hostname') @@ -62,7 +56,7 @@ class FileEntry(FileBacked): return 0 else: pass - syslog(LOG_ERR, "Cfg: Critical: Ran off of the end of the world sorting %s" % (self.name)) + logger.critical("Ran off of the end of the world sorting %s" % (self.name)) def applies(self, metadata): '''Predicate if fragment matches client metadata''' @@ -75,7 +69,7 @@ class FileEntry(FileBacked): class ConfigFileEntry(object): '''ConfigFileEntry is a repository entry for a single file, containing all data for all clients.''' - info = regcompile('^owner:(\s)*(?P\w+)|group:(\s)*(?P\w+)|' + + info = re.compile('^owner:(\s)*(?P\w+)|group:(\s)*(?P\w+)|' + 'perms:(\s)*(?P\w+)|encoding:(\s)*(?P\w+)|' + '(?Pparanoid(\s)*)$') @@ -128,28 +122,28 @@ class ConfigFileEntry(object): return self.read_info() if event.filename != self.path.split('/')[-1]: if not specific.match('/' + event.filename): - syslog(LOG_INFO, 'Cfg: Suppressing event for bogus file %s' % event.filename) + logger.info('Suppressing event for bogus file %s' % event.filename) return entries = [entry for entry in self.fragments if entry.name.split('/')[-1] == event.filename] if len(entries) == 0: - syslog(LOG_ERR, "Cfg: Failed to match entry for spec %s" % (event.filename)) + logger.error("Failed to match entry for spec %s" % (event.filename)) elif len(entries) > 1: - syslog(LOG_ERR, "Cfg: Matched multiple entries for spec %s" % (event.filename)) + logger.error("Matched multiple entries for spec %s" % (event.filename)) if action == 'deleted': - syslog(LOG_INFO, "Cfg: Removing entry %s" % event.filename) + logger.info("Removing entry %s" % event.filename) for entry in entries: - syslog(LOG_INFO, "Cfg: Removing entry %s" % (entry.name)) + logger.info("Removing entry %s" % (entry.name)) self.fragments.remove(entry) self.fragments.sort() - syslog(LOG_INFO, "Cfg: Entry deletion completed") + logger.info("Entry deletion completed") elif action in ['changed', 'exists', 'created']: [entry.HandleEvent(event) for entry in entries] else: - syslog(LOG_ERR, "Cfg: Unhandled Action %s for file %s" % (action, event.filename)) + logger.error("Unhandled Action %s for file %s" % (action, event.filename)) def GetConfigFile(self, entry, metadata): '''Fetch config file from repository''' @@ -159,8 +153,8 @@ class ConfigFileEntry(object): try: basefile = [bfile for bfile in self.fragments if bfile.applies(metadata) and not bfile.op][-1] except IndexError: - syslog(LOG_ERR, "Cfg: Failed to locate basefile for %s" % name) - raise PluginExecutionError, ('basefile', name) + logger.error("Failed to locate basefile for %s" % name) + raise Bcfg2.Server.Plugin.PluginExecutionError, ('basefile', name) filedata += basefile.data for delta in [delta for delta in self.fragments if delta.applies(metadata) and delta.op]: @@ -186,17 +180,17 @@ class ConfigFileEntry(object): try: entry.text = filedata except exceptions.AttributeError: - syslog(LOG_ERR, "Failed to marshall file %s. Mark it as base64" % (entry.get('name'))) + logger.error("Failed to marshall file %s. Mark it as base64" % (entry.get('name'))) -class Cfg(Plugin): +class Cfg(Bcfg2.Server.Plugin.Plugin): '''This generator in the configuration file repository for bcfg2''' __name__ = 'Cfg' __version__ = '$Id$' __author__ = 'bcfg-dev@mcs.anl.gov' - tempfile = regcompile("^.*~$|^.*\.swp") + tempfile = re.compile("^.*~$|^.*\.swp") def __init__(self, core, datastore): - Plugin.__init__(self, core, datastore) + Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) self.entries = {} self.Entries = {'ConfigFile':{}} self.famID = {} @@ -209,9 +203,9 @@ class Cfg(Plugin): '''Add new directory to FAM structures''' if name not in self.directories: try: - stat(name) + os.stat(name) except OSError: - self.LogError("Failed to open directory %s" % (name)) + logger.error("Failed to open directory %s" % (name)) return reqid = self.core.fam.AddMonitor(name, self) self.famID[reqid] = name @@ -220,11 +214,11 @@ class Cfg(Plugin): def AddEntry(self, name, event): '''Add new entry to FAM structures''' try: - sdata = stat(name)[ST_MODE] + sdata = os.stat(name)[stat.ST_MODE] except OSError: return - if S_ISDIR(sdata): + if stat.S_ISDIR(sdata): self.AddDirectoryMonitor(name) else: # file entries shouldn't contain path-to-repo @@ -240,7 +234,7 @@ class Cfg(Plugin): '''Handle FAM updates''' action = event.code2str() if self.tempfile.match(event.filename): - syslog(LOG_INFO, "Cfg: Suppressed event for file %s" % event.filename) + logger.info("Suppressed event for file %s" % event.filename) return if event.filename[0] != '/': filename = "%s/%s" % (self.famID[event.requestID], event.filename) @@ -258,11 +252,11 @@ class Cfg(Plugin): if filename != self.data: self.AddEntry(filename, event) else: - self.LogError("Ignoring event for %s"%(configfile)) + logger.error("Ignoring event for %s"%(configfile)) elif action == 'deleted': if self.entries.has_key(configfile): self.entries[configfile].HandleEvent(event) elif action in ['exists', 'endExist']: pass else: - self.LogError("Got unknown event %s %s:%s" % (action, event.requestID, event.filename)) + logger.error("Got unknown event %s %s:%s" % (action, event.requestID, event.filename)) diff --git a/src/lib/Server/Plugins/Chiba.py b/src/lib/Server/Plugins/Chiba.py index e74036d1b..92ad05ab5 100644 --- a/src/lib/Server/Plugins/Chiba.py +++ b/src/lib/Server/Plugins/Chiba.py @@ -1,14 +1,13 @@ '''This module configures files in a Chiba City specific way''' -__revision__ = '$Revision:$' +__revision__ = '$Revision$' -from socket import gethostbyname, gaierror -from Bcfg2.Server.Plugin import Plugin, DirectoryBacked, SingleXMLFileBacked, PluginExecutionError +import socket, Bcfg2.Server.Plugin -class ChibaConf(SingleXMLFileBacked): +class ChibaConf(Bcfg2.Server.Plugin.SingleXMLFileBacked): '''This class encapsulates all information needed for all Chiba config ops''' pass -class Chiba(Plugin): +class Chiba(Bcfg2.Server.Plugin.Plugin): '''the Chiba generator builds the following files: -> /etc/fstab -> /etc/network/interfaces @@ -20,8 +19,8 @@ class Chiba(Plugin): __author__ = 'bcfg-dev@mcs.anl.gov' def __init__(self, core, datastore): - Plugin.__init__(self, core, datastore) - self.repo = DirectoryBacked(self.data, self.core.fam) + 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): @@ -32,9 +31,9 @@ class Chiba(Plugin): try: myriname = "%s-myr.%s" % (metadata.hostname.split('.')[0], ".".join(metadata.hostname.split('.')[1:])) - myriaddr = gethostbyname(myriname) - except gaierror: - self.LogError("Failed to resolve %s"% myriname) - raise PluginExecutionError, (myriname, 'lookup') + myriaddr = socket.gethostbyname(myriname) + except socket.gaierror: + self.logger.error("Failed to resolve %s"% myriname) + raise Bcfg2.Server.Plugin.PluginExecutionError, (myriname, 'lookup') entry.text = self.repo.entries['interfaces-template'].data % myriaddr diff --git a/src/lib/Server/Plugins/Hostbase.py b/src/lib/Server/Plugins/Hostbase.py index e729030fb..96f215451 100644 --- a/src/lib/Server/Plugins/Hostbase.py +++ b/src/lib/Server/Plugins/Hostbase.py @@ -1,7 +1,6 @@ '''This file provides the Hostbase plugin. It manages dns/dhcp/nis host information''' __revision__ = '$Revision$' -from syslog import syslog, LOG_INFO from lxml.etree import XML, SubElement from Cheetah.Template import Template from Bcfg2.Server.Plugin import Plugin, PluginExecutionError, PluginInitError, DirectoryBacked @@ -9,6 +8,10 @@ from time import strftime from sets import Set import re +import logging + +logger = logging.getLogger('Bcfg2.Plugins.Hostbase') + class DataNexus(DirectoryBacked): '''DataNexus is an object that watches multiple files and handles changes in an intelligent fashion.''' @@ -23,7 +26,7 @@ class DataNexus(DirectoryBacked): 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)) + logger.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: @@ -48,7 +51,7 @@ class Hostbase(Plugin, DataNexus): DataNexus.__init__(self, datastore + '/Hostbase/data', files, self.core.fam) except: - self.LogError("Failed to load data directory") + logger.error("Failed to load data directory") raise PluginInitError self.xdata = {} self.filedata = {} @@ -96,12 +99,12 @@ class Hostbase(Plugin, DataNexus): todaydate = (strftime('%Y%m%d')) try: if todaydate == zone.get('serial')[:8]: - serial = atoi(zone.get('serial')) + 1 + serial = int(zone.get('serial')) + 1 else: - serial = atoi(todaydate) * 100 + serial = int(todaydate) * 100 return str(serial) except (KeyError): - serial = atoi(todaydate) * 100 + serial = int(todaydate) * 100 return str(serial) if self.entries.has_key(event.filename) and not self.xdata.has_key(event.filename): diff --git a/src/lib/Server/Plugins/Pkgmgr.py b/src/lib/Server/Plugins/Pkgmgr.py index e77dd99e5..2367c7c22 100644 --- a/src/lib/Server/Plugins/Pkgmgr.py +++ b/src/lib/Server/Plugins/Pkgmgr.py @@ -1,9 +1,9 @@ '''This module implements a package management scheme for all images''' __revision__ = '$Revision$' -import re -from syslog import syslog, LOG_ERR -import Bcfg2.Server.Plugin +import logging, re, Bcfg2.Server.Plugin + +logger = logging.getLogger('Bcfg2.Plugins.Pkgmgr') class PNode(Bcfg2.Server.Plugin.LNode): '''PNode has a list of packages available at a particular group intersection''' @@ -29,7 +29,7 @@ class PNode(Bcfg2.Server.Plugin.LNode): if self.splitters.has_key(pkg.get('type')): mdata = self.splitters[pkg.get('type')].match(pkg.get('file')) if not mdata: - syslog(LOG_ERR, "Pkgmgr: Failed to match pkg %s" % pkg.get('file')) + logger.error("Failed to match pkg %s" % pkg.get('file')) continue pkgname = mdata.group('name') self.contents[pkgname] = mdata.groupdict() diff --git a/src/lib/Server/Plugins/SSHbase.py b/src/lib/Server/Plugins/SSHbase.py index 6cab373b0..87e9225af 100644 --- a/src/lib/Server/Plugins/SSHbase.py +++ b/src/lib/Server/Plugins/SSHbase.py @@ -1,13 +1,9 @@ '''This module manages ssh key files for bcfg2''' __revision__ = '$Revision$' -from binascii import b2a_base64 -from os import system, popen -from socket import gethostbyname, gaierror +import binascii, os, socket, Bcfg2.Server.Plugin -from Bcfg2.Server.Plugin import Plugin, DirectoryBacked, PluginExecutionError - -class SSHbase(Plugin): +class SSHbase(Bcfg2.Server.Plugin.Plugin): '''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 @@ -35,8 +31,8 @@ class SSHbase(Plugin): "ssh_host_rsa_key.H_%s", "ssh_host_key.H_%s"] def __init__(self, core, datastore): - Plugin.__init__(self, core, datastore) - self.repository = DirectoryBacked(self.data, self.core.fam) + Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) + self.repository = Bcfg2.Server.Plugin.DirectoryBacked(self.data, self.core.fam) try: prefix = open("%s/prefix" % (self.data)).read().strip() except IOError: @@ -65,20 +61,20 @@ class SSHbase(Plugin): else: # need to add entry try: - ipaddr = gethostbyname(client) + ipaddr = socket.gethostbyname(client) self.ipcache[client] = (ipaddr, client) return (ipaddr, client) - except gaierror: - (client) + except socket.gaierror: + pass try: - ipaddr = popen("getent hosts %s" % client).read().strip().split() + ipaddr = os.popen("getent hosts %s" % client).read().strip().split() except: ipaddr = '' if ipaddr: self.ipcache[client] = (ipaddr, client) return (ipaddr, client) - self.LogError("Failed to find IP address for %s" % client) - raise gaierror + self.logger.error("Failed to find IP address for %s" % client) + raise socket.gaierror def cache_skn(self): '''build memory cache of the ssh known hosts file''' @@ -87,7 +83,7 @@ class SSHbase(Plugin): hostname = pubkey.split('H_')[1] try: (ipaddr, fqdn) = self.get_ipcache_entry(hostname) - except gaierror: + except socket.gaierror: continue shortname = hostname.split('.')[0] self.static_skn += "%s,%s,%s %s" % (shortname, fqdn, ipaddr, @@ -114,8 +110,8 @@ class SSHbase(Plugin): if hasattr(self, 'static_skn'): del self.static_skn if not self.repository.entries.has_key(filename): - self.LogError("%s still not registered" % filename) - raise PluginExecutionError + self.logger.error("%s still not registered" % filename) + raise Bcfg2.Server.Plugin.PluginExecutionError keydata = self.repository.entries[filename].data permdata = {'owner':'root', 'group':'root'} permdata['perms'] = '0600' @@ -124,7 +120,7 @@ class SSHbase(Plugin): [entry.attrib.__setitem__(x, permdata[x]) for x in permdata] if "ssh_host_key.H_" == filename[:15]: entry.attrib['encoding'] = 'base64' - entry.text = b2a_base64(keydata) + entry.text = binascii.b2a_base64(keydata) else: entry.text = keydata @@ -143,7 +139,8 @@ class SSHbase(Plugin): fileloc = "%s/%s" % (self.data, hostkey) publoc = self.data + '/' + ".".join([hostkey.split('.')[0]]+['pub', "H_%s" % client]) temploc = "/tmp/%s" % hostkey - system('ssh-keygen -q -f %s -N "" -t %s -C root@%s < /dev/null' % (temploc, keytype, client)) + os.system('ssh-keygen -q -f %s -N "" -t %s -C root@%s < /dev/null' % + (temploc, keytype, client)) open(fileloc, 'w').write(open(temploc).read()) open(publoc, 'w').write(open("%s.pub" % temploc).read()) self.repository.AddEntry(hostkey) diff --git a/src/lib/Server/Plugins/TCheetah.py b/src/lib/Server/Plugins/TCheetah.py index 1ebdb6c94..beff8e869 100644 --- a/src/lib/Server/Plugins/TCheetah.py +++ b/src/lib/Server/Plugins/TCheetah.py @@ -2,11 +2,14 @@ __revision__ = '$Revision$' from posixpath import isdir -from syslog import syslog, LOG_ERR from Bcfg2.Server.Plugin import Plugin, PluginExecutionError, FileBacked, SingleXMLFileBacked from lxml.etree import XML, XMLSyntaxError from Cheetah.Template import Template +import logging + +logger = logging.getLogger('Bcfg2.Plugins.TCheetah') + class TemplateFile(FileBacked): '''Template file creates Cheetah template structures for the loaded file''' def __init__(self, name, properties): @@ -25,7 +28,7 @@ class TemplateFile(FileBacked): try: entry.text = str(self.template) except: - syslog(LOG_ERR, "TCheetah: Failed to template %s" % entry.get('name')) + logger.error("Failed to template %s" % entry.get('name')) raise PluginExecutionError perms = {'owner':'root', 'group':'root', 'perms':'0644'} [entry.attrib.__setitem__(key, value) for (key, value) in perms.iteritems()] @@ -38,7 +41,7 @@ class CheetahProperties(SingleXMLFileBacked): self.properties = XML(self.data) del self.data except XMLSyntaxError: - syslog(LOG_ERR, "TCheetah: Failed to parse properties") + logger.error("Failed to parse properties") class TCheetah(Plugin): '''The TCheetah generator implements a templating mechanism for configuration files''' @@ -80,7 +83,6 @@ class TCheetah(Plugin): self.entries[identifier].HandleEvent(event) self.Entries['ConfigFile'][identifier] = self.BuildEntry #except: - # syslog(LOG_ERR, "TCheetah: bad format for file %s" % identifier) elif action == 'changed': if self.entries.has_key(identifier): self.entries[identifier].HandleEvent(event) -- cgit v1.2.3-1-g7c22