summaryrefslogtreecommitdiffstats
path: root/src/lib/Server
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/Server')
-rw-r--r--src/lib/Server/Lint/GroupPatterns.py31
-rw-r--r--src/lib/Server/Lint/__init__.py5
-rw-r--r--src/lib/Server/Plugin.py11
-rw-r--r--src/lib/Server/Plugins/FileProbes.py2
-rw-r--r--src/lib/Server/Plugins/GroupPatterns.py25
-rw-r--r--src/lib/Server/Plugins/Packages/__init__.py3
-rw-r--r--src/lib/Server/Plugins/Properties.py2
-rw-r--r--src/lib/Server/Plugins/Rules.py8
-rw-r--r--src/lib/Server/Snapshots/model.py2
9 files changed, 72 insertions, 17 deletions
diff --git a/src/lib/Server/Lint/GroupPatterns.py b/src/lib/Server/Lint/GroupPatterns.py
new file mode 100644
index 000000000..b69d7a5d8
--- /dev/null
+++ b/src/lib/Server/Lint/GroupPatterns.py
@@ -0,0 +1,31 @@
+import sys
+import Bcfg2.Server.Lint
+from Bcfg2.Server.Plugins.GroupPatterns import PatternMap
+
+class GroupPatterns(Bcfg2.Server.Lint.ServerPlugin):
+ """ Check Genshi templates for syntax errors """
+
+ def Run(self):
+ """ run plugin """
+ if 'GroupPatterns' in self.core.plugins:
+ cfg = self.core.plugins['GroupPatterns'].config
+ for entry in cfg.xdata.xpath('//GroupPattern'):
+ groups = [g.text for g in entry.findall('Group')]
+ self.check(entry, groups, ptype='NamePattern')
+ self.check(entry, groups, ptype='NameRange')
+
+ def check(self, entry, groups, ptype="NamePattern"):
+ if ptype == "NamePattern":
+ pmap = lambda p: PatternMap(p, None, groups)
+ else:
+ pmap = lambda p: PatternMap(None, p, groups)
+
+ for el in entry.findall(ptype):
+ pat = el.text
+ try:
+ pmap(pat)
+ except:
+ err = sys.exc_info()[1]
+ self.LintError("pattern-fails-to-initialize",
+ "Failed to initialize %s %s for %s: %s" %
+ (ptype, pat, entry.get('pattern'), err))
diff --git a/src/lib/Server/Lint/__init__.py b/src/lib/Server/Lint/__init__.py
index f47059ac4..a9d57c46c 100644
--- a/src/lib/Server/Lint/__init__.py
+++ b/src/lib/Server/Lint/__init__.py
@@ -117,8 +117,9 @@ class ErrorHandler (object):
"xml-failed-to-verify":"error",
"merge-cfg":"warning",
"merge-probes":"warning",
- "input-output-error": "error",
- "genshi-syntax-error": "error"}
+ "input-output-error":"error",
+ "genshi-syntax-error":"error",
+ "pattern-fails-to-initialize":"error"}
def __init__(self, config=None):
self.errors = 0
diff --git a/src/lib/Server/Plugin.py b/src/lib/Server/Plugin.py
index 41ac9dc20..4bfa3fdf5 100644
--- a/src/lib/Server/Plugin.py
+++ b/src/lib/Server/Plugin.py
@@ -357,7 +357,7 @@ class FileBacked(object):
object.__init__(self)
self.data = ''
self.name = name
-
+
def HandleEvent(self, event=None):
"""Read file upon update."""
if event and event.code2str() not in ['exists', 'changed', 'created']:
@@ -373,6 +373,12 @@ class FileBacked(object):
"""Update local data structures based on current file state"""
pass
+ def __repr__(self):
+ return "%s: %s" % (self.__class__.__name__, str(self))
+
+ def __str__(self):
+ return "%s: %s" % (self.name, self.data)
+
class DirectoryBacked(object):
"""This object is a coherent cache for a filesystem hierarchy of files."""
@@ -568,6 +574,9 @@ class XMLFileBacked(FileBacked):
def __iter__(self):
return iter(self.entries)
+ def __str__(self):
+ return "%s: %s" % (self.name, lxml.etree.tostring(self.xdata))
+
class SingleXMLFileBacked(XMLFileBacked):
"""This object is a coherent cache for an independent XML file."""
diff --git a/src/lib/Server/Plugins/FileProbes.py b/src/lib/Server/Plugins/FileProbes.py
index 0c1a0d897..269664ef4 100644
--- a/src/lib/Server/Plugins/FileProbes.py
+++ b/src/lib/Server/Plugins/FileProbes.py
@@ -133,7 +133,7 @@ class FileProbes(Bcfg2.Server.Plugin.Plugin,
create = True
# get current entry data
- if entry.get("encoding") == "base64":
+ if entry.text and entry.get("encoding") == "base64":
entrydata = binascii.a2b_base64(entry.text)
else:
entrydata = entry.text
diff --git a/src/lib/Server/Plugins/GroupPatterns.py b/src/lib/Server/Plugins/GroupPatterns.py
index 76a628931..58b4d4afb 100644
--- a/src/lib/Server/Plugins/GroupPatterns.py
+++ b/src/lib/Server/Plugins/GroupPatterns.py
@@ -1,9 +1,8 @@
-import lxml.etree
import re
-
+import logging
+import lxml.etree
import Bcfg2.Server.Plugin
-
class PackedDigitRange(object):
def __init__(self, digit_range):
self.sparse = list()
@@ -25,7 +24,7 @@ class PackedDigitRange(object):
class PatternMap(object):
- range_finder = '\\[\\[[\d\-,]+\\]\\]'
+ range_finder = r'\[\[[\d\-,]+\]\]'
def __init__(self, pattern, rangestr, groups):
self.pattern = pattern
@@ -35,15 +34,18 @@ class PatternMap(object):
self.re = re.compile(pattern)
self.process = self.process_re
elif rangestr != None:
+ if '\\' in rangestr:
+ raise Exception("Backslashes are not allowed in NameRanges")
self.process = self.process_range
- self.re = re.compile('^' + re.subn(self.range_finder, '(\d+)',
- rangestr)[0])
- dmatcher = re.compile(re.subn(self.range_finder,
- '\\[\\[([\d\-,]+)\\]\\]',
- rangestr)[0])
- self.dranges = [PackedDigitRange(x) for x in dmatcher.match(rangestr).groups()]
+ self.re = re.compile('^' + re.sub(self.range_finder, '(\d+)',
+ rangestr))
+ dmatcher = re.compile(re.sub(self.range_finder,
+ r'\[\[([\d\-,]+)\]\]',
+ rangestr))
+ self.dranges = [PackedDigitRange(x)
+ for x in dmatcher.match(rangestr).groups()]
else:
- raise Exception
+ raise Exception("No pattern or range given")
def process_range(self, name):
match = self.re.match(name)
@@ -75,6 +77,7 @@ class PatternFile(Bcfg2.Server.Plugin.SingleXMLFileBacked):
def __init__(self, filename, fam):
Bcfg2.Server.Plugin.SingleXMLFileBacked.__init__(self, filename, fam)
self.patterns = []
+ self.logger = logging.getLogger(self.__class__.__name__)
def Index(self):
Bcfg2.Server.Plugin.SingleXMLFileBacked.Index(self)
diff --git a/src/lib/Server/Plugins/Packages/__init__.py b/src/lib/Server/Plugins/Packages/__init__.py
index b8babfac2..b12d633f3 100644
--- a/src/lib/Server/Plugins/Packages/__init__.py
+++ b/src/lib/Server/Plugins/Packages/__init__.py
@@ -214,7 +214,8 @@ class Packages(Bcfg2.Server.Plugin.Plugin,
keys = []
for source in self.sources:
for key in source.gpgkeys:
- localfile = os.path.join(self.keypath, os.path.basename(key))
+ localfile = os.path.join(self.keypath,
+ os.path.basename(key.rstrip("/")))
if localfile not in keyfiles:
keyfiles.append(localfile)
if ((force_update and key not in keys) or
diff --git a/src/lib/Server/Plugins/Properties.py b/src/lib/Server/Plugins/Properties.py
index 58f7215c9..9b44942cd 100644
--- a/src/lib/Server/Plugins/Properties.py
+++ b/src/lib/Server/Plugins/Properties.py
@@ -1,4 +1,5 @@
import os
+import re
import sys
import copy
import logging
@@ -49,6 +50,7 @@ class PropertyFile(Bcfg2.Server.Plugin.StructFile):
class PropDirectoryBacked(Bcfg2.Server.Plugin.DirectoryBacked):
__child__ = PropertyFile
+ patterns = re.compile(r'.*\.xml$')
class Properties(Bcfg2.Server.Plugin.Plugin,
diff --git a/src/lib/Server/Plugins/Rules.py b/src/lib/Server/Plugins/Rules.py
index fde0f3d59..c66276179 100644
--- a/src/lib/Server/Plugins/Rules.py
+++ b/src/lib/Server/Plugins/Rules.py
@@ -36,6 +36,14 @@ class Rules(Bcfg2.Server.Plugin.PrioDir):
def _matches(self, entry, metadata, rules):
if Bcfg2.Server.Plugin.PrioDir._matches(self, entry, metadata, rules):
return True
+ elif (entry.tag == "Path" and
+ ((entry.get('name').endswith("/") and
+ entry.get('name').rstrip("/") in rules) or
+ (not entry.get('name').endswith("/") and
+ entry.get('name') + '/' in rules))):
+ # special case for Path tags:
+ # http://trac.mcs.anl.gov/projects/bcfg2/ticket/967
+ return True
elif self._regex_enabled:
# attempt regular expression matching
for rule in rules:
diff --git a/src/lib/Server/Snapshots/model.py b/src/lib/Server/Snapshots/model.py
index f30c38a05..5d7973c16 100644
--- a/src/lib/Server/Snapshots/model.py
+++ b/src/lib/Server/Snapshots/model.py
@@ -211,7 +211,7 @@ class File(Base, Uniquer):
type = Column(Unicode(12))
owner = Column(Unicode(12))
group = Column(Unicode(16))
- perms = Column(Integer(5))
+ perms = Column(Integer)
contents = Column(UnicodeText)