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, config 
 31   
32 -class ConfigError(Exception):
33 pass
34
35 -class ConfigEntryManager:
36 "I represent a <manager> entry in a worker config file"
37 - def __init__(self, host, port, transport):
38 self.host = host 39 self.port = port 40 self.transport = transport
41
42 -class ConfigEntryAuthentication:
43 "I represent a <authentication> entry in a worker config file"
44 - def __init__(self, username, password):
45 self.username = username 46 self.password = password
47
48 -class WorkerConfigXML(log.Loggable):
49 logCategory = 'config' 50
51 - def __init__(self, filename, string=None):
52 self.name = None 53 self.manager = None 54 self.authentication = None 55 self.feederports = None 56 self.fludebug = None 57 self.randomFeederports = False 58 59 try: 60 if filename != None: 61 self.debug('Loading configuration file `%s\'' % filename) 62 self.doc = minidom.parse(filename) 63 else: 64 self.doc = minidom.parseString(string) 65 except expat.ExpatError, e: 66 raise ConfigError("XML parser error: %s" % e) 67 68 if filename != None: 69 self.path = os.path.split(filename)[0] 70 else: 71 self.path = None 72 73 self.parse()
74 75 # FIXME: privatize, called from __init__
76 - def parse(self):
77 # <worker name="default"> 78 # <manager> 79 # <authentication> 80 # ... 81 # </worker> 82 83 root = self.doc.documentElement 84 85 if not root.nodeName == 'worker': 86 raise ConfigError("unexpected root node': %s" % root.nodeName) 87 88 if root.hasAttribute('name'): 89 self.name = str(root.getAttribute('name')) 90 91 for node in root.childNodes: 92 if (node.nodeType == Node.TEXT_NODE or 93 node.nodeType == Node.COMMENT_NODE): 94 continue 95 if node.nodeName == 'manager': 96 self.manager = self.parseManager(node) 97 elif node.nodeName == 'authentication': 98 self.authentication = self.parseAuthentication(node) 99 elif node.nodeName == 'feederports': 100 self.feederports, self.randomFeederports = \ 101 self.parseFeederports(node) 102 elif node.nodeName == 'debug': 103 self.fludebug = str(node.firstChild.nodeValue) 104 else: 105 raise ConfigError("unexpected node under '%s': %s" % (root.nodeName, node.nodeName))
106
107 - def parseManager(self, node):
108 # <manager> 109 # <host>...</host> 110 # <port>...</port> 111 # <transport>...</transport> 112 # </manager> 113 114 host = None 115 port = None 116 transport = None 117 for child in node.childNodes: 118 if (child.nodeType == Node.TEXT_NODE or 119 child.nodeType == Node.COMMENT_NODE): 120 continue 121 122 if child.nodeName == "host": 123 if child.firstChild: 124 host = str(child.firstChild.nodeValue) 125 else: 126 host = 'localhost' 127 elif child.nodeName == "port": 128 try: 129 port = int(child.firstChild.nodeValue) 130 except ValueError: 131 raise ConfigError("<port> value must be an integer") 132 elif child.nodeName == "transport": 133 transport = str(child.firstChild.nodeValue) 134 if not transport in ('tcp', 'ssl'): 135 raise ConfigError("<transport> must be ssl or tcp") 136 137 else: 138 raise ConfigError("unexpected '%s' node: %s" % (node.nodeName, child.nodeName)) 139 140 return ConfigEntryManager(host, port, transport)
141
142 - def parseAuthentication(self, node):
143 # <authentication> 144 # <username>...</username> 145 # <password>...</password> 146 # </authentication> 147 148 username = None 149 password = None 150 for child in node.childNodes: 151 if (child.nodeType == Node.TEXT_NODE or 152 child.nodeType == Node.COMMENT_NODE): 153 continue 154 155 if child.nodeName == "username": 156 username = str(child.firstChild.nodeValue) 157 elif child.nodeName == "password": 158 password = str(child.firstChild.nodeValue) 159 else: 160 raise ConfigError("unexpected '%s' node: %s" % (node.nodeName, child.nodeName)) 161 162 return ConfigEntryAuthentication(username, password)
163
164 - def parseFeederports(self, node):
165 """ 166 Returns a list of feeder ports to use (possibly empty), 167 and whether or not to use random feeder ports. 168 169 @rtype: (list, bool) 170 """ 171 # returns a list of allowed port numbers 172 # port := int 173 # port-range := port "-" port 174 # port-term := port | port-range 175 # port-list := "" | port-term | port-term "," port-list 176 # <feederports>port-list</feederports> 177 random = False 178 if node.hasAttribute('random'): 179 random = node.getAttribute('random') in config.BOOL_TRUE_VALUES 180 ports = [] 181 if not node.firstChild: 182 return (ports, random) 183 terms = str(node.firstChild.nodeValue).split(',') 184 for term in terms: 185 if '-' in term: 186 (lower, upper) = [int(x) for x in term.split('-')] 187 for port in range(lower, upper+1): 188 if port not in ports: 189 ports.append(port) 190 else: 191 port = int(term) 192 if port not in ports: 193 ports.append(port) 194 return (ports, random)
195