display version at startup
[nodemanager.git] / nm.py
1 #!/usr/bin/python
2 """Node Manager"""
3
4 import optparse
5 import time
6 import xmlrpclib
7 import socket
8 import os
9 import sys
10 import resource
11
12 import logger
13 import tools
14
15 from config import Config
16 from plcapi import PLCAPI 
17 import random
18 import net
19
20 id="$Id$"
21 savedargv = sys.argv[:]
22
23 parser = optparse.OptionParser()
24 parser.add_option('-d', '--daemon', action='store_true', dest='daemon', default=False, help='run daemonized')
25 parser.add_option('-s', '--startup', action='store_true', dest='startup', default=False, help='run all sliver startup scripts')
26 parser.add_option('-f', '--config', action='store', dest='config', default='/etc/planetlab/plc_config', help='PLC configuration file')
27 parser.add_option('-k', '--session', action='store', dest='session', default='/etc/planetlab/session', help='API session key (or file)')
28 parser.add_option('-p', '--period', action='store', dest='period', default=600, help='Polling interval (sec)')
29 parser.add_option('-r', '--random', action='store', dest='random', default=301, help='Range for additional random polling interval (sec)')
30 parser.add_option('-v', '--verbose', action='store_true', dest='verbose', default=False, help='more verbose log')
31 (options, args) = parser.parse_args()
32
33 modules = []
34
35 def GetSlivers(plc):
36     try: data = plc.GetSlivers()
37     except: logger.log_exc()
38     if (options.verbose):
39         logger.log_slivers(data)
40     # Set i2 ip list for nodes in I2 nodegroup.
41     try: net.GetSlivers(plc, data)
42     except: logger.log_exc()
43     #  All other callback modules
44     for module in modules:
45         try:        
46             callback = getattr(module, 'GetSlivers')
47             callback(data)
48         except: logger.log_exc()
49
50 def run():
51     try:
52         if options.daemon: tools.daemon()
53
54         # set log level
55         if (options.verbose):
56             logger.set_level(logger.LOG_VERBOSE)
57
58         # Load /etc/planetlab/plc_config
59         config = Config(options.config)
60
61         try:
62             other_pid = tools.pid_file()
63             if other_pid != None:
64                 print """There might be another instance of the node manager running as pid %d.  If this is not the case, please remove the pid file %s""" % (other_pid, tools.PID_FILE)
65                 return
66         except OSError, err:
67             print "Warning while writing PID file:", err
68
69         # Load and start modules
70         for module in ['proper', 'conf_files', 'sm', 'bwmon']:
71             try:
72                 m = __import__(module)
73                 m.start(options, config)
74                 modules.append(m)
75             except ImportError, err:
76                 print "Warning while loading module %s:" % module, err
77
78         # Load /etc/planetlab/session
79         if os.path.exists(options.session):
80             session = file(options.session).read().strip()
81         else:
82             session = options.session
83
84         # Initialize XML-RPC client
85         iperiod=int(options.period)
86         irandom=int(options.random)
87         plc = PLCAPI(config.plc_api_uri, config.cacert, session, timeout=iperiod/2)
88
89         while True:
90         # Main NM Loop
91             logger.verbose('mainloop - nm:getSlivers - period=%d random=%d'%(iperiod,irandom))
92             GetSlivers(plc)
93             delay=iperiod + random.randrange(0,irandom)
94             logger.verbose('mainloop - sleeping for %d s'%delay)
95             time.sleep(delay)
96     except: logger.log_exc()
97
98
99 if __name__ == '__main__':
100     logger.log("Entering nm.py "+id)
101     stacklim = 512*1024  # 0.5 MiB
102     curlim = resource.getrlimit(resource.RLIMIT_STACK)[0]  # soft limit
103     if curlim > stacklim:
104         resource.setrlimit(resource.RLIMIT_STACK, (stacklim, stacklim))
105         # for some reason, doesn't take effect properly without the exec()
106         python = '/usr/bin/python'
107         os.execv(python, [python] + savedargv)
108     run()
109 else:
110     # This is for debugging purposes.  Open a copy of Python and import nm
111     tools.as_daemon_thread(run)