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 if 'slivers' not in data:
39 logger.log("codemux.GetSlivers: could not find the slivers keyin data (PLC connection down?) - IGNORED")
42 # Parse attributes and update dict of scripts
43 for sliver in data['slivers']:
44 for attribute in sliver['attributes']:
45 if attribute['tagname'] == 'codemux':
46 # add to conf. Attribute is [host, port]
47 parts = attribute['value'].split(",")
49 logger.log("codemux: attribute value (%s) for codemux not separated by comma. Skipping."%attribute['value'])
51 params = {'host': parts[0], 'port': parts[1]}
53 # Check to see if sliver is running. If not, continue
54 if vserver.VServer(sliver['name']).is_running():
55 # Check if new or needs updating
56 if (sliver['name'] not in slicesinconf.keys()) \
57 or (params not in slicesinconf.get(sliver['name'], [])):
58 logger.log("codemux: Updaiting slice %s using %s" % \
59 (sliver['name'], params['host']))
62 # Add to dict of codemuxslices. Make list to support more than one
63 # codemuxed host per slice.
64 codemuxslices.setdefault(sliver['name'],[])
65 codemuxslices[sliver['name']].append(params)
67 logger.log("codemux: sliver %s not running yet. Deferring."\
71 # Remove slices from conf that no longer have the attribute
72 for deadslice in Set(slicesinconf.keys()) - Set(codemuxslices.keys()):
73 # XXX Hack for root slice
74 if deadslice != "root":
75 logger.log("codemux: Removing %s" % deadslice)
78 if _writeconf: writeConf(sortDomains(codemuxslices))
79 # ensure the service is running
83 def writeConf(slivers, conf = CODEMUXCONF):
84 '''Write conf with default entry up top. Elements in [] should have lower order domain names first. Restart service.'''
86 # This needs to be the first entry...
88 f.write("* root 1080 %s\n" % Config().PLC_PLANETFLOW_HOST)
89 except AttributeError:
90 logger.log("codemux: Can't find PLC_CONFIG_HOST in config. Using PLC_API_HOST")
91 f.write("* root 1080 %s\n" % Config().PLC_API_HOST)
92 # Sort items for like domains
93 for mapping in slivers:
94 for (host, params) in mapping.iteritems():
95 if params['slice'] == "root": continue
96 f.write("%s %s %s\n" % (host, params['slice'], params['port']))
100 except: logger.log_exc()
103 def sortDomains(slivers):
104 '''Given a dict of {slice: {domainname, port}}, return array of slivers with lower order domains first'''
105 dnames = {} # {host: slice}
106 for (slice, params) in slivers.iteritems():
107 for mapping in params:
108 dnames[mapping['host']] = {"slice":slice, "port": mapping['port']}
109 hosts = dnames.keys()
111 hosts.sort(key=str.__len__)
114 # make list of slivers
116 for host in hosts: sortedslices.append({host: dnames[host]})
121 def parseConf(conf = CODEMUXCONF):
122 '''Parse the CODEMUXCONF and return dict of slices in conf. {slice: (host,port)}'''
123 slicesinconf = {} # default
126 for line in f.readlines():
127 if line.startswith("#") \
128 or (len(line.split()) > 4) \
129 or (len(line.split()) < 3):
131 (host, slice, port) = line.split()[:3]
132 logger.log("codemux: found %s in conf" % slice, 2)
133 slicesinconf.setdefault(slice, [])
134 slicesinconf[slice].append({"host": host, "port": port})
136 except IOError: logger.log_exc()
141 if len(os.popen("pidof codemux").readline().rstrip("\n")) > 0:
147 def restartService():
148 if not os.path.exists("/etc/init.d/codemux"): return
149 logger.log("codemux: Restarting codemux service")
151 logger.log_call("/etc/init.d/codemux","condrestart")
153 logger.log_call("/etc/init.d/codemux","restart")
157 if not os.path.exists("/etc/init.d/codemux"): return
159 logger.log("codemux: Starting codemux service")
160 logger.log_call("/etc/init.d/codemux", "start")
161 logger.log_call("/sbin/chkconfig", "codemux", "on")
165 if not os.path.exists("/etc/init.d/codemux"): return
167 logger.log("codemux: Stopping codemux service")
168 logger.log_call("/etc/init.d/codemux", "stop")
169 logger.log_call("/sbin/chkconfig", "codemux", "off")