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):
19 """For each sliver with the codemux attribute, parse out "host,port" and make entry in conf. Restart service after."""
20 logger.log("codemux: Starting.", 2)
21 # slices already in conf
22 slicesinconf = parseConf()
23 # slices that need to be written to the conf
26 # XXX Hack for planetflow
27 if slicesinconf.has_key("root"): _writeconf = False
28 else: _writeconf = True
30 # Parse attributes and update dict of scripts
31 for sliver in data['slivers']:
32 for attribute in sliver['attributes']:
33 if attribute['name'] == 'codemux':
34 # add to conf. Attribute is [host, port]
35 [host, port] = attribute['value'].split(",")
37 # Check to see if sliver is running. If not, continue
38 if vserver.VServer(sliver['name']).is_running():
39 # Add to dict of codemuxslices
40 codemuxslices[sliver['name']] = {'host': host, 'port': port}
42 if sliver['name'] not in slicesinconf.keys():
43 logger.log("codemux: New slice %s using %s" % \
44 (sliver['name'], host))
47 # Check old slivers for changes
49 # Get info about slice in conf
50 sliverinconf = slicesinconf[sliver['name']]
51 # Check values for changes.
52 if (sliverinconf['host'] != host) or \
53 (sliverinconf['port'] != port):
54 logger.log("codemux: Updating slice %s" % sliver['name'])
56 codemuxslices[sliver['name']] = {'host': host, 'port': port}
60 logger.log("codemux: sliver %s not running yet. Deferring."\
63 logger.log_exc(name = "codemux")
66 # Remove slices from conf that no longer have the attribute
67 for deadslice in Set(slicesinconf.keys()) - Set(codemuxslices.keys()):
68 # XXX Hack for root slice
69 if deadslice != "root":
70 logger.log("codemux: Removing %s" % deadslice)
73 if _writeconf: writeConf(codemuxslices)
75 def writeConf(slivers, conf = CODEMUXCONF):
76 '''Write conf with default entry up top. Write lower order domain names first. Restart service.'''
78 # This needs to be the first entry...
79 f.write("* root %s\n", Config().PLC_PLANETFLOW_HOST)
80 # Sort items for like domains
81 for slice in sortDomains(slivers):
82 if slice == "root": continue
83 f.write("%s %s %s\n" % (slivers[slice]['host'], slice, slivers[slice]['port']))
87 except: logger.log_exc()
89 def sortDomains(slivers):
90 '''Given a dict of {slice: {domainname, port}}, return array of slivers with lower order domains first'''
91 dnames = {} # {host: slice}
92 for (slice,params) in slivers.iteritems():
93 dnames[params['host']] = slice
96 hosts.sort(key=str.__len__)
99 # make list of slivers
101 for host in hosts: sortedslices.append(dnames[host])
105 def parseConf(conf = CODEMUXCONF):
106 '''Parse the CODEMUXCONF and return dict of slices in conf. {slice: (host,port)}'''
107 slicesinconf = {} # default
110 for line in f.readlines():
111 if line.startswith("#") or (len(line.split()) != 3):
113 (host, slice, port) = line.split()[:3]
114 logger.log("codemux: found %s in conf" % slice, 2)
115 slicesinconf[slice] = {"host": host, "port": port}
117 except IOError: logger.log_exc()
120 def restartService():
121 logger.log("codemux: Restarting codemux service")
122 os.system("/etc/init.d/codemux stop")
123 f = os.popen("/sbin/pidof codemux")
127 pids = tmp[0].rstrip("\n").split()
129 logger.log("codemux: Killing stalled pid %s" % pid, 2)
131 os.system("/etc/init.d/codemux start")