1 """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."""
6 from config import Config
9 CODEMUXCONF="/etc/codemux/codemux.conf"
12 logger.log("codemux: plugin starting up...")
14 def GetSlivers(data, config, plc = None):
16 For each sliver with the codemux attribute, parse out "host,port"
17 and make entry in conf. Restart service after.
19 if 'OVERRIDES' in dir(config):
20 if config.OVERRIDES.get('codemux') == '-1':
21 logger.log("codemux: Disabled", 2)
25 logger.log("codemux: Starting.", 2)
26 # slices already in conf
27 slicesinconf = parseConf()
28 # slices that need to be written to the conf
31 # XXX Hack for planetflow
32 if slicesinconf.has_key("root"): _writeconf = False
33 else: _writeconf = True
35 # Parse attributes and update dict of scripts
36 if 'slivers' not in data:
37 logger.log_missing_data("codemux.GetSlivers", 'slivers')
39 for sliver in data['slivers']:
40 for attribute in sliver['attributes']:
41 if attribute['tagname'] == 'codemux':
42 # add to conf. Attribute is [host, port]
43 parts = attribute['value'].split(",")
45 logger.log("codemux: attribute value (%s) for codemux not separated by comma. Skipping."%attribute['value'])
51 params = {'host': parts[0], 'port': parts[1], 'ip': ip}
54 # Check to see if sliver is running. If not, continue
55 if slivermanager.is_running(sliver['name']):
56 # Check if new or needs updating
57 if (sliver['name'] not in slicesinconf.keys()) \
58 or (params not in slicesinconf.get(sliver['name'], [])):
59 logger.log("codemux: Updating slice %s using %s" % \
60 (sliver['name'], params['host']))
63 # Add to dict of codemuxslices. Make list to support more than one
64 # codemuxed host per slice.
65 codemuxslices.setdefault(sliver['name'],[])
66 codemuxslices[sliver['name']].append(params)
68 logger.log("codemux: sliver %s not running yet. Deferring."\
72 # Remove slices from conf that no longer have the attribute
73 for deadslice in set(slicesinconf.keys()) - set(codemuxslices.keys()):
74 # XXX Hack for root slice
75 if deadslice != "root":
76 logger.log("codemux: Removing %s" % deadslice)
79 if _writeconf: writeConf(sortDomains(codemuxslices))
80 # ensure the service is running
84 def writeConf(slivers, conf = CODEMUXCONF):
85 '''Write conf with default entry up top. Elements in [] should have lower order domain names first. Restart service.'''
87 # This needs to be the first entry...
89 f.write("* root 1080 %s\n" % Config().PLC_PLANETFLOW_HOST)
90 except AttributeError:
91 logger.log("codemux: Can't find PLC_CONFIG_HOST in config. Using PLC_API_HOST")
92 f.write("* root 1080 %s\n" % Config().PLC_API_HOST)
93 # Sort items for like domains
94 for mapping in slivers:
95 for (host, params) in mapping.iteritems():
96 if params['slice'] == "root": continue
97 f.write("%s %s %s %s\n" % (host, params['slice'], params['port'], params['ip']))
100 try: restartService()
101 except: logger.log_exc("codemux.writeConf failed to restart service")
104 def sortDomains(slivers):
105 '''Given a dict of {slice: {domainname, port}}, return array of slivers with lower order domains first'''
106 dnames = {} # {host: slice}
107 for (slice, params) in slivers.iteritems():
108 for mapping in params:
109 dnames[mapping['host']] = {"slice":slice, "port": mapping['port'], "ip": mapping['ip']}
110 hosts = dnames.keys()
112 hosts.sort(key=str.__len__)
115 # make list of slivers
117 for host in hosts: sortedslices.append({host: dnames[host]})
122 def parseConf(conf = CODEMUXCONF):
123 '''Parse the CODEMUXCONF and return dict of slices in conf. {slice: (host,port)}'''
124 slicesinconf = {} # default
127 for line in f.readlines():
129 if line.startswith("#") or (len(parts) > 4) or (len(parts) < 3):
132 (host, slice, port, ip) = parts
133 logger.log("codemux: found %s in conf" % slice, 2)
134 slicesinconf.setdefault(slice, [])
135 slicesinconf[slice].append({"host": host, "port": port, "ip": ip})
137 (host, slice, port) = parts[:3]
138 logger.log("codemux: found %s in conf" % slice, 2)
139 slicesinconf.setdefault(slice, [])
140 slicesinconf[slice].append({"host": host, "port": port})
142 except IOError: logger.log_exc("codemux.parseConf got IOError")
147 if len(os.popen("pidof codemux").readline().rstrip("\n")) > 0:
152 def restartService():
153 if not os.path.exists("/etc/init.d/codemux"): return
154 logger.log("codemux: Restarting codemux service")
156 logger.log_call(["/etc/init.d/codemux","condrestart", ])
158 logger.log_call(["/etc/init.d/codemux","restart", ])
161 if not os.path.exists("/etc/init.d/codemux"): return
163 logger.log("codemux: Starting codemux service")
164 logger.log_call(["/etc/init.d/codemux", "start", ])
165 logger.log_call(["/sbin/chkconfig", "codemux", "on"])
169 if not os.path.exists("/etc/init.d/codemux"): return
171 logger.log("codemux: Stopping codemux service")
172 logger.log_call(["/etc/init.d/codemux", "stop", ])
173 logger.log_call(["/sbin/chkconfig", "codemux", "off"])