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):
20 For each sliver with the codemux attribute, parse out "host,port"
21 and make entry in conf. Restart service after.
23 logger.log("codemux: Starting.", 2)
24 # slices already in conf
25 slicesinconf = parseConf()
26 # slices that need to be written to the conf
29 # XXX Hack for planetflow
30 if slicesinconf.has_key("root"): _writeconf = False
31 else: _writeconf = True
33 # Parse attributes and update dict of scripts
34 for sliver in data['slivers']:
35 for attribute in sliver['attributes']:
36 if attribute['tagname'] == 'codemux':
37 # add to conf. Attribute is [host, port]
38 params = {'host': attribute['value'].split(",")[0],
39 'port': attribute['value'].split(",")[1]}
41 # Check to see if sliver is running. If not, continue
42 if vserver.VServer(sliver['name']).is_running():
43 # Check if new or needs updating
44 if (sliver['name'] not in slicesinconf.keys()) \
45 or (params not in slicesinconf.get(sliver['name'], [])):
46 logger.log("codemux: Updaiting slice %s using %s" % \
47 (sliver['name'], params['host']))
50 # Add to dict of codemuxslices. Make list to support more than one
51 # codemuxed host per slice.
52 codemuxslices.setdefault(sliver['name'],[])
53 codemuxslices[sliver['name']].append(params)
55 logger.log("codemux: sliver %s not running yet. Deferring."\
59 # Remove slices from conf that no longer have the attribute
60 for deadslice in Set(slicesinconf.keys()) - Set(codemuxslices.keys()):
61 # XXX Hack for root slice
62 if deadslice != "root":
63 logger.log("codemux: Removing %s" % deadslice)
66 if _writeconf: writeConf(sortDomains(codemuxslices))
68 def writeConf(slivers, conf = CODEMUXCONF):
69 '''Write conf with default entry up top. Elements in [] should have lower order domain names first. Restart service.'''
71 # This needs to be the first entry...
73 f.write("* root 1080 %s\n" % Config().PLC_PLANETFLOW_HOST)
74 except AttributeError:
75 logger.log("codemux: Can't find PLC_CONFIG_HOST in config. Using PLC_API_HOST")
76 f.write("* root 1080 %s\n" % Config().PLC_API_HOST)
77 # Sort items for like domains
78 for mapping in slivers:
79 for (host, params) in mapping.iteritems():
80 if params['slice'] == "root": continue
81 f.write("%s %s %s\n" % (host, params['slice'], params['port']))
85 except: logger.log_exc()
87 def sortDomains(slivers):
88 '''Given a dict of {slice: {domainname, port}}, return array of slivers with lower order domains first'''
89 dnames = {} # {host: slice}
90 for (slice, params) in slivers.iteritems():
91 for mapping in params:
92 dnames[mapping['host']] = {"slice":slice, "port": mapping['port']}
95 hosts.sort(key=str.__len__)
98 # make list of slivers
100 for host in hosts: sortedslices.append({host: dnames[host]})
104 def parseConf(conf = CODEMUXCONF):
105 '''Parse the CODEMUXCONF and return dict of slices in conf. {slice: (host,port)}'''
106 slicesinconf = {} # default
109 for line in f.readlines():
110 if line.startswith("#") \
111 or (len(line.split()) > 4) \
112 or (len(line.split()) < 3):
114 (host, slice, port) = line.split()[:3]
115 logger.log("codemux: found %s in conf" % slice, 2)
116 slicesinconf.setdefault(slice, [])
117 slicesinconf[slice].append({"host": host, "port": port})
119 except IOError: logger.log_exc()
122 def restartService():
123 logger.log("codemux: Restarting codemux service")
124 os.system("/etc/init.d/codemux stop")
125 f = os.popen("/sbin/pidof codemux")
129 pids = tmp[0].rstrip("\n").split()
131 logger.log("codemux: Killing stalled pid %s" % pid, 2)
133 os.system("/etc/init.d/codemux start")