Package flumotion :: Package worker :: Module config
[hide private]

Source Code for Module flumotion.worker.config

  1  # -*- Mode: Python; test-case-name:flumotion.test.test_workerconfig -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3  # 
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007 Fluendo, S.L. (www.fluendo.com). 
  6  # All rights reserved. 
  7   
  8  # This file may be distributed and/or modified under the terms of 
  9  # the GNU General Public License version 2 as published by 
 10  # the Free Software Foundation. 
 11  # This file is distributed without any warranty; without even the implied 
 12  # warranty of merchantability or fitness for a particular purpose. 
 13  # See "LICENSE.GPL" in the source distribution for more information. 
 14   
 15  # Licensees having purchased or holding a valid Flumotion Advanced 
 16  # Streaming Server license may use this file in accordance with the 
 17  # Flumotion Advanced Streaming Server Commercial License Agreement. 
 18  # See "LICENSE.Flumotion" in the source distribution for more information. 
 19   
 20  # Headers in this file shall remain intact. 
 21   
 22  """ 
 23  Parsing of configuration files. 
 24  """ 
 25   
 26  import os 
 27  from xml.dom import minidom, Node 
 28  from xml.parsers import expat 
 29   
 30  from flumotion.common import log, common 
 31   
 32  __version__ = "$Rev: 7978 $" 
 33   
 34   
35 -class ConfigError(Exception):
36 pass
37 38
39 -class ConfigEntryManager:
40 "I represent a <manager> entry in a worker config file" 41
42 - def __init__(self, host, port, transport):
43 self.host = host 44 self.port = port 45 self.transport = transport
46 47
48 -class ConfigEntryAuthentication:
49 "I represent a <authentication> entry in a worker config file" 50
51 - def __init__(self, username, password):
52 self.username = username 53 self.password = password
54 55
56 -class WorkerConfigXML(log.Loggable):
57 logCategory = 'config' 58
59 - def __init__(self, filename, string=None):
60 self.name = None 61 self.manager = None 62 self.authentication = None 63 self.feederports = None 64 self.fludebug = None 65 self.randomFeederports = False 66 67 try: 68 if filename != None: 69 self.debug('Loading configuration file `%s\'' % filename) 70 self.doc = minidom.parse(filename) 71 else: 72 self.doc = minidom.parseString(string) 73 except expat.ExpatError, e: 74 raise ConfigError("XML parser error: %s" % e) 75 76 if filename != None: 77 self.path = os.path.split(filename)[0] 78 else: 79 self.path = None 80 81 self.parse()
82 83 # FIXME: privatize, called from __init__ 84
85 - def parse(self):
86 # <worker name="default"> 87 # <manager> 88 # <authentication> 89 # ... 90 # </worker> 91 92 root = self.doc.documentElement 93 94 if not root.nodeName == 'worker': 95 raise ConfigError("unexpected root node': %s" % root.nodeName) 96 97 if root.hasAttribute('name'): 98 self.name = str(root.getAttribute('name')) 99 100 for node in root.childNodes: 101 if (node.nodeType == Node.TEXT_NODE or 102 node.nodeType == Node.COMMENT_NODE): 103 continue 104 if node.nodeName == 'manager': 105 self.manager = self.parseManager(node) 106 elif node.nodeName == 'authentication': 107 self.authentication = self.parseAuthentication(node) 108 elif node.nodeName == 'feederports': 109 self.feederports, self.randomFeederports = \ 110 self.parseFeederports(node) 111 elif node.nodeName == 'debug': 112 self.fludebug = str(node.firstChild.nodeValue) 113 else: 114 raise ConfigError("unexpected node under '%s': %s" % ( 115 root.nodeName, node.nodeName))
116
117 - def parseManager(self, node):
118 # <manager> 119 # <host>...</host> 120 # <port>...</port> 121 # <transport>...</transport> 122 # </manager> 123 124 host = None 125 port = None 126 transport = None 127 for child in node.childNodes: 128 if (child.nodeType == Node.TEXT_NODE or 129 child.nodeType == Node.COMMENT_NODE): 130 continue 131 132 if child.nodeName == "host": 133 if child.firstChild: 134 host = str(child.firstChild.nodeValue) 135 else: 136 host = 'localhost' 137 elif child.nodeName == "port": 138 if not child.firstChild: 139 raise ConfigError("<port> value must not be empty") 140 try: 141 port = int(child.firstChild.nodeValue) 142 except ValueError: 143 raise ConfigError("<port> value must be an integer") 144 elif child.nodeName == "transport": 145 if not child.firstChild: 146 raise ConfigError("<transport> value must not be empty") 147 transport = str(child.firstChild.nodeValue) 148 if not transport in ('tcp', 'ssl'): 149 raise ConfigError("<transport> must be ssl or tcp") 150 151 else: 152 raise ConfigError("unexpected '%s' node: %s" % ( 153 node.nodeName, child.nodeName)) 154 155 return ConfigEntryManager(host, port, transport)
156
157 - def parseAuthentication(self, node):
158 # <authentication> 159 # <username>...</username> 160 # <password>...</password> 161 # </authentication> 162 163 username = None 164 password = None 165 for child in node.childNodes: 166 if (child.nodeType == Node.TEXT_NODE or 167 child.nodeType == Node.COMMENT_NODE): 168 continue 169 170 if child.nodeName == "username": 171 username = str(child.firstChild.nodeValue) 172 elif child.nodeName == "password": 173 password = str(child.firstChild.nodeValue) 174 else: 175 raise ConfigError("unexpected '%s' node: %s" % ( 176 node.nodeName, child.nodeName)) 177 178 return ConfigEntryAuthentication(username, password)
179
180 - def parseFeederports(self, node):
181 """ 182 Returns a list of feeder ports to use (possibly empty), 183 and whether or not to use random feeder ports. 184 185 @rtype: (list, bool) 186 """ 187 # returns a list of allowed port numbers 188 # port := int 189 # port-range := port "-" port 190 # port-term := port | port-range 191 # port-list := "" | port-term | port-term "," port-list 192 # <feederports>port-list</feederports> 193 random = False 194 if node.hasAttribute('random'): 195 random = common.strToBool(node.getAttribute('random')) 196 ports = [] 197 if not node.firstChild: 198 return (ports, random) 199 terms = str(node.firstChild.nodeValue).split(',') 200 for term in terms: 201 if '-' in term: 202 (lower, upper) = [int(x) for x in term.split('-')] 203 for port in range(lower, upper+1): 204 if port not in ports: 205 ports.append(port) 206 else: 207 port = int(term) 208 if port not in ports: 209 ports.append(port) 210 return (ports, random)
211