4 """Codemux configurator. Monitors slice attributes and configures CoDemux to mux port 80 based on HOST field in HTTP request. Forwards to localhost port belonging to configured slice."""
10 from config import Config
12 CODEMUXCONF="/etc/codemux/codemux.conf"
14 def start(options, config):
18 def GetSlivers(data, plc = None, config = None):
20 For each sliver with the codemux attribute, parse out "host,port"
21 and make entry in conf. Restart service after.
23 if 'OVERRIDES' in dir(config):
24 if config.OVERRIDES.get('codemux') == '-1':
25 logger.log("codemux: Disabled", 2)
29 logger.log("codemux: Starting.", 2)
30 # slices already in conf
31 slicesinconf = parseConf()
32 # slices that need to be written to the conf
35 # XXX Hack for planetflow
36 if slicesinconf.has_key("root"): _writeconf = False
37 else: _writeconf = True
39 # Parse attributes and update dict of scripts
40 for sliver in data['slivers']:
41 for attribute in sliver['attributes']:
42 if attribute['tagname'] == 'codemux':
43 # add to conf. Attribute is [host, port]
44 params = {'host': attribute['value'].split(",")[0],
45 'port': attribute['value'].split(",")[1]}
47 # Check to see if sliver is running. If not, continue
48 if vserver.VServer(sliver['name']).is_running():
49 # Check if new or needs updating
50 if (sliver['name'] not in slicesinconf.keys()) \
51 or (params not in slicesinconf.get(sliver['name'], [])):
52 logger.log("codemux: Updaiting slice %s using %s" % \
53 (sliver['name'], params['host']))
56 # Add to dict of codemuxslices. Make list to support more than one
57 # codemuxed host per slice.
58 codemuxslices.setdefault(sliver['name'],[])
59 codemuxslices[sliver['name']].append(params)
61 logger.log("codemux: sliver %s not running yet. Deferring."\
65 # Remove slices from conf that no longer have the attribute
66 for deadslice in Set(slicesinconf.keys()) - Set(codemuxslices.keys()):
67 # XXX Hack for root slice
68 if deadslice != "root":
69 logger.log("codemux: Removing %s" % deadslice)
72 if _writeconf: writeConf(sortDomains(codemuxslices))
73 # ensure the service is running
77 def writeConf(slivers, conf = CODEMUXCONF):
78 '''Write conf with default entry up top. Elements in [] should have lower order domain names first. Restart service.'''
80 # This needs to be the first entry...
82 f.write("* root 1080 %s\n" % Config().PLC_PLANETFLOW_HOST)
83 except AttributeError:
84 logger.log("codemux: Can't find PLC_CONFIG_HOST in config. Using PLC_API_HOST")
85 f.write("* root 1080 %s\n" % Config().PLC_API_HOST)
86 # Sort items for like domains
87 for mapping in slivers:
88 for (host, params) in mapping.iteritems():
89 if params['slice'] == "root": continue
90 f.write("%s %s %s\n" % (host, params['slice'], params['port']))
94 except: logger.log_exc()
97 def sortDomains(slivers):
98 '''Given a dict of {slice: {domainname, port}}, return array of slivers with lower order domains first'''
99 dnames = {} # {host: slice}
100 for (slice, params) in slivers.iteritems():
101 for mapping in params:
102 dnames[mapping['host']] = {"slice":slice, "port": mapping['port']}
103 hosts = dnames.keys()
105 hosts.sort(key=str.__len__)
108 # make list of slivers
110 for host in hosts: sortedslices.append({host: dnames[host]})
115 def parseConf(conf = CODEMUXCONF):
116 '''Parse the CODEMUXCONF and return dict of slices in conf. {slice: (host,port)}'''
117 slicesinconf = {} # default
120 for line in f.readlines():
121 if line.startswith("#") \
122 or (len(line.split()) > 4) \
123 or (len(line.split()) < 3):
125 (host, slice, port) = line.split()[:3]
126 logger.log("codemux: found %s in conf" % slice, 2)
127 slicesinconf.setdefault(slice, [])
128 slicesinconf[slice].append({"host": host, "port": port})
130 except IOError: logger.log_exc()
135 if len(os.popen("pidof codemux").readline().rstrip("\n")) > 0:
141 def restartService():
142 logger.log("codemux: Restarting codemux service")
144 logger.log_call("/etc/init.d/codemux","condrestart")
146 logger.log_call("/etc/init.d/codemux","restart")
151 logger.log("codemux: Starting codemux service")
152 logger.log_call("/etc/init.d/codemux", "start")
157 logger.log("codemux: Stopping codemux service")
158 logger.log_call("/etc/init.d/codemux", "stop")