X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=codemux.py;h=7b113504e43020a6408733c900f5a4f44e0d339c;hb=bdf20298cd1cd206cf8899f291f8a2d32f50bca4;hp=2dd23bf013eff32452158ca1e0b37e6700e6f6aa;hpb=294d455265671d437beda6acf08408d3b198c7b3;p=nodemanager.git diff --git a/codemux.py b/codemux.py index 2dd23bf..7b11350 100644 --- a/codemux.py +++ b/codemux.py @@ -7,6 +7,7 @@ import logger import os import vserver from sets import Set +from config import Config CODEMUXCONF="/etc/codemux/codemux.conf" @@ -16,65 +17,114 @@ def start(options, config): def GetSlivers(data): """For each sliver with the codemux attribute, parse out "host,port" and make entry in conf. Restart service after.""" + logger.log("codemux: Starting.", 2) # slices already in conf slicesinconf = parseConf() # slices that need to be written to the conf codemuxslices = {} - _writeconf = False + + # XXX Hack for planetflow + if slicesinconf.has_key("root"): _writeconf = False + else: _writeconf = True + # Parse attributes and update dict of scripts for sliver in data['slivers']: for attribute in sliver['attributes']: if attribute['name'] == 'codemux': # add to conf. Attribute is [host, port] - [host, port] = attribute['value'].split() + params = {'host': attribute['value'].split(",")[0], + 'port': attribute['value'].split(",")[1]} try: # Check to see if sliver is running. If not, continue if vserver.VServer(sliver['name']).is_running(): - # Check for new - if sliver['name'] not in slicesinconf.keys(): - logger.log("codemux: New slice %s using %s" % \ - (sliver['name'], host)) - codemuxslices[sliver['name']] = {'host': host, 'port': port} + # Check if new or needs updating + if (sliver['name'] not in slicesinconf.keys()) \ + or (params not in slicesinconf.get(sliver['name'], [])): + logger.log("codemux: Updaiting slice %s using %s" % \ + (sliver['name'], params['host'])) + # Toggle write. _writeconf = True - # Check old slivers for changes - else: - sliverinconf = slicesinconf[sliver['name']] - if (sliverinconf['host'] != host) or \ - (sliverinconf['port'] != port): - logger.log("codemux: Updating slice %s" % sliver['name']) - _writeconf = True - codemuxslices[sliver['name']] = {'host': host, 'port': port} + # Add to dict of codemuxslices. Make list to support more than one + # codemuxed host per slice. + codemuxslices.setdefault(sliver['name'],[]) + codemuxslices[sliver['name']].append(params) except: logger.log("codemux: sliver %s not running yet. Deferring."\ % sliver['name']) pass - if _writeconf: writeConf(codemuxslices) + # Remove slices from conf that no longer have the attribute + for deadslice in Set(slicesinconf.keys()) - Set(codemuxslices.keys()): + # XXX Hack for root slice + if deadslice != "root": + logger.log("codemux: Removing %s" % deadslice) + _writeconf = True + + if _writeconf: writeConf(sortDomains(codemuxslices)) def writeConf(slivers, conf = CODEMUXCONF): - '''Write conf with default entry up top. Restart service.''' - f.open(conf) - f.write("* root 1080") - for (host, slice, port) in slivers.iteritems(): - f.write("%s %s %s" % [host, slice, port]) + '''Write conf with default entry up top. Elements in [] should have lower order domain names first. Restart service.''' + f = open(conf, "w") + # This needs to be the first entry... + try: + f.write("* root 1080 %s\n" % Config().PLC_PLANETFLOW_HOST) + except AttributeError: + logger.log("codemux: Can't find PLC_CONFIG_HOST in config. Using PLC_API_HOST") + f.write("* root 1080 %s\n" % Config().PLC_API_HOST) + # Sort items for like domains + for mapping in slivers: + for (host, params) in mapping.iteritems(): + if params['slice'] == "root": continue + f.write("%s %s %s\n" % (host, params['slice'], params['port'])) f.truncate() f.close() - logger.log("codemux: restarting codemux service") - os.system("/etc/init.d/codemux restart") - + try: restartService() + except: logger.log_exc() +def sortDomains(slivers): + '''Given a dict of {slice: {domainname, port}}, return array of slivers with lower order domains first''' + dnames = {} # {host: slice} + for (slice, params) in slivers.iteritems(): + for mapping in params: + dnames[mapping['host']] = {"slice":slice, "port": mapping['port']} + hosts = dnames.keys() + # sort by length + hosts.sort(key=str.__len__) + # longer first + hosts.reverse() + # make list of slivers + sortedslices = [] + for host in hosts: sortedslices.append({host: dnames[host]}) + + return sortedslices + def parseConf(conf = CODEMUXCONF): '''Parse the CODEMUXCONF and return dict of slices in conf. {slice: (host,port)}''' - slicesinconf = {} + slicesinconf = {} # default try: f = open(conf) for line in f.readlines(): - if line.startswith("#") or (len(line.split()) != 3): + if line.startswith("#") \ + or (len(line.split()) > 4) \ + or (len(line.split()) < 3): continue (host, slice, port) = line.split()[:3] - slicesinconf[slice] = {"host": host, "port": port} + logger.log("codemux: found %s in conf" % slice, 2) + slicesinconf.setdefault(slice, []) + slicesinconf[slice].append({"host": host, "port": port}) f.close() - except: logger.log_exc() + except IOError: logger.log_exc() return slicesinconf - +def restartService(): + logger.log("codemux: Restarting codemux service") + os.system("/etc/init.d/codemux stop") + f = os.popen("/sbin/pidof codemux") + tmp = f.readlines() + f.close() + if len(tmp) > 0: + pids = tmp[0].rstrip("\n").split() + for pid in pids: + logger.log("codemux: Killing stalled pid %s" % pid, 2) + os.kill(pid, 9) + os.system("/etc/init.d/codemux start")