summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSol Jerome <sol.jerome@gmail.com>2011-03-07 10:11:55 -0600
committerSol Jerome <sol.jerome@gmail.com>2011-03-07 10:11:55 -0600
commit3c290811195e23c9a948ac15c304b34ea16fbe9b (patch)
tree02514f60ff0a1efd91b1f3a99e8383a237019a35
parent1d17b980a15a2fd138ad746d51e148befa26faa0 (diff)
downloadbcfg2-3c290811195e23c9a948ac15c304b34ea16fbe9b.tar.gz
bcfg2-3c290811195e23c9a948ac15c304b34ea16fbe9b.tar.bz2
bcfg2-3c290811195e23c9a948ac15c304b34ea16fbe9b.zip
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 <sol.jerome@gmail.com>
-rw-r--r--doc/help/troubleshooting.txt8
-rw-r--r--src/lib/Server/Plugins/Cfg.py32
2 files changed, 33 insertions, 7 deletions
diff --git a/doc/help/troubleshooting.txt b/doc/help/troubleshooting.txt
index 0892587aa..bfd770cfd 100644
--- a/doc/help/troubleshooting.txt
+++ b/doc/help/troubleshooting.txt
@@ -139,6 +139,12 @@ be taken to remedy them.
| | | associated with a | |
| | | non-profile group. | |
+------------------------------+----------+---------------------+--------------+
+| Failed to decode <filename> | Server | The encoding being | [10]_ |
+| Please verify you are using | | used is unable to | |
+| the proper encoding | | decode the | |
+| | | character present | |
+| | | in this file. | |
++------------------------------+----------+---------------------+--------------+
.. [1] This entry is not being bound. Ensure that a version of this
@@ -158,6 +164,8 @@ be taken to remedy them.
.. [8] Ensure that the file is properly formed XML.
.. [9] Fix hostname resolution for the client or ensure that the profile
group is properly setup.
+.. [10] Ensure the correct encoding is specified in the [components]
+ section of ``bcfg2.conf``.
FAQs
====
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<basename>%s)(|\\.H_(?P<hostname>\S+?)|.G(?P<prio>\d+)_(?P<group>\S+?))(?P<genshi>\\.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)