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, conf):
15 logger.log("codemux: plugin starting up...")
17 def GetSlivers(data, config, plc = None):
19 For each sliver with the codemux attribute, parse out "host,port"
20 and make entry in conf. Restart service after.
22 if 'OVERRIDES' in dir(config):
23 if config.OVERRIDES.get('codemux') == '-1':
24 logger.log("codemux: Disabled", 2)
28 logger.log("codemux: Starting.", 2)
29 # slices already in conf
30 slicesinconf = parseConf()
31 # slices that need to be written to the conf
34 # XXX Hack for planetflow
35 if slicesinconf.has_key("root"): _writeconf = False
36 else: _writeconf = True
38 # Parse attributes and update dict of scripts
39 if 'slivers' not in data:
40 logger.log_missing_data("codemux.GetSlivers", 'slivers')
42 for sliver in data['slivers']:
43 for attribute in sliver['attributes']:
44 if attribute['tagname'] == 'codemux':
45 # add to conf. Attribute is [host, port]
46 parts = attribute['value'].split(",")
48 logger.log("codemux: attribute value (%s) for codemux not separated by comma. Skipping."%attribute['value'])
54 params = {'host': parts[0], 'port': parts[1], 'ip': ip}
57 # Check to see if sliver is running. If not, continue
58 if vserver.VServer(sliver['name']).is_running():
59 # Check if new or needs updating
60 if (sliver['name'] not in slicesinconf.keys()) \
61 or (params not in slicesinconf.get(sliver['name'], [])):
62 logger.log("codemux: Updaiting slice %s using %s" % \
63 (sliver['name'], params['host']))
66 # Add to dict of codemuxslices. Make list to support more than one
67 # codemuxed host per slice.
68 codemuxslices.setdefault(sliver['name'],[])
69 codemuxslices[sliver['name']].append(params)
71 logger.log("codemux: sliver %s not running yet. Deferring."\
75 # Remove slices from conf that no longer have the attribute
76 for deadslice in Set(slicesinconf.keys()) - Set(codemuxslices.keys()):
77 # XXX Hack for root slice
78 if deadslice != "root":
79 logger.log("codemux: Removing %s" % deadslice)
82 if _writeconf: writeConf(sortDomains(codemuxslices))
83 # ensure the service is running
87 def writeConf(slivers, conf = CODEMUXCONF):
88 '''Write conf with default entry up top. Elements in [] should have lower order domain names first. Restart service.'''
90 # This needs to be the first entry...
92 f.write("* root 1080 %s\n" % Config().PLC_PLANETFLOW_HOST)
93 except AttributeError:
94 logger.log("codemux: Can't find PLC_CONFIG_HOST in config. Using PLC_API_HOST")
95 f.write("* root 1080 %s\n" % Config().PLC_API_HOST)
96 # Sort items for like domains
97 for mapping in slivers:
98 for (host, params) in mapping.iteritems():
99 if params['slice'] == "root": continue
100 f.write("%s %s %s %s\n" % (host, params['slice'], params['port'], params['ip']))
103 try: restartService()
104 except: logger.log_exc("codemux.writeConf failed to restart service")
107 def sortDomains(slivers):
108 '''Given a dict of {slice: {domainname, port}}, return array of slivers with lower order domains first'''
109 dnames = {} # {host: slice}
110 for (slice, params) in slivers.iteritems():
111 for mapping in params:
112 dnames[mapping['host']] = {"slice":slice, "port": mapping['port'], "ip": mapping['ip']}
113 hosts = dnames.keys()
115 hosts.sort(key=str.__len__)
118 # make list of slivers
120 for host in hosts: sortedslices.append({host: dnames[host]})
125 def parseConf(conf = CODEMUXCONF):
126 '''Parse the CODEMUXCONF and return dict of slices in conf. {slice: (host,port)}'''
127 slicesinconf = {} # default
130 for line in f.readlines():
131 if line.startswith("#") \
132 or (len(line.split()) > 4) \
133 or (len(line.split()) < 3):
135 (host, slice, port) = line.split()[:3]
136 logger.log("codemux: found %s in conf" % slice, 2)
137 slicesinconf.setdefault(slice, [])
138 slicesinconf[slice].append({"host": host, "port": port})
140 except IOError: logger.log_exc("codemux.parseConf got IOError")
145 if len(os.popen("pidof codemux").readline().rstrip("\n")) > 0:
150 def restartService():
151 if not os.path.exists("/etc/init.d/codemux"): return
152 logger.log("codemux: Restarting codemux service")
154 logger.log_call(["/etc/init.d/codemux","condrestart", ])
156 logger.log_call(["/etc/init.d/codemux","restart", ])
159 if not os.path.exists("/etc/init.d/codemux"): return
161 logger.log("codemux: Starting codemux service")
162 logger.log_call(["/etc/init.d/codemux", "start", ])
163 logger.log_call(["/sbin/chkconfig", "codemux", "on"])
167 if not os.path.exists("/etc/init.d/codemux"): return
169 logger.log("codemux: Stopping codemux service")
170 logger.log_call(["/etc/init.d/codemux", "stop", ])
171 logger.log_call(["/sbin/chkconfig", "codemux", "off"])