3 Monitors slice attributes and configures CoDemux to mux port 80 based on HOST field in HTTP request.
4 Forwards to localhost port belonging to configured slice.
8 # in November 2015 it was established that this plugin is the culprit
9 # for our long standing slice re-creation issue
10 # for this reason this is now turned off on lxc-based hosts
11 # as per the spec file this plugin gets packaged as part of
12 # nodemanager-vs and not nodemanager-lib anymore
17 from config import Config
20 CODEMUXCONF="/etc/codemux/codemux.conf"
23 logger.log("codemux: plugin starting up...")
25 def GetSlivers(data, config, plc = None):
27 For each sliver with the codemux attribute, parse out "host,port"
28 and make entry in conf. Restart service after.
30 if 'OVERRIDES' in dir(config):
31 if config.OVERRIDES.get('codemux') == '-1':
32 logger.log("codemux: Disabled", 2)
36 logger.log("codemux: Starting.", 2)
37 # slices already in conf
38 slicesinconf = parseConf()
39 # slices that need to be written to the conf
42 # XXX Hack for planetflow
43 if "root" in slicesinconf:
48 # Parse attributes and update dict of scripts
49 if 'slivers' not in data:
50 logger.log_missing_data("codemux.GetSlivers", 'slivers')
52 for sliver in data['slivers']:
53 for attribute in sliver['attributes']:
54 if attribute['tagname'] == 'codemux':
55 # add to conf. Attribute is [host, port]
56 parts = attribute['value'].split(",")
58 logger.log("codemux: attribute value (%s) for codemux not separated by comma. Skipping."
65 params = {'host': parts[0], 'port': parts[1], 'ip': ip}
68 # Check to see if sliver is running. If not, continue
69 if slivermanager.is_running(sliver['name']):
70 # Check if new or needs updating
71 if (sliver['name'] not in list(slicesinconf.keys())) \
72 or (params not in slicesinconf.get(sliver['name'], [])):
73 logger.log("codemux: Updating slice %s using %s" % \
74 (sliver['name'], params['host']))
77 # Add to dict of codemuxslices. Make list to support more than one
78 # codemuxed host per slice.
79 codemuxslices.setdefault(sliver['name'], [])
80 codemuxslices[sliver['name']].append(params)
82 logger.log("codemux: sliver %s not running yet. Deferring."
86 # Remove slices from conf that no longer have the attribute
87 for deadslice in set(slicesinconf.keys()) - set(codemuxslices.keys()):
88 # XXX Hack for root slice
89 if deadslice != "root":
90 logger.log("codemux: Removing %s" % deadslice)
94 writeConf(sortDomains(codemuxslices))
95 # ensure the service is running
99 def writeConf(slivers, conf = CODEMUXCONF):
100 '''Write conf with default entry up top. Elements in [] should have lower order domain names first. Restart service.'''
102 # This needs to be the first entry...
104 f.write("* root 1080 %s\n" % Config().PLC_PLANETFLOW_HOST)
105 except AttributeError:
106 logger.log("codemux: Can't find PLC_CONFIG_HOST in config. Using PLC_API_HOST")
107 f.write("* root 1080 %s\n" % Config().PLC_API_HOST)
108 # Sort items for like domains
109 for mapping in slivers:
110 for (host, params) in mapping.items():
111 if params['slice'] == "root": continue
112 f.write("%s %s %s %s\n" % (host, params['slice'], params['port'], params['ip']))
118 logger.log_exc("codemux.writeConf failed to restart service")
121 def sortDomains(slivers):
122 '''Given a dict of {slice: {domainname, port}}, return array of slivers with lower order domains first'''
123 dnames = {} # {host: slice}
124 for (slice, params) in slivers.items():
125 for mapping in params:
126 dnames[mapping['host']] = {"slice":slice, "port": mapping['port'], "ip": mapping['ip']}
127 hosts = list(dnames.keys())
129 hosts.sort(key=str.__len__)
132 # make list of slivers
135 sortedslices.append({host: dnames[host]})
140 def parseConf(conf = CODEMUXCONF):
141 '''Parse the CODEMUXCONF and return dict of slices in conf. {slice: (host,port)}'''
142 slicesinconf = {} # default
145 for line in f.readlines():
147 if line.startswith("#") or (len(parts) > 4) or (len(parts) < 3):
150 (host, slice, port, ip) = parts
151 logger.log("codemux: found %s in conf" % slice, 2)
152 slicesinconf.setdefault(slice, [])
153 slicesinconf[slice].append({"host": host, "port": port, "ip": ip})
155 (host, slice, port) = parts[:3]
156 logger.log("codemux: found %s in conf" % slice, 2)
157 slicesinconf.setdefault(slice, [])
158 slicesinconf[slice].append({"host": host, "port": port})
160 except IOError: logger.log_exc("codemux.parseConf got IOError")
165 if len(os.popen("pidof codemux").readline().rstrip("\n")) > 0:
170 def restartService():
171 if not os.path.exists("/etc/init.d/codemux"): return
172 logger.log("codemux: Restarting codemux service")
174 logger.log_call(["/etc/init.d/codemux", "condrestart", ])
176 logger.log_call(["/etc/init.d/codemux", "restart", ])
179 if not os.path.exists("/etc/init.d/codemux"): return
181 logger.log("codemux: Starting codemux service")
182 logger.log_call(["/etc/init.d/codemux", "start", ])
183 logger.log_call(["/sbin/chkconfig", "codemux", "on"])
187 if not os.path.exists("/etc/init.d/codemux"): return
189 logger.log("codemux: Stopping codemux service")
190 logger.log_call(["/etc/init.d/codemux", "stop", ])
191 logger.log_call(["/sbin/chkconfig", "codemux", "off"])