summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/Bcfg2/Server/Lint/GroupPatterns.py5
-rw-r--r--src/lib/Bcfg2/Server/Lint/__init__.py4
-rw-r--r--src/lib/Bcfg2/Server/Plugin/helpers.py10
-rw-r--r--src/lib/Bcfg2/Server/Plugin/interfaces.py10
-rw-r--r--src/lib/Bcfg2/Server/Plugins/AWSTags.py18
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Bundler.py4
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Cfg/CfgGenshiGenerator.py11
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Cfg/CfgPrivateKeyCreator.py33
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py16
-rw-r--r--src/lib/Bcfg2/Server/Plugins/FileProbes.py4
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Git.py27
-rw-r--r--src/lib/Bcfg2/Server/Plugins/GroupPatterns.py72
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Guppy.py41
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Hg.py11
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Metadata.py25
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Ohai.py4
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/Apt.py2
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/Pac.py2
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/Pkgng.py2
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/Source.py18
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/Yum.py8
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/YumHelper.py4
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/__init__.py4
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Pkgmgr.py8
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Probes.py9
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Properties.py8
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Reporting.py9
-rw-r--r--src/lib/Bcfg2/Server/Plugins/SSHbase.py17
-rw-r--r--src/lib/Bcfg2/Server/Plugins/TemplateHelper.py4
29 files changed, 172 insertions, 218 deletions
diff --git a/src/lib/Bcfg2/Server/Lint/GroupPatterns.py b/src/lib/Bcfg2/Server/Lint/GroupPatterns.py
index deb91020d..e9813b7e9 100644
--- a/src/lib/Bcfg2/Server/Lint/GroupPatterns.py
+++ b/src/lib/Bcfg2/Server/Lint/GroupPatterns.py
@@ -4,7 +4,8 @@
import sys
from Bcfg2.Server.Lint import ServerPlugin
-from Bcfg2.Server.Plugins.GroupPatterns import PatternMap
+from Bcfg2.Server.Plugins.GroupPatterns import PatternMap, \
+ PatternInitializationError
class GroupPatterns(ServerPlugin):
@@ -36,7 +37,7 @@ class GroupPatterns(ServerPlugin):
PatternMap(pat, None, groups)
else:
PatternMap(None, pat, groups)
- except: # pylint: disable=W0702
+ except PatternInitializationError:
err = sys.exc_info()[1]
self.LintError("pattern-fails-to-initialize",
"Failed to initialize %s %s for %s: %s" %
diff --git a/src/lib/Bcfg2/Server/Lint/__init__.py b/src/lib/Bcfg2/Server/Lint/__init__.py
index 903ee6326..61f704206 100644
--- a/src/lib/Bcfg2/Server/Lint/__init__.py
+++ b/src/lib/Bcfg2/Server/Lint/__init__.py
@@ -26,7 +26,7 @@ def _ioctl_GWINSZ(fd): # pylint: disable=C0103
from the given file descriptor """
try:
return struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))
- except: # pylint: disable=W0702
+ except (IOError, struct.error):
return None
@@ -40,7 +40,7 @@ def get_termsize():
fd = os.open(os.ctermid(), os.O_RDONLY)
dims = _ioctl_GWINSZ(fd)
os.close(fd)
- except: # pylint: disable=W0702
+ except IOError:
pass
if not dims:
try:
diff --git a/src/lib/Bcfg2/Server/Plugin/helpers.py b/src/lib/Bcfg2/Server/Plugin/helpers.py
index 2aab231c6..5cfc8998c 100644
--- a/src/lib/Bcfg2/Server/Plugin/helpers.py
+++ b/src/lib/Bcfg2/Server/Plugin/helpers.py
@@ -266,7 +266,7 @@ class FileBacked(Debuggable):
self.fam = Bcfg2.Server.FileMonitor.get_fam()
def HandleEvent(self, event=None):
- """ HandleEvent is called whenever the FAM registers an event.
+ """HandleEvent is called whenever the FAM registers an event.
:param event: The event object
:type event: Bcfg2.Server.FileMonitor.Event
@@ -276,13 +276,11 @@ class FileBacked(Debuggable):
return
try:
self.data = open(self.name).read()
- self.Index()
except IOError:
err = sys.exc_info()[1]
self.logger.error("Failed to read file %s: %s" % (self.name, err))
- except:
- err = sys.exc_info()[1]
- self.logger.error("Failed to parse file %s: %s" % (self.name, err))
+
+ self.Index()
def Index(self):
""" Index() is called by :func:`HandleEvent` every time the
@@ -1196,7 +1194,7 @@ class SpecificData(Debuggable):
self.data = open(self.name).read()
except UnicodeDecodeError:
self.data = open(self.name, mode='rb').read()
- except: # pylint: disable=W0201
+ except IOError:
self.logger.error("Failed to read file %s" % self.name)
diff --git a/src/lib/Bcfg2/Server/Plugin/interfaces.py b/src/lib/Bcfg2/Server/Plugin/interfaces.py
index c45d6fa84..da39ac77a 100644
--- a/src/lib/Bcfg2/Server/Plugin/interfaces.py
+++ b/src/lib/Bcfg2/Server/Plugin/interfaces.py
@@ -445,8 +445,14 @@ class ThreadedStatistics(Statistics, Threaded, threading.Thread):
except Empty:
continue
except:
- err = sys.exc_info()[1]
- self.logger.error("ThreadedStatistics: %s" % err)
+ # we want to catch all exceptions here so that a stray
+ # error doesn't kill the entire statistics thread. For
+ # instance, if a bad value gets pushed onto the queue
+ # and the assignment above raises TypeError, we want
+ # to report the error, ignore the bad value, and
+ # continue processing statistics.
+ self.logger.error("Unknown error processing statistics: %s" %
+ sys.exc_info()[1])
continue
self.handle_statistic(client, xdata)
if self.work_queue is not None and not self.work_queue.empty():
diff --git a/src/lib/Bcfg2/Server/Plugins/AWSTags.py b/src/lib/Bcfg2/Server/Plugins/AWSTags.py
index 3f92542e7..0d6eefaaa 100644
--- a/src/lib/Bcfg2/Server/Plugins/AWSTags.py
+++ b/src/lib/Bcfg2/Server/Plugins/AWSTags.py
@@ -1,4 +1,4 @@
-""" Query tags from AWS via boto, optionally setting group membership """
+"""Query tags from AWS via boto, optionally setting group membership."""
import os
import re
@@ -82,22 +82,17 @@ class PatternFile(Bcfg2.Server.Plugin.XMLFileBacked):
self.tags.append(AWSTagPattern(entry.get("name"),
entry.get("value"),
groups))
- except: # pylint: disable=W0702
+ except re.error:
self.logger.error("AWSTags: Failed to initialize pattern %s: "
"%s" % (entry.get("name"),
sys.exc_info()[1]))
- def get_groups(self, hostname, tags):
+ def get_groups(self, tags):
""" return a list of groups that should be added to the given
- client based on patterns that match the hostname """
+ client based on patterns that match the tags """
ret = []
for pattern in self.tags:
- try:
- ret.extend(pattern.get_groups(tags))
- except: # pylint: disable=W0702
- self.logger.error("AWSTags: Failed to process pattern %s for "
- "%s" % (pattern, hostname),
- exc_info=1)
+ ret.extend(pattern.get_groups(tags))
return ret
@@ -182,5 +177,4 @@ class AWSTags(Bcfg2.Server.Plugin.Plugin,
return self.get_tags(metadata)
def get_additional_groups(self, metadata):
- return self.config.get_groups(metadata.hostname,
- self.get_tags(metadata))
+ return self.config.get_groups(self.get_tags(metadata))
diff --git a/src/lib/Bcfg2/Server/Plugins/Bundler.py b/src/lib/Bcfg2/Server/Plugins/Bundler.py
index 6c35ada59..e38eeea89 100644
--- a/src/lib/Bcfg2/Server/Plugins/Bundler.py
+++ b/src/lib/Bcfg2/Server/Plugins/Bundler.py
@@ -92,10 +92,6 @@ class Bundler(Plugin,
self.logger.error("Bundler: Failed to render templated bundle "
"%s: %s" % (bundlename, err))
continue
- except:
- self.logger.error("Bundler: Unexpected bundler error for %s" %
- bundlename, exc_info=1)
- continue
if data.get("independent", "false").lower() == "true":
data.tag = "Independent"
diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgGenshiGenerator.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgGenshiGenerator.py
index ef4e6a656..c3bf9569b 100644
--- a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgGenshiGenerator.py
+++ b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgGenshiGenerator.py
@@ -10,6 +10,7 @@ from Bcfg2.Server.Plugin import PluginExecutionError, removecomment, \
DefaultTemplateDataProvider, get_template_data
from Bcfg2.Server.Plugins.Cfg import CfgGenerator
from genshi.template import TemplateLoader, NewTextTemplate
+from genshi.template.base import TemplateError
from genshi.template.eval import UndefinedError, Suite
@@ -117,6 +118,8 @@ class CfgGenshiGenerator(CfgGenerator):
quad[2]))
raise
except:
+ # this needs to be a blanket except, since it can catch
+ # any error raised by the genshi template.
self._handle_genshi_exception(sys.exc_info())
get_data.__doc__ = CfgGenerator.get_data.__doc__
@@ -184,10 +187,10 @@ class CfgGenshiGenerator(CfgGenerator):
def handle_event(self, event):
CfgGenerator.handle_event(self, event)
try:
- self.template = \
- self.loader.load(self.name, cls=NewTextTemplate,
- encoding=Bcfg2.Options.setup.encoding)
- except:
+ self.template = self.loader.load(
+ self.name, cls=NewTextTemplate,
+ encoding=Bcfg2.Options.setup.encoding)
+ except TemplateError:
raise PluginExecutionError("Failed to load template: %s" %
sys.exc_info()[1])
handle_event.__doc__ = CfgGenerator.handle_event.__doc__
diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgPrivateKeyCreator.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgPrivateKeyCreator.py
index 8cc3f7b21..43035b410 100644
--- a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgPrivateKeyCreator.py
+++ b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgPrivateKeyCreator.py
@@ -47,7 +47,7 @@ class CfgPrivateKeyCreator(XMLCfgCreator):
the given client metadata, and may be obtained by
doing ``self.XMLMatch(metadata)``
:type spec: lxml.etree._Element
- :returns: string - The filename of the private key
+ :returns: tuple - (private key data, public key data)
"""
if spec is None:
spec = self.XMLMatch(metadata)
@@ -91,10 +91,9 @@ class CfgPrivateKeyCreator(XMLCfgCreator):
"with errors: %s" % (filename,
metadata.hostname,
result.stderr))
- return filename
- except:
+ return (open(filename).read(), open(filename + ".pub").read())
+ finally:
shutil.rmtree(tempdir)
- raise
# pylint: disable=W0221
def create_data(self, entry, metadata):
@@ -109,21 +108,17 @@ class CfgPrivateKeyCreator(XMLCfgCreator):
"""
spec = self.XMLMatch(metadata)
specificity = self.get_specificity(metadata)
- filename = self._gen_keypair(metadata, spec)
+ privkey, pubkey = self._gen_keypair(metadata, spec)
- try:
- # write the public key, stripping the comment and
- # replacing it with a comment that specifies the filename.
- kdata = open(filename + ".pub").read().split()[:2]
- kdata.append(self.pubkey_creator.get_filename(**specificity))
- pubkey = " ".join(kdata) + "\n"
- self.pubkey_creator.write_data(pubkey, **specificity)
+ # write the public key, stripping the comment and
+ # replacing it with a comment that specifies the filename.
+ kdata = pubkey.split()[:2]
+ kdata.append(self.pubkey_creator.get_filename(**specificity))
+ pubkey = " ".join(kdata) + "\n"
+ self.pubkey_creator.write_data(pubkey, **specificity)
- # encrypt the private key, write to the proper place, and
- # return it
- privkey = open(filename).read()
- self.write_data(privkey, **specificity)
- return privkey
- finally:
- shutil.rmtree(os.path.dirname(filename))
+ # encrypt the private key, write to the proper place, and
+ # return it
+ self.write_data(privkey, **specificity)
+ return privkey
# pylint: enable=W0221
diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py b/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py
index 5dc3d98eb..355e53588 100644
--- a/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py
+++ b/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py
@@ -553,12 +553,7 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet):
% (action, event.filename))
self.debug_log("%s handling %s event on %s" %
(hdlr.__name__, action, event.filename))
- try:
- self.entry_init(event, hdlr)
- except: # pylint: disable=W0702
- err = sys.exc_info()[1]
- self.logger.error("Cfg: Failed to parse %s: %s" %
- (event.filename, err))
+ self.entry_init(event, hdlr)
return
elif hdlr.ignore(event, basename=self.path):
return
@@ -732,7 +727,7 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet):
try:
return creator.create_data(entry, metadata)
- except:
+ except CfgCreationError:
raise PluginExecutionError("Cfg: Error creating data for %s: %s" %
(entry.get("name"), sys.exc_info()[1]))
@@ -760,6 +755,9 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet):
try:
return (generator.get_data(entry, metadata), generator)
except:
+ # TODO: the exceptions raised by ``get_data`` are not
+ # constrained in any way, so for now this needs to be a
+ # blanket except.
msg = "Cfg: Error rendering %s: %s" % (entry.get("name"),
sys.exc_info()[1])
self.logger.error(msg)
@@ -803,7 +801,7 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet):
try:
best = self.best_matching(metadata, generators)
rv.append(best.specific)
- except: # pylint: disable=W0702
+ except PluginExecutionError:
pass
if not rv or not rv[0].hostname:
@@ -835,7 +833,7 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet):
raise PluginExecutionError(msg)
try:
etext = new_entry['text'].encode(Bcfg2.Options.setup.encoding)
- except:
+ except UnicodeDecodeError:
msg = "Cfg: Cannot encode content of %s as %s" % \
(name, Bcfg2.Options.setup.encoding)
self.logger.error(msg)
diff --git a/src/lib/Bcfg2/Server/Plugins/FileProbes.py b/src/lib/Bcfg2/Server/Plugins/FileProbes.py
index 38f9403f5..b7d78bf75 100644
--- a/src/lib/Bcfg2/Server/Plugins/FileProbes.py
+++ b/src/lib/Bcfg2/Server/Plugins/FileProbes.py
@@ -38,7 +38,7 @@ if not os.path.exists(path):
try:
stat = os.stat(path)
-except:
+except OSError:
sys.stderr.write("Could not stat %%s: %%s" %% (path, sys.exc_info()[1]))
raise SystemExit(0)
data = Bcfg2.Client.XML.Element("ProbedFileData",
@@ -48,7 +48,7 @@ data = Bcfg2.Client.XML.Element("ProbedFileData",
mode=oct_mode(stat[0] & 4095))
try:
data.text = b64encode(open(path).read())
-except:
+except IOError:
sys.stderr.write("Could not read %%s: %%s" %% (path, sys.exc_info()[1]))
raise SystemExit(0)
print(Bcfg2.Client.XML.tostring(data, xml_declaration=False).decode('UTF-8'))
diff --git a/src/lib/Bcfg2/Server/Plugins/Git.py b/src/lib/Bcfg2/Server/Plugins/Git.py
index 9012fceb0..d0ae010fa 100644
--- a/src/lib/Bcfg2/Server/Plugins/Git.py
+++ b/src/lib/Bcfg2/Server/Plugins/Git.py
@@ -41,22 +41,17 @@ class Git(Version):
def get_revision(self):
"""Read git revision information for the Bcfg2 repository."""
- try:
- if HAS_GITPYTHON:
- return self.repo.head.commit.hexsha
- else:
- cmd = ["git", "--git-dir", self.vcs_path,
- "--work-tree", Bcfg2.Options.setup.vcs_root,
- "rev-parse", "HEAD"]
- self.debug_log("Git: Running %s" % cmd)
- result = self.cmd.run(cmd)
- if not result.success:
- raise Exception(result.stderr)
- return result.stdout
- except:
- raise PluginExecutionError("Git: Error getting revision from %s: "
- "%s" % (Bcfg2.Options.setup.vcs_root,
- sys.exc_info()[1]))
+ if HAS_GITPYTHON:
+ return self.repo.head.commit.hexsha
+ else:
+ cmd = ["git", "--git-dir", self.vcs_path,
+ "--work-tree", Bcfg2.Options.setup.vcs_root,
+ "rev-parse", "HEAD"]
+ self.debug_log("Git: Running %s" % cmd)
+ result = self.cmd.run(cmd)
+ if not result.success:
+ raise PluginExecutionError(result.stderr)
+ return result.stdout
def Update(self, ref=None):
""" Git.Update() => True|False
diff --git a/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py b/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py
index 7fa95fd05..9874977df 100644
--- a/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py
+++ b/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py
@@ -8,34 +8,43 @@ import Bcfg2.Server.Plugin
from Bcfg2.Utils import PackedDigitRange
+class PatternInitializationError(Exception):
+ """Raised when creating a PatternMap object fails."""
+
+
class PatternMap(object):
- """ Handler for a single pattern or range """
+ """Handler for a single pattern or range."""
def __init__(self, pattern, rangestr, groups):
self.pattern = pattern
self.rangestr = rangestr
self.groups = groups
- if pattern is not None:
- self.re = re.compile(pattern)
- self.process = self.process_re
- elif rangestr is not None:
- if '\\' in rangestr:
- raise Exception("Backslashes are not allowed in NameRanges")
- range_finder = r'\[\[[\d\-,]+\]\]'
- self.process = self.process_range
- self.re = re.compile(r'^' + re.sub(range_finder, r'(\d+)',
- rangestr))
- dmatcher = re.compile(re.sub(range_finder,
- r'\[\[([\d\-,]+)\]\]',
- rangestr))
- self.dranges = [PackedDigitRange(x)
- for x in dmatcher.match(rangestr).groups()]
- else:
- raise Exception("No pattern or range given")
+ try:
+ if pattern is not None:
+ self._re = re.compile(pattern)
+ self.process = self.process_re
+ elif rangestr is not None:
+ if '\\' in rangestr:
+ raise PatternInitializationError(
+ "Backslashes are not allowed in NameRanges")
+ range_finder = r'\[\[[\d\-,]+\]\]'
+ self.process = self.process_range
+ self._re = re.compile(r'^' + re.sub(range_finder, r'(\d+)',
+ rangestr))
+ dmatcher = re.compile(re.sub(range_finder,
+ r'\[\[([\d\-,]+)\]\]',
+ rangestr))
+ self.dranges = [PackedDigitRange(x)
+ for x in dmatcher.match(rangestr).groups()]
+ else:
+ raise PatternInitializationError("No pattern or range given")
+ except re.error:
+ raise PatternInitializationError(
+ "Could not compile pattern regex: %s" % sys.exc_info()[1])
def process_range(self, name):
- """ match the given hostname against a range-based NameRange """
- match = self.re.match(name)
+ """match the given hostname against a range-based NameRange."""
+ match = self._re.match(name)
if not match:
return None
digits = match.groups()
@@ -45,11 +54,11 @@ class PatternMap(object):
return self.groups
def process_re(self, name):
- """ match the given hostname against a regex-based NamePattern """
- match = self.re.search(name)
+ """match the given hostname against a regex-based NamePattern."""
+ match = self._re.search(name)
if not match:
return None
- ret = list()
+ ret = []
sub = match.groups()
for group in self.groups:
newg = group
@@ -64,7 +73,7 @@ class PatternMap(object):
class PatternFile(Bcfg2.Server.Plugin.XMLFileBacked):
- """ representation of GroupPatterns config.xml """
+ """representation of GroupPatterns config.xml."""
__identifier__ = None
create = 'GroupPatterns'
@@ -89,7 +98,7 @@ class PatternFile(Bcfg2.Server.Plugin.XMLFileBacked):
for range_ent in entry.findall('NameRange'):
rng = range_ent.text
self.patterns.append(PatternMap(None, rng, groups))
- except: # pylint: disable=W0702
+ except PatternInitializationError:
self.logger.error("GroupPatterns: Failed to initialize "
"pattern %s: %s" % (entry.text,
sys.exc_info()[1]))
@@ -99,20 +108,15 @@ class PatternFile(Bcfg2.Server.Plugin.XMLFileBacked):
client based on patterns that match the hostname """
ret = []
for pattern in self.patterns:
- try:
- grps = pattern.process(hostname)
- if grps is not None:
- ret.extend(grps)
- except: # pylint: disable=W0702
- self.logger.error("GroupPatterns: Failed to process pattern "
- "%s for %s" % (pattern.pattern, hostname),
- exc_info=1)
+ grps = pattern.process(hostname)
+ if grps is not None:
+ ret.extend(grps)
return ret
class GroupPatterns(Bcfg2.Server.Plugin.Plugin,
Bcfg2.Server.Plugin.Connector):
- """ set group membership based on client hostnames """
+ """set group membership based on client hostnames."""
def __init__(self, core):
Bcfg2.Server.Plugin.Plugin.__init__(self, core)
diff --git a/src/lib/Bcfg2/Server/Plugins/Guppy.py b/src/lib/Bcfg2/Server/Plugins/Guppy.py
index 8427a56c3..de994a2db 100644
--- a/src/lib/Bcfg2/Server/Plugins/Guppy.py
+++ b/src/lib/Bcfg2/Server/Plugins/Guppy.py
@@ -1,9 +1,9 @@
-"""
-This plugin is used to trace memory leaks within the bcfg2-server
-process using Guppy. By default the remote debugger is started
-when this plugin is enabled. The debugger can be shutoff in a running
-process using "bcfg2-admin xcmd Guppy.Disable" and reenabled using
-"bcfg2-admin xcmd Guppy.Enable".
+"""Debugging plugin to trace memory leaks within the bcfg2-server process.
+
+By default the remote debugger is started when this plugin is enabled.
+The debugger can be shutoff in a running process using "bcfg2-admin
+xcmd Guppy.Disable" and reenabled using "bcfg2-admin xcmd
+Guppy.Enable".
To attach the console run:
@@ -23,36 +23,27 @@ Remote connection 1. To return to Monitor, type <Ctrl-C> or .<RETURN>
Remote interactive console. To return to Annex, type '-'.
>>> hp.heap()
...
-
-
"""
import Bcfg2.Server.Plugin
from guppy.heapy import Remote
class Guppy(Bcfg2.Server.Plugin.Plugin):
- """Guppy is a debugging plugin to help trace memory leaks"""
+ """Guppy is a debugging plugin to help trace memory leaks."""
__author__ = 'bcfg-dev@mcs.anl.gov'
__rmi__ = Bcfg2.Server.Plugin.Plugin.__rmi__ + ['Enable', 'Disable']
__child_rmi__ = __rmi__[:]
def __init__(self, core):
Bcfg2.Server.Plugin.Plugin.__init__(self, core)
-
self.Enable()
- def Enable(self):
- """Enable remote debugging"""
- try:
- Remote.on()
- except:
- self.logger.error("Failed to create Heapy context")
- raise Bcfg2.Server.Plugin.PluginInitError
-
- def Disable(self):
- """Disable remote debugging"""
- try:
- Remote.off()
- except:
- self.logger.error("Failed to disable Heapy")
- raise Bcfg2.Server.Plugin.PluginInitError
+ @staticmethod
+ def Enable():
+ """Enable remote debugging."""
+ Remote.on()
+
+ @staticmethod
+ def Disable():
+ """Disable remote debugging."""
+ Remote.off()
diff --git a/src/lib/Bcfg2/Server/Plugins/Hg.py b/src/lib/Bcfg2/Server/Plugins/Hg.py
index 7554b4d52..3260908d8 100644
--- a/src/lib/Bcfg2/Server/Plugins/Hg.py
+++ b/src/lib/Bcfg2/Server/Plugins/Hg.py
@@ -1,5 +1,5 @@
-""" The Hg plugin provides a revision interface for Bcfg2 repos using
-mercurial. """
+"""Revision interface for Bcfg2 repos using mercurial.
+"""
import sys
from mercurial import ui, hg
@@ -7,8 +7,9 @@ import Bcfg2.Server.Plugin
class Hg(Bcfg2.Server.Plugin.Version):
- """ The Hg plugin provides a revision interface for Bcfg2 repos
- using mercurial. """
+ """Revision interface for Bcfg2 repos using mercurial.
+ """
+
__author__ = 'bcfg-dev@mcs.anl.gov'
__vcs_metadata_path__ = ".hg"
@@ -24,7 +25,7 @@ class Hg(Bcfg2.Server.Plugin.Version):
repo = hg.repository(ui.ui(), repo_path)
tip = repo.changelog.tip()
return repo.changelog.rev(tip)
- except:
+ except hg.error.RepoError:
err = sys.exc_info()[1]
msg = "Failed to read hg repository: %s" % err
self.logger.error(msg)
diff --git a/src/lib/Bcfg2/Server/Plugins/Metadata.py b/src/lib/Bcfg2/Server/Plugins/Metadata.py
index 26f39e50d..b850c1870 100644
--- a/src/lib/Bcfg2/Server/Plugins/Metadata.py
+++ b/src/lib/Bcfg2/Server/Plugins/Metadata.py
@@ -7,7 +7,6 @@ import sys
import time
import copy
import errno
-import fcntl
import socket
import logging
import lxml.etree
@@ -201,15 +200,7 @@ class XMLMetadataConfig(Bcfg2.Server.Plugin.XMLFileBacked):
while locked(fd):
pass
- try:
- datafile.write(newcontents)
- except:
- fcntl.lockf(fd, fcntl.LOCK_UN)
- msg = "Metadata: Failed to write new xml data to %s: %s" % \
- (tmpfile, sys.exc_info()[1])
- self.logger.error(msg, exc_info=1)
- os.unlink(tmpfile)
- raise Bcfg2.Server.Plugin.MetadataRuntimeError(msg)
+ datafile.write(newcontents)
datafile.close()
# check if clients.xml is a symlink
if os.path.islink(fname):
@@ -217,10 +208,10 @@ class XMLMetadataConfig(Bcfg2.Server.Plugin.XMLFileBacked):
try:
os.rename(tmpfile, fname)
- except: # pylint: disable=W0702
+ except OSError:
try:
os.unlink(tmpfile)
- except: # pylint: disable=W0702
+ except OSError:
pass
msg = "Metadata: Failed to rename %s: %s" % (tmpfile,
sys.exc_info()[1])
@@ -594,14 +585,8 @@ class Metadata(Bcfg2.Server.Plugin.Metadata,
def _handle_file(self, fname):
""" set up the necessary magic for handling a metadata file
(clients.xml or groups.xml, e.g.) """
- try:
- Bcfg2.Server.FileMonitor.get_fam().AddMonitor(
- os.path.join(self.data, fname), self)
- except:
- err = sys.exc_info()[1]
- msg = "Unable to add file monitor for %s: %s" % (fname, err)
- self.logger.error(msg)
- raise Bcfg2.Server.Plugin.PluginInitError(msg)
+ Bcfg2.Server.FileMonitor.get_fam().AddMonitor(
+ os.path.join(self.data, fname), self)
self.states[fname] = False
xmlcfg = XMLMetadataConfig(self, fname)
aname = re.sub(r'[^A-z0-9_]', '_', os.path.basename(fname))
diff --git a/src/lib/Bcfg2/Server/Plugins/Ohai.py b/src/lib/Bcfg2/Server/Plugins/Ohai.py
index c5fb46c97..461be9ba8 100644
--- a/src/lib/Bcfg2/Server/Plugins/Ohai.py
+++ b/src/lib/Bcfg2/Server/Plugins/Ohai.py
@@ -51,7 +51,7 @@ class OhaiCache(object):
if item not in self.cache:
try:
data = open(self.hostpath(item)).read()
- except:
+ except IOError:
raise KeyError(item)
self.cache[item] = json.loads(data)
return self.cache[item]
@@ -61,7 +61,7 @@ class OhaiCache(object):
del self.cache[item]
try:
os.unlink(self.hostpath(item))
- except:
+ except OSError:
raise IndexError("Could not unlink %s: %s" % (self.hostpath(item),
sys.exc_info()[1]))
diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Apt.py b/src/lib/Bcfg2/Server/Plugins/Packages/Apt.py
index cfabd8457..7de79e2f3 100644
--- a/src/lib/Bcfg2/Server/Plugins/Packages/Apt.py
+++ b/src/lib/Bcfg2/Server/Plugins/Packages/Apt.py
@@ -89,7 +89,7 @@ class AptSource(Source):
bprov[barch] = dict()
try:
reader = gzip.GzipFile(fname)
- except:
+ except IOError:
self.logger.error("Packages: Failed to read file %s" % fname)
raise
for line in reader.readlines():
diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Pac.py b/src/lib/Bcfg2/Server/Plugins/Packages/Pac.py
index 5f4d2ea41..0e15d2e15 100644
--- a/src/lib/Bcfg2/Server/Plugins/Packages/Pac.py
+++ b/src/lib/Bcfg2/Server/Plugins/Packages/Pac.py
@@ -67,7 +67,7 @@ class PacSource(Source):
try:
self.debug_log("Packages: try to read %s" % fname)
tar = tarfile.open(fname, "r")
- except:
+ except (IOError, tarfile.TarError):
self.logger.error("Packages: Failed to read file %s" % fname)
raise
diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Pkgng.py b/src/lib/Bcfg2/Server/Plugins/Packages/Pkgng.py
index e393cabfe..736cdcdd4 100644
--- a/src/lib/Bcfg2/Server/Plugins/Packages/Pkgng.py
+++ b/src/lib/Bcfg2/Server/Plugins/Packages/Pkgng.py
@@ -71,7 +71,7 @@ class PkgngSource(Source):
try:
tar = tarfile.open(fileobj=lzma.LZMAFile(fname))
reader = tar.extractfile('packagesite.yaml')
- except:
+ except (IOError, tarfile.TarError):
self.logger.error("Packages: Failed to read file %s" % fname)
raise
for line in reader.readlines():
diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Source.py b/src/lib/Bcfg2/Server/Plugins/Packages/Source.py
index 67ada2399..c9f6ea14a 100644
--- a/src/lib/Bcfg2/Server/Plugins/Packages/Source.py
+++ b/src/lib/Bcfg2/Server/Plugins/Packages/Source.py
@@ -331,10 +331,11 @@ class Source(Debuggable): # pylint: disable=R0902
@track_statistics()
def setup_data(self, force_update=False):
- """ Perform all data fetching and setup tasks. For most
- backends, this involves downloading all metadata from the
- repository, parsing it, and caching the parsed data locally.
- The order of operations is:
+ """Perform all data fetching and setup tasks.
+
+ For most backends, this involves downloading all metadata from
+ the repository, parsing it, and caching the parsed data
+ locally. The order of operations is:
#. Call :func:`load_state` to try to load data from the local
cache.
@@ -352,6 +353,15 @@ class Source(Debuggable): # pylint: disable=R0902
upstream repository.
:type force_update: bool
"""
+ # there are a bunch of wildcard except statements here,
+ # because the various functions called herein (``load_state``,
+ # ``read_files``, ``update``) are defined entirely by the
+ # Packages plugins that implement them.
+ #
+ # TODO: we should define an exception subclass that each of
+ # these functions can raise when an *expected* error condition
+ # is encountered.
+ #
# pylint: disable=W0702
if not force_update:
if os.path.exists(self.cachefile):
diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py
index b6e9f13eb..dbe3f9ce5 100644
--- a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py
+++ b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py
@@ -631,10 +631,6 @@ class YumCollection(Collection):
err = sys.exc_info()[1]
self.logger.error("Packages: Could not contact Pulp server: %s" %
err)
- except:
- err = sys.exc_info()[1]
- self.logger.error("Packages: Unknown error querying Pulp server: "
- "%s" % err)
return consumer
@track_statistics()
@@ -1034,10 +1030,6 @@ class YumSource(Source):
err = sys.exc_info()[1]
raise SourceInitError("Could not contact Pulp server: %s" %
err)
- except:
- err = sys.exc_info()[1]
- raise SourceInitError("Unknown error querying Pulp server: %s"
- % err)
self.rawurl = "%s/%s" % (PULPCONFIG.cds['baseurl'],
self.repo['relative_path'])
self.arches = [self.repo['arch']]
diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/YumHelper.py b/src/lib/Bcfg2/Server/Plugins/Packages/YumHelper.py
index f26d6ba18..b2e43bde7 100644
--- a/src/lib/Bcfg2/Server/Plugins/Packages/YumHelper.py
+++ b/src/lib/Bcfg2/Server/Plugins/Packages/YumHelper.py
@@ -285,8 +285,8 @@ class HelperSubcommand(Bcfg2.Options.Subcommand):
def run(self, setup):
try:
data = json.loads(sys.stdin.read())
- except: # pylint: disable=W0702
- self.logger.error("Unexpected error decoding JSON input: %s" %
+ except ValueError:
+ self.logger.error("Error decoding JSON input: %s" %
sys.exc_info()[1])
print(json.dumps(self.fallback))
return 2
diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py b/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py
index 87d42fd1c..3aa5c415f 100644
--- a/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py
+++ b/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py
@@ -515,10 +515,6 @@ class Packages(Bcfg2.Server.Plugin.Plugin,
err = sys.exc_info()[1]
self.logger.error("Packages: Error writing %s to %s: "
"%s" % (key, localfile, err))
- except:
- err = sys.exc_info()[1]
- self.logger.error("Packages: Unknown error fetching "
- "%s: %s" % (key, err))
for kfile in glob.glob(os.path.join(self.keypath, "*")):
if kfile not in keyfiles:
diff --git a/src/lib/Bcfg2/Server/Plugins/Pkgmgr.py b/src/lib/Bcfg2/Server/Plugins/Pkgmgr.py
index c7d8986ed..7c6ab0ed7 100644
--- a/src/lib/Bcfg2/Server/Plugins/Pkgmgr.py
+++ b/src/lib/Bcfg2/Server/Plugins/Pkgmgr.py
@@ -35,7 +35,7 @@ class FuzzyDict(dict):
def get(self, key, default=None):
try:
return self.__getitem__(key)
- except:
+ except KeyError:
if default:
return default
raise
@@ -182,11 +182,7 @@ class PNode(object):
"""Return a dictionary of package mappings."""
if self.predicate(metadata, entry):
for key in self.contents:
- try:
- data[key].update(self.contents[key])
- except: # pylint: disable=W0702
- data[key] = FuzzyDict()
- data[key].update(self.contents[key])
+ data.setdefault(key, FuzzyDict).update(self.contents[key])
for child in self.children:
child.Match(metadata, data)
diff --git a/src/lib/Bcfg2/Server/Plugins/Probes.py b/src/lib/Bcfg2/Server/Plugins/Probes.py
index 21d50ace6..76aab69b5 100644
--- a/src/lib/Bcfg2/Server/Plugins/Probes.py
+++ b/src/lib/Bcfg2/Server/Plugins/Probes.py
@@ -405,7 +405,7 @@ class ProbeSet(Bcfg2.Server.Plugin.EntrySet):
else:
try:
probe.text = entry.data
- except: # pylint: disable=W0702
+ except ValueError:
self.logger.error("Client unable to handle unicode "
"probes. Skipping %s" %
probe.get('name'))
@@ -447,12 +447,7 @@ class Probes(Bcfg2.Server.Plugin.Probing,
Bcfg2.Server.Plugin.Connector.__init__(self)
Bcfg2.Server.Plugin.DatabaseBacked.__init__(self, core)
- try:
- self.probes = ProbeSet(self.data, self.name)
- except:
- err = sys.exc_info()[1]
- raise Bcfg2.Server.Plugin.PluginInitError(err)
-
+ self.probes = ProbeSet(self.data, self.name)
if self._use_db:
self.probestore = DBProbeStore(core, self.data)
else:
diff --git a/src/lib/Bcfg2/Server/Plugins/Properties.py b/src/lib/Bcfg2/Server/Plugins/Properties.py
index 28400f6d2..c4dd75e60 100644
--- a/src/lib/Bcfg2/Server/Plugins/Properties.py
+++ b/src/lib/Bcfg2/Server/Plugins/Properties.py
@@ -79,13 +79,12 @@ class PropertyFile(object):
class JSONPropertyFile(Bcfg2.Server.Plugin.FileBacked, PropertyFile):
- """ Handle JSON Properties files. """
+ """Handle JSON Properties files."""
def __init__(self, name):
Bcfg2.Server.Plugin.FileBacked.__init__(self, name)
PropertyFile.__init__(self, name)
self.json = None
- __init__.__doc__ = Bcfg2.Server.Plugin.FileBacked.__init__.__doc__
def Index(self):
try:
@@ -94,21 +93,18 @@ class JSONPropertyFile(Bcfg2.Server.Plugin.FileBacked, PropertyFile):
err = sys.exc_info()[1]
raise PluginExecutionError("Could not load JSON data from %s: %s" %
(self.name, err))
- Index.__doc__ = Bcfg2.Server.Plugin.FileBacked.Index.__doc__
def _write(self):
json.dump(self.json, open(self.name, 'wb'))
return True
- _write.__doc__ = PropertyFile._write.__doc__
def validate_data(self):
try:
json.dumps(self.json)
- except:
+ except TypeError:
err = sys.exc_info()[1]
raise PluginExecutionError("Data for %s cannot be dumped to JSON: "
"%s" % (self.name, err))
- validate_data.__doc__ = PropertyFile.validate_data.__doc__
def __str__(self):
return str(self.json)
diff --git a/src/lib/Bcfg2/Server/Plugins/Reporting.py b/src/lib/Bcfg2/Server/Plugins/Reporting.py
index 282de8247..5c73546b4 100644
--- a/src/lib/Bcfg2/Server/Plugins/Reporting.py
+++ b/src/lib/Bcfg2/Server/Plugins/Reporting.py
@@ -3,7 +3,6 @@
import sys
import time
import platform
-import traceback
import lxml.etree
import Bcfg2.Options
from Bcfg2.Reporting.Transport.base import TransportError
@@ -102,11 +101,11 @@ class Reporting(Statistics, Threaded, PullSource):
except TransportError:
continue
except:
- self.logger.error("%s: Attempt %s: Failed to add statistic %s"
+ self.logger.error("%s: Attempt %s: Failed to add statistic: %s"
% (self.__class__.__name__, i,
- traceback.format_exc().splitlines()[-1]))
- self.logger.error("%s: Retry limit reached for %s" %
- (self.__class__.__name__, client.hostname))
+ sys.exc_info()[1]))
+ raise PluginExecutionError("%s: Retry limit reached for %s" %
+ (self.__class__.__name__, client.hostname))
def shutdown(self):
super(Reporting, self).shutdown()
diff --git a/src/lib/Bcfg2/Server/Plugins/SSHbase.py b/src/lib/Bcfg2/Server/Plugins/SSHbase.py
index 89c7107aa..e4fb9b565 100644
--- a/src/lib/Bcfg2/Server/Plugins/SSHbase.py
+++ b/src/lib/Bcfg2/Server/Plugins/SSHbase.py
@@ -199,20 +199,19 @@ class SSHbase(Bcfg2.Server.Plugin.Plugin,
newnames.add(name.split('.')[0])
try:
newips.update(self.get_ipcache_entry(name)[0])
- except: # pylint: disable=W0702
+ except PluginExecutionError:
continue
names[cmeta.hostname].update(newnames)
names[cmeta.hostname].update(cmeta.addresses)
names[cmeta.hostname].update(newips)
# TODO: Only perform reverse lookups on IPs if an
# option is set.
- if True:
- for ip in newips:
- try:
- names[cmeta.hostname].update(
- self.get_namecache_entry(ip))
- except: # pylint: disable=W0702
- continue
+ for ip in newips:
+ try:
+ names[cmeta.hostname].update(
+ self.get_namecache_entry(ip))
+ except socket.gaierror:
+ continue
names[cmeta.hostname] = sorted(names[cmeta.hostname])
pubkeys = [pubk for pubk in list(self.entries.keys())
@@ -309,7 +308,7 @@ class SSHbase(Bcfg2.Server.Plugin.Plugin,
(event.filename, action))
def get_ipcache_entry(self, client):
- """ Build a cache of dns results. """
+ """Build a cache of dns results."""
if client in self.ipcache:
if self.ipcache[client]:
return self.ipcache[client]
diff --git a/src/lib/Bcfg2/Server/Plugins/TemplateHelper.py b/src/lib/Bcfg2/Server/Plugins/TemplateHelper.py
index 047fc062e..cec2de297 100644
--- a/src/lib/Bcfg2/Server/Plugins/TemplateHelper.py
+++ b/src/lib/Bcfg2/Server/Plugins/TemplateHelper.py
@@ -55,6 +55,10 @@ class HelperModule(Debuggable):
module = imp.load_source(safe_module_name(self._module_name),
self.name)
except: # pylint: disable=W0702
+ # this needs to be a blanket except because the
+ # imp.load_source() call can raise literally any error,
+ # since it imports the module and just passes through any
+ # exceptions raised.
err = sys.exc_info()[1]
self.logger.error("TemplateHelper: Failed to import %s: %s" %
(self.name, err))