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."""
9 from config import Config
11 CODEMUXCONF="/etc/codemux/codemux.conf"
14 logger.log("codemux: plugin starting up...")
16 def GetSlivers(data, config, plc = None):
18 For each sliver with the codemux attribute, parse out "host,port"
19 and make entry in conf. Restart service after.
21 if 'OVERRIDES' in dir(config):
22 if config.OVERRIDES.get('codemux') == '-1':
23 logger.log("codemux: Disabled", 2)
27 logger.log("codemux: Starting.", 2)
28 # slices already in conf
29 slicesinconf = parseConf()
30 # slices that need to be written to the conf
33 # XXX Hack for planetflow
34 if slicesinconf.has_key("root"): _writeconf = False
35 else: _writeconf = True
37 # Parse attributes and update dict of scripts
38 if 'slivers' not in data:
39 logger.log_missing_data("codemux.GetSlivers", 'slivers')
41 for sliver in data['slivers']:
42 for attribute in sliver['attributes']:
43 if attribute['tagname'] == 'codemux':
44 # add to conf. Attribute is [host, port]
45 parts = attribute['value'].split(",")
47 logger.log("codemux: attribute value (%s) for codemux not separated by comma. Skipping."%attribute['value'])
53 params = {'host': parts[0], 'port': parts[1], 'ip': ip}
56 # Check to see if sliver is running. If not, continue
57 if isLXCDomRunning(sliver['name']):
58 # Check if new or needs updating
59 if (sliver['name'] not in slicesinconf.keys()) \
60 or (params not in slicesinconf.get(sliver['name'], [])):
61 logger.log("codemux: Updating slice %s using %s" % \
62 (sliver['name'], params['host']))
65 # Add to dict of codemuxslices. Make list to support more than one
66 # codemuxed host per slice.
67 codemuxslices.setdefault(sliver['name'],[])
68 codemuxslices[sliver['name']].append(params)
70 logger.log("codemux: sliver %s not running yet. Deferring."\
74 # Remove slices from conf that no longer have the attribute
75 for deadslice in set(slicesinconf.keys()) - set(codemuxslices.keys()):
76 # XXX Hack for root slice
77 if deadslice != "root":
78 logger.log("codemux: Removing %s" % deadslice)
81 if _writeconf: writeConf(sortDomains(codemuxslices))
82 # ensure the service is running
86 def writeConf(slivers, conf = CODEMUXCONF):
87 '''Write conf with default entry up top. Elements in [] should have lower order domain names first. Restart service.'''
89 # This needs to be the first entry...
91 f.write("* root 1080 %s\n" % Config().PLC_PLANETFLOW_HOST)
92 except AttributeError:
93 logger.log("codemux: Can't find PLC_CONFIG_HOST in config. Using PLC_API_HOST")
94 f.write("* root 1080 %s\n" % Config().PLC_API_HOST)
95 # Sort items for like domains
96 for mapping in slivers:
97 for (host, params) in mapping.iteritems():
98 if params['slice'] == "root": continue
99 f.write("%s %s %s %s\n" % (host, params['slice'], params['port'], params['ip']))
102 try: restartService()
103 except: logger.log_exc("codemux.writeConf failed to restart service")
106 def sortDomains(slivers):
107 '''Given a dict of {slice: {domainname, port}}, return array of slivers with lower order domains first'''
108 dnames = {} # {host: slice}
109 for (slice, params) in slivers.iteritems():
110 for mapping in params:
111 dnames[mapping['host']] = {"slice":slice, "port": mapping['port'], "ip": mapping['ip']}
112 hosts = dnames.keys()
114 hosts.sort(key=str.__len__)
117 # make list of slivers
119 for host in hosts: sortedslices.append({host: dnames[host]})
124 def parseConf(conf = CODEMUXCONF):
125 '''Parse the CODEMUXCONF and return dict of slices in conf. {slice: (host,port)}'''
126 slicesinconf = {} # default
129 for line in f.readlines():
130 if line.startswith("#") \
131 or (len(line.split()) > 4) \
132 or (len(line.split()) < 3):
134 (host, slice, port) = line.split()[:3]
135 logger.log("codemux: found %s in conf" % slice, 2)
136 slicesinconf.setdefault(slice, [])
137 slicesinconf[slice].append({"host": host, "port": port})
139 except IOError: logger.log_exc("codemux.parseConf got IOError")
144 if len(os.popen("pidof codemux").readline().rstrip("\n")) > 0:
149 def restartService():
150 if not os.path.exists("/etc/init.d/codemux"): return
151 logger.log("codemux: Restarting codemux service")
153 logger.log_call(["/etc/init.d/codemux","condrestart", ])
155 logger.log_call(["/etc/init.d/codemux","restart", ])
158 if not os.path.exists("/etc/init.d/codemux"): return
160 logger.log("codemux: Starting codemux service")
161 logger.log_call(["/etc/init.d/codemux", "start", ])
162 logger.log_call(["/sbin/chkconfig", "codemux", "on"])
166 if not os.path.exists("/etc/init.d/codemux"): return
168 logger.log("codemux: Stopping codemux service")
169 logger.log_call(["/etc/init.d/codemux", "stop", ])
170 logger.log_call(["/sbin/chkconfig", "codemux", "off"])
172 def isLXCDomRunning(domName):
175 conn = libvirt.open('lxc://')
176 dom = conn.lookupByName(domName)
177 running = dom.info()[0] == libvirt.VIR_DOMAIN_RUNNING