only report one for now.
[monitor.git] / RunlevelAgent.py
1 #!/usr/bin/python
2
3 import xml, xmlrpclib
4 import logging
5 import time
6 import traceback
7 import sys
8 import os
9 import string
10
11 CONFIG_FILE="/tmp/source/configuration"
12 SESSION_FILE="/etc/planetlab/session"
13
14 def read_config_file(filename):
15     ## NOTE: text copied from BootManager.py 
16     # TODO: unify this code to make it common. i.e. use ConfigParser module
17     vars = {}
18     vars_file= file(filename,'r')
19     validConfFile = True
20     for line in vars_file:
21         # if its a comment or a whitespace line, ignore
22         if line[:1] == "#" or string.strip(line) == "":
23             continue
24
25         parts= string.split(line,"=")
26         if len(parts) != 2:
27             print "Invalid line in vars file: %s" % line
28             validConfFile = False
29             break
30
31         name= string.strip(parts[0])
32         value= string.strip(parts[1])
33         vars[name]= value
34
35     vars_file.close()
36     if not validConfFile:
37         print "Unable to read configuration vars."
38
39     return vars
40
41 try:
42     sys.path = ['/etc/planetlab'] + sys.path
43     import plc_config
44     api_server_url = "https://" + plc_config.PLC_API_HOST + plc_config.PLC_API_PATH
45 except:
46     filename=CONFIG_FILE
47     vars = read_config_file(filename)
48     api_server_url = vars['BOOT_API_SERVER']
49
50
51 class Auth:
52     def __init__(self, username=None, password=None, **kwargs):
53         if 'session' in kwargs:
54             self.auth= { 'AuthMethod' : 'session',
55                     'session' : kwargs['session'] }
56         else:
57             if username==None and password==None:
58                 self.auth = {'AuthMethod': "anonymous"}
59             else:
60                 self.auth = {'Username' : username,
61                             'AuthMethod' : 'password',
62                             'AuthString' : password}
63 class PLC:
64     def __init__(self, auth, url):
65         self.auth = auth
66         self.url = url
67         self.api = xmlrpclib.Server(self.url, verbose=False, allow_none=True)
68
69     def __getattr__(self, name):
70         method = getattr(self.api, name)
71         if method is None:
72             raise AssertionError("method does not exist")
73
74         return lambda *params : method(self.auth.auth, *params)
75
76     def __repr__(self):
77         return self.api.__repr__()
78
79 def main():
80
81     f=open(SESSION_FILE,'r')
82     session_str=f.read().strip()
83     api = PLC(Auth(session=session_str), api_server_url)
84     # NOTE: should we rely on bootmanager for this functionality?
85     api.AuthCheck()
86
87     try:
88         env = 'production'
89         if len(sys.argv) > 1:
90             env = sys.argv[1]
91     except:
92         traceback.print_exc()
93         pass
94
95     while True:
96         # TODO: remove from output
97         print "reporting status: ", os.popen("uptime").read().strip()
98         try:
99             # NOTE: alternately, check other stuff in the environment to infer
100             # run_level
101             #     is BootManager running?
102             #     what is the boot_state at PLC?
103             #     does /vservers exist?
104             #     what about /tmp/source?
105             #     is BootManager in /tmp/source?
106             #     is /tmp/mnt/sysimg mounted?
107             #     how long have we been running?  if we were in safeboot and
108             #       still running, we're likely in failboot now.
109             #     length of runtime increases the certainty of inferred state.
110             #     
111             if env == "bootmanager":
112                 # if bm not running, and plc bootstate = boot, then
113                 #api.ReportRunlevel({'run_level' : 'failboot'})
114                 #api.ReportRunlevel({'run_level' : 'reinstall'})
115                 # if bm not running, and plc bootstate = safeboot, then
116                 api.ReportRunlevel({'run_level' : 'safeboot'})
117             elif env == "production":
118                 api.ReportRunlevel({'run_level' : 'boot'})
119             else:
120                 api.ReportRunlevel({'run_level' : 'failboot'})
121                 
122         except:
123             traceback.print_exc()
124
125         # TODO: change to a configurable value
126         sys.stdout.flush()
127         time.sleep(60)
128
129 if __name__ == "__main__":
130     main()