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,2008,2009 Fluendo, S.L. 
  6  # Copyright (C) 2010,2011 Flumotion Services, S.A. 
  7  # All rights reserved. 
  8  # 
  9  # This file may be distributed and/or modified under the terms of 
 10  # the GNU Lesser General Public License version 2.1 as published by 
 11  # the Free Software Foundation. 
 12  # This file is distributed without any warranty; without even the implied 
 13  # warranty of merchantability or fitness for a particular purpose. 
 14  # See "LICENSE.LGPL" in the source distribution for more information. 
 15  # 
 16  # Headers in this file shall remain intact. 
 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   
31 -class ConfigError(Exception):
32 pass
33 34
35 -class ConfigEntryManager:
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
44 -class ConfigEntryAuthentication:
45 "I represent a <authentication> entry in a worker config file" 46
47 - def __init__(self, username, password):
48 self.username = username 49 self.password = password
50 51
52 -class WorkerConfigXML(log.Loggable):
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 # FIXME: privatize, called from __init__ 80
81 - def parse(self):
82 # <worker name="default"> 83 # <manager> 84 # <authentication> 85 # ... 86 # </worker> 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
113 - def parseManager(self, node):
114 # <manager> 115 # <host>...</host> 116 # <port>...</port> 117 # <transport>...</transport> 118 # </manager> 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
153 - def parseAuthentication(self, node):
154 # <authentication> 155 # <username>...</username> 156 # <password>...</password> 157 # </authentication> 158 159 username = None 160 password = None 161 for child in node.childNodes: 162 if (child.nodeType == Node.TEXT_NODE or 163 child.nodeType == Node.COMMENT_NODE): 164 continue 165 166 if child.nodeName == "username": 167 username = str(child.firstChild.nodeValue) 168 elif child.nodeName == "password": 169 password = str(child.firstChild.nodeValue) 170 else: 171 raise ConfigError("unexpected '%s' node: %s" % ( 172 node.nodeName, child.nodeName)) 173 174 return ConfigEntryAuthentication(username, password)
175
176 - def parseFeederports(self, node):
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 # returns a list of allowed port numbers 184 # port := int 185 # port-range := port "-" port 186 # port-term := port | port-range 187 # port-list := "" | port-term | port-term "," port-list 188 # <feederports>port-list</feederports> 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