From f26780538a46beac2655230a93bd2134af7fc5bc Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Fri, 4 Mar 2011 15:56:09 -0500 Subject: fixed handling of group- and host-specific .genshi templates in Cfg (non-greedy matching) --- src/lib/Server/Plugins/Cfg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib/Server/Plugins/Cfg.py') diff --git a/src/lib/Server/Plugins/Cfg.py b/src/lib/Server/Plugins/Cfg.py index f851b7914..42cfb288d 100644 --- a/src/lib/Server/Plugins/Cfg.py +++ b/src/lib/Server/Plugins/Cfg.py @@ -66,7 +66,7 @@ def process_delta(data, delta): class CfgMatcher: def __init__(self, fname): name = re.escape(fname) - self.basefile_reg = re.compile('^(?P%s)(|\\.H_(?P\S+)|.G(?P\d+)_(?P\S+))(?P\\.genshi)?$' % name) + self.basefile_reg = re.compile('^(?P%s)(|\\.H_(?P\S+?)|.G(?P\d+)_(?P\S+?))(?P\\.genshi)?$' % name) self.delta_reg = re.compile('^(?P%s)(|\\.H_(?P\S+)|\\.G(?P\d+)_(?P\S+))\\.(?P(cat|diff))$' % name) self.cat_count = fname.count(".cat") self.diff_count = fname.count(".diff") -- cgit v1.2.3-1-g7c22 From 3c290811195e23c9a948ac15c304b34ea16fbe9b Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Mon, 7 Mar 2011 10:11:55 -0600 Subject: Cfg: Fix unicode traceback (Resolves #993) If the Cfg plugin handled a file containing a character which isn't contained in the encoding specified, it resulted in a traceback. This now fails gracefully and suggests use of an alternate encoding. Signed-off-by: Sol Jerome --- src/lib/Server/Plugins/Cfg.py | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'src/lib/Server/Plugins/Cfg.py') diff --git a/src/lib/Server/Plugins/Cfg.py b/src/lib/Server/Plugins/Cfg.py index 42cfb288d..585f4f6ac 100644 --- a/src/lib/Server/Plugins/Cfg.py +++ b/src/lib/Server/Plugins/Cfg.py @@ -22,6 +22,7 @@ except: logger = logging.getLogger('Bcfg2.Plugins.Cfg') + # snipped from TGenshi def removecomment(stream): """A genshi filter that removes comments from the stream.""" @@ -30,6 +31,7 @@ def removecomment(stream): continue yield kind, data, pos + def process_delta(data, delta): if not delta.specific.delta: return data @@ -63,7 +65,9 @@ def process_delta(data, delta): raise Bcfg2.Server.Plugin.PluginExecutionError, ('delta', delta) return output + class CfgMatcher: + def __init__(self, fname): name = re.escape(fname) self.basefile_reg = re.compile('^(?P%s)(|\\.H_(?P\S+?)|.G(?P\d+)_(?P\S+?))(?P\\.genshi)?$' % name) @@ -77,7 +81,9 @@ class CfgMatcher: return self.delta_reg.match(fname) return self.basefile_reg.match(fname) + class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): + def __init__(self, basename, path, entry_type, encoding): Bcfg2.Server.Plugin.EntrySet.__init__(self, basename, path, entry_type, encoding) @@ -87,15 +93,18 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): return cmp(one.specific, other.specific) def get_pertinent_entries(self, metadata): - '''return a list of all entries pertinent to a client => [base, delta1, delta2]''' + """return a list of all entries pertinent + to a client => [base, delta1, delta2] + """ matching = [ent for ent in self.entries.values() if \ ent.specific.matches(metadata)] matching.sort(self.sort_by_specific) - non_delta = [matching.index(m) for m in matching if not m.specific.delta] + non_delta = [matching.index(m) for m in matching + if not m.specific.delta] if not non_delta: raise Bcfg2.Server.Plugin.PluginExecutionError base = min(non_delta) - used = matching[:base+1] + used = matching[:base + 1] used.reverse() return used @@ -136,7 +145,12 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): if entry.get('encoding') == 'base64': entry.text = binascii.b2a_base64(data) else: - entry.text = unicode(data, self.encoding) + try: + entry.text = unicode(data, self.encoding) + except UnicodeDecodeError, e: + logger.error("Failed to decode %s: %s" % (entry.get('name'), e)) + logger.error("Please verify you are using the proper encoding.") + raise Bcfg2.Server.Plugin.PluginExecutionError if entry.text in ['', None]: entry.set('empty', 'true') @@ -168,7 +182,8 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): open(name, 'w').write(new_entry['text']) if log: logger.info("Wrote file %s" % name) - badattr = [attr for attr in ['owner', 'group', 'perms'] if attr in new_entry] + badattr = [attr for attr in ['owner', 'group', 'perms'] + if attr in new_entry] if badattr: metadata_updates = {} metadata_updates.update(self.metadata) @@ -178,12 +193,13 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): infotag = lxml.etree.SubElement(infoxml, 'Info') [infotag.attrib.__setitem__(attr, metadata_updates[attr]) \ for attr in metadata_updates] - ofile = open(self.path + "/info.xml","w") + ofile = open(self.path + "/info.xml", "w") ofile.write(lxml.etree.tostring(infoxml, pretty_print=True)) ofile.close() if log: logger.info("Wrote file %s" % (self.path + "/info.xml")) + class Cfg(Bcfg2.Server.Plugin.GroupSpool, Bcfg2.Server.Plugin.PullTarget): """This generator in the configuration file repository for Bcfg2.""" @@ -197,4 +213,6 @@ class Cfg(Bcfg2.Server.Plugin.GroupSpool, return self.entries[entry.get('name')].list_accept_choices(metadata) def AcceptPullData(self, specific, new_entry, log): - return self.entries[new_entry.get('name')].write_update(specific, new_entry, log) + return self.entries[new_entry.get('name')].write_update(specific, + new_entry, + log) -- cgit v1.2.3-1-g7c22 From 0984e097c2f7d973320fa14fcfab36d3122cfaf0 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Wed, 16 Mar 2011 07:57:25 -0400 Subject: In TGenshi templates, the "name" variable is set to the destination path of the file. If an altsrc attribute was used, then "name" is set to the altsrc value; otherwise, it is set to the "name" attribute of the original tag used to declare the file. In the new Genshi handler functionality of Cfg, this had not been ported over; "name" was always the original name of the file, even if altsrc was specified. Fixed that bug. --- src/lib/Server/Plugins/Cfg.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/lib/Server/Plugins/Cfg.py') diff --git a/src/lib/Server/Plugins/Cfg.py b/src/lib/Server/Plugins/Cfg.py index 585f4f6ac..184bb792c 100644 --- a/src/lib/Server/Plugins/Cfg.py +++ b/src/lib/Server/Plugins/Cfg.py @@ -122,10 +122,11 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): template_cls = NewTextTemplate loader = TemplateLoader() template = loader.load(basefile.name, cls=template_cls, - encoding=self.encoding) - stream = template.generate( \ - name=entry.get('name'), metadata=metadata, - path=basefile.name).filter(removecomment) + encoding=self.encoding) + fname = entry.get('realname', entry.get('name')) + stream = template.generate(name=fname, + metadata=metadata, + path=basefile.name).filter(removecomment) try: data = stream.render('text', strip_whitespace=False) except TypeError: -- cgit v1.2.3-1-g7c22 From 2d90970d7da08e3c89fe67f4ebf8d0c1cdafeb20 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Tue, 5 Apr 2011 14:32:29 -0500 Subject: Plugins: PY3K + PEP8 fixes Signed-off-by: Sol Jerome --- src/lib/Server/Plugins/Cfg.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/lib/Server/Plugins/Cfg.py') diff --git a/src/lib/Server/Plugins/Cfg.py b/src/lib/Server/Plugins/Cfg.py index 184bb792c..6c7a40a52 100644 --- a/src/lib/Server/Plugins/Cfg.py +++ b/src/lib/Server/Plugins/Cfg.py @@ -13,9 +13,7 @@ import Bcfg2.Server.Plugin try: import genshi.core import genshi.input - from genshi.template import TemplateLoader, \ - TextTemplate, MarkupTemplate, TemplateError - from genshi.template import NewTextTemplate + from genshi.template import TemplateLoader, NewTextTemplate have_genshi = True except: have_genshi = False @@ -62,7 +60,7 @@ def process_delta(data, delta): output = open(basefile.name, 'r').read() [os.unlink(fname) for fname in [basefile.name, dfile.name]] if ret >> 8 != 0: - raise Bcfg2.Server.Plugin.PluginExecutionError, ('delta', delta) + raise Bcfg2.Server.Plugin.PluginExecutionError('delta', delta) return output @@ -96,7 +94,7 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): """return a list of all entries pertinent to a client => [base, delta1, delta2] """ - matching = [ent for ent in self.entries.values() if \ + matching = [ent for ent in list(self.entries.values()) if \ ent.specific.matches(metadata)] matching.sort(self.sort_by_specific) non_delta = [matching.index(m) for m in matching -- cgit v1.2.3-1-g7c22 From bef2d0c73eb0b3fd071f616aa43a945ae2d103b7 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Tue, 26 Apr 2011 15:18:04 -0500 Subject: Plugins: Add full PY3K compatibility Signed-off-by: Sol Jerome --- src/lib/Server/Plugins/Cfg.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src/lib/Server/Plugins/Cfg.py') diff --git a/src/lib/Server/Plugins/Cfg.py b/src/lib/Server/Plugins/Cfg.py index 6c7a40a52..41cf6c9c1 100644 --- a/src/lib/Server/Plugins/Cfg.py +++ b/src/lib/Server/Plugins/Cfg.py @@ -6,6 +6,7 @@ import logging import lxml import os import re +import sys import tempfile import Bcfg2.Server.Plugin @@ -21,6 +22,13 @@ except: logger = logging.getLogger('Bcfg2.Plugins.Cfg') +def u_str(string, encoding): + if sys.hexversion >= 0x03000000: + return str(string, encoding) + else: + return unicode(string, encoding) + + # snipped from TGenshi def removecomment(stream): """A genshi filter that removes comments from the stream.""" @@ -131,7 +139,8 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): data = stream.render('text') if data == '': entry.set('empty', 'true') - except Exception, e: + except Exception: + e = sys.exc_info()[1] logger.error("Cfg: genshi exception: %s" % e) raise Bcfg2.Server.Plugin.PluginExecutionError else: @@ -145,8 +154,9 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): entry.text = binascii.b2a_base64(data) else: try: - entry.text = unicode(data, self.encoding) - except UnicodeDecodeError, e: + entry.text = u_str(data, self.encoding) + except UnicodeDecodeError: + e = sys.exc_info()[1] logger.error("Failed to decode %s: %s" % (entry.get('name'), e)) logger.error("Please verify you are using the proper encoding.") raise Bcfg2.Server.Plugin.PluginExecutionError -- cgit v1.2.3-1-g7c22