* Checks for zombied pids during restart
[nodemanager.git] / codemux.py
1 # $Id$
2 # $URL$
3
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."""
5
6 import logger
7 import os
8 import vserver
9 from sets import Set
10
11 CODEMUXCONF="/etc/codemux/codemux.conf"
12
13 def start(options, config):
14     pass
15
16
17 def GetSlivers(data):
18     """For each sliver with the codemux attribute, parse out "host,port" and make entry in conf.  Restart service after."""
19     logger.log("codemux:  Starting.", 2)
20     # slices already in conf
21     slicesinconf = parseConf()
22     # slices that need to be written to the conf
23     codemuxslices = {}
24     _writeconf = False
25     # Parse attributes and update dict of scripts
26     for sliver in data['slivers']:
27         for attribute in sliver['attributes']:
28             if attribute['name'] == 'codemux':
29                 # add to conf.  Attribute is [host, port]
30                 [host, port] = attribute['value'].split(",")
31                 try:
32                     # Check to see if sliver is running.  If not, continue
33                     if vserver.VServer(sliver['name']).is_running():
34                         # Add to dict of codemuxslices 
35                         codemuxslices[sliver['name']] = {'host': host, 'port': port}
36                         # Check if new
37                         if sliver['name'] not in slicesinconf.keys():
38                             logger.log("codemux:  New slice %s using %s" % \
39                                 (sliver['name'], host))
40                             #  Toggle write.
41                             _writeconf = True
42                         # Check old slivers for changes
43                         else:
44                             # Get info about slice in conf
45                             sliverinconf = slicesinconf[sliver['name']]
46                             # Check values for changes.
47                             if (sliverinconf['host'] != host) or \
48                                 (sliverinconf['port'] != port):
49                                 logger.log("codemux:  Updating slice %s" % sliver['name'])
50                                 # use updated values
51                                 codemuxslices[sliver['name']] = {'host': host, 'port': port}
52                                 #  Toggle write.
53                                 _writeconf = True
54                 except:
55                     logger.log("codemux:  sliver %s not running yet.  Deferring."\
56                                 % sliver['name'])
57
58                     logger.log_exc(name = "codemux")
59                     pass
60
61     # Remove slices from conf that no longer have the attribute
62     for deadslice in Set(slicesinconf.keys()) - Set(codemuxslices.keys()):
63         logger.log("codemux:  Removing %s" % deadslice)
64         _writeconf = True
65         
66     if _writeconf:  writeConf(codemuxslices)
67
68 def writeConf(slivers, conf = CODEMUXCONF):
69     '''Write conf with default entry up top. Restart service.'''
70     f = open(conf, "w")
71     f.write("* root 1080\n")
72     for (slice, params) in slivers.iteritems():
73         f.write("%s %s %s\n" % (params['host'], slice, params['port']))
74     f.truncate()
75     f.close()
76     try:  restartService()
77     except:  logger.log_exc()
78
79 def parseConf(conf = CODEMUXCONF):
80     '''Parse the CODEMUXCONF and return dict of slices in conf. {slice: (host,port)}'''
81     slicesinconf = {} 
82     try: 
83         f = open(conf)
84         for line in f.readlines():
85             if line.startswith("#") or (len(line.split()) != 3)\
86             or line.startswith("*"):  
87                 continue
88             (host, slice, port) = line.split()[:3]
89             logger.log("codemux:  found %s in conf" % slice, 2)
90             slicesinconf[slice] = {"host": host, "port": port}
91         f.close()
92     except: logger.log_exc()
93     return slicesinconf
94
95 def restartService():
96     logger.log("codemux:  Restarting codemux service")
97     os.system("/etc/init.d/codemux stop")
98     f = os.popen("/sbin/pidof codemux")
99     tmp = f.readlines()
100     f.close()
101     if len(tmp) > 0: 
102         pids = tmp[0].rstrip("\n").split()
103         for pid in pids:
104             logger.log("codemux:  Killing stalled pid %s" % pid, 2)
105             os.kill(pid, 9)
106     os.system("/etc/init.d/codemux start")