1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 """
19 Parsing of configuration files.
20 """
21
22 import os
23 from xml.dom import minidom, Node
24 from xml.parsers import expat
25
26 from flumotion.common import log, common
27
28 __version__ = "$Rev$"
29
30
33
34
36 "I represent a <manager> entry in a worker config file"
37
38 - def __init__(self, host, port, transport):
39 self.host = host
40 self.port = port
41 self.transport = transport
42
43
45 "I represent a <authentication> entry in a worker config file"
46
47 - def __init__(self, username, password):
50
51
53 logCategory = 'config'
54
55 - def __init__(self, filename, string=None):
56 self.name = None
57 self.manager = None
58 self.authentication = None
59 self.feederports = None
60 self.fludebug = None
61 self.randomFeederports = False
62
63 try:
64 if filename != None:
65 self.debug('Loading configuration file `%s\'' % filename)
66 self.doc = minidom.parse(filename)
67 else:
68 self.doc = minidom.parseString(string)
69 except expat.ExpatError, e:
70 raise ConfigError("XML parser error: %s" % e)
71
72 if filename != None:
73 self.path = os.path.split(filename)[0]
74 else:
75 self.path = None
76
77 self.parse()
78
79
80
82
83
84
85
86
87
88 root = self.doc.documentElement
89
90 if not root.nodeName == 'worker':
91 raise ConfigError("unexpected root node': %s" % root.nodeName)
92
93 if root.hasAttribute('name'):
94 self.name = str(root.getAttribute('name'))
95
96 for node in root.childNodes:
97 if (node.nodeType == Node.TEXT_NODE or
98 node.nodeType == Node.COMMENT_NODE):
99 continue
100 if node.nodeName == 'manager':
101 self.manager = self.parseManager(node)
102 elif node.nodeName == 'authentication':
103 self.authentication = self.parseAuthentication(node)
104 elif node.nodeName == 'feederports':
105 self.feederports, self.randomFeederports = \
106 self.parseFeederports(node)
107 elif node.nodeName == 'debug':
108 self.fludebug = str(node.firstChild.nodeValue)
109 else:
110 raise ConfigError("unexpected node under '%s': %s" % (
111 root.nodeName, node.nodeName))
112
114
115
116
117
118
119
120 host = None
121 port = None
122 transport = None
123 for child in node.childNodes:
124 if (child.nodeType == Node.TEXT_NODE or
125 child.nodeType == Node.COMMENT_NODE):
126 continue
127
128 if child.nodeName == "host":
129 if child.firstChild:
130 host = str(child.firstChild.nodeValue)
131 else:
132 host = 'localhost'
133 elif child.nodeName == "port":
134 if not child.firstChild:
135 raise ConfigError("<port> value must not be empty")
136 try:
137 port = int(child.firstChild.nodeValue)
138 except ValueError:
139 raise ConfigError("<port> value must be an integer")
140 elif child.nodeName == "transport":
141 if not child.firstChild:
142 raise ConfigError("<transport> value must not be empty")
143 transport = str(child.firstChild.nodeValue)
144 if not transport in ('tcp', 'ssl'):
145 raise ConfigError("<transport> must be ssl or tcp")
146
147 else:
148 raise ConfigError("unexpected '%s' node: %s" % (
149 node.nodeName, child.nodeName))
150
151 return ConfigEntryManager(host, port, transport)
152
175
177 """
178 Returns a list of feeder ports to use (possibly empty),
179 and whether or not to use random feeder ports.
180
181 @rtype: (list, bool)
182 """
183
184
185
186
187
188
189 random = False
190 if node.hasAttribute('random'):
191 random = common.strToBool(node.getAttribute('random'))
192 ports = []
193 if not node.firstChild:
194 return (ports, random)
195 terms = str(node.firstChild.nodeValue).split(',')
196 for term in terms:
197 if '-' in term:
198 (lower, upper) = [int(x) for x in term.split('-')]
199 if lower > upper:
200 raise ConfigError("<feederports> has an invalid range: "
201 "%s > %s " % (lower, upper))
202 for port in range(lower, upper+1):
203 if port not in ports:
204 ports.append(port)
205 else:
206 port = int(term)
207 if port not in ports:
208 ports.append(port)
209 return (ports, random)
210