1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
"""This provides bundle clauses with translation functionality."""
import os
import re
import sys
import copy
import Bcfg2.Server
import Bcfg2.Server.Plugin
from genshi.template import TemplateError
class BundleFile(Bcfg2.Server.Plugin.StructFile):
""" Representation of a bundle XML file """
bundle_name_re = re.compile(r'^(?P<name>.*)\.(xml|genshi)$')
def __init__(self, filename, should_monitor=False):
Bcfg2.Server.Plugin.StructFile.__init__(self, filename,
should_monitor=should_monitor)
if self.name.endswith(".genshi"):
self.logger.warning("Bundler: %s: Bundle filenames ending with "
".genshi are deprecated; add the Genshi XML "
"namespace to a .xml bundle instead" %
self.name)
__init__.__doc__ = Bcfg2.Server.Plugin.StructFile.__init__.__doc__
def Index(self):
Bcfg2.Server.Plugin.StructFile.Index(self)
if self.xdata.get("name"):
self.logger.warning("Bundler: %s: Explicitly specifying bundle "
"names is deprecated" % self.name)
Index.__doc__ = Bcfg2.Server.Plugin.StructFile.Index.__doc__
@property
def bundle_name(self):
""" The name of the bundle, as determined from the filename """
return self.bundle_name_re.match(
os.path.basename(self.name)).group("name")
class Bundler(Bcfg2.Server.Plugin.Plugin,
Bcfg2.Server.Plugin.Structure,
Bcfg2.Server.Plugin.XMLDirectoryBacked):
""" The bundler creates dependent clauses based on the
bundle/translation scheme from Bcfg1. """
__author__ = 'bcfg-dev@mcs.anl.gov'
__child__ = BundleFile
patterns = re.compile(r'^.*\.(?:xml|genshi)$')
def __init__(self, core, datastore):
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
Bcfg2.Server.Plugin.Structure.__init__(self)
Bcfg2.Server.Plugin.XMLDirectoryBacked.__init__(self, self.data)
#: Bundles by bundle name, rather than filename
self.bundles = dict()
__init__.__doc__ = Bcfg2.Server.Plugin.Plugin.__init__.__doc__
def HandleEvent(self, event):
Bcfg2.Server.Plugin.XMLDirectoryBacked.HandleEvent(self, event)
self.bundles = dict([(b.bundle_name, b)
for b in self.entries.values()])
HandleEvent.__doc__ = \
Bcfg2.Server.Plugin.XMLDirectoryBacked.HandleEvent.__doc__
def BuildStructures(self, metadata):
bundleset = []
bundles = copy.copy(metadata.bundles)
bundles_added = set(bundles)
while bundles:
bundlename = bundles.pop()
try:
bundle = self.bundles[bundlename]
except KeyError:
self.logger.error("Bundler: Bundle %s does not exist" %
bundlename)
continue
try:
data = bundle.XMLMatch(metadata)
except TemplateError:
err = sys.exc_info()[1]
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"
del data.attrib['independent']
data.set("name", bundlename)
for child in data.findall("Bundle"):
if child.getchildren():
# XInclude'd bundle -- "flatten" it so there
# aren't extra Bundle tags, since other bits in
# Bcfg2 only handle the direct children of the
# top-level Bundle tag
if data.get("name"):
self.logger.warning("Bundler: In file XIncluded from "
"%s: Explicitly specifying "
"bundle names is deprecated" %
self.name)
for el in child.getchildren():
data.append(el)
data.remove(child)
elif child.get("name"):
# dependent bundle -- add it to the list of
# bundles for this client
if child.get("name") not in bundles_added:
bundles.append(child.get("name"))
bundles_added.add(child.get("name"))
data.remove(child)
else:
# neither name or children -- wat
self.logger.warning("Bundler: Useless empty Bundle tag "
"in %s" % self.name)
data.remove(child)
bundleset.append(data)
return bundleset
BuildStructures.__doc__ = \
Bcfg2.Server.Plugin.Structure.BuildStructures.__doc__
|