clearer names for actions, and infer actions better
[monitor.git] / statistics / nodebad.py
1 #!/usr/bin/python
2
3 import os
4 import sys
5 import string
6 import time
7
8
9 from monitor import database
10 from nodequeryold import verify,query_to_dict,node_select
11 from monitor.common import *
12
13 from monitor.wrapper import plc
14 api = plc.getAuthAPI()
15 from monitor.model import *
16
17 round = 1
18 externalState = {'round': round, 'nodes': {}}
19 count = 0
20
21 def main(config):
22         global externalState
23         externalState = database.if_cached_else(1, config.dbname, lambda : externalState) 
24         if config.increment:
25                 # update global round number to force refreshes across all nodes
26                 externalState['round'] += 1
27
28         #l_nodes = syncplcdb.create_plcdb()
29         l_plcnodes = database.dbLoad("l_plcnodes")
30
31         l_nodes = get_nodeset(config)
32         #if config.node:
33         #       l_nodes = [config.node]
34         ##else:
35         #       l_nodes = [node['hostname'] for node in l_plcnodes]
36         
37         checkAndRecordState(l_nodes, l_plcnodes)
38
39 def checkAndRecordState(l_nodes, l_plcnodes):
40         global externalState
41         global count
42         global_round = externalState['round']
43
44         for nodename in l_nodes:
45                 if nodename not in externalState['nodes']:
46                         externalState['nodes'][nodename] = {'round': 0, 'values': []}
47
48                 node_round   = externalState['nodes'][nodename]['round']
49                 if node_round < global_round:
50                         # do work
51                         values = collectStatusAndState(nodename, l_plcnodes)
52                         global_round = externalState['round']
53                         externalState['nodes'][nodename]['values'] = values
54                         externalState['nodes'][nodename]['round'] = global_round
55                 else:
56                         count += 1
57
58                 if count % 20 == 0:
59                         database.dbDump(config.dbname, externalState)
60
61         database.dbDump(config.dbname, externalState)
62
63 fb = database.dbLoad('findbad')
64
65 def getnodesup(nodelist):
66         up = 0
67         for node in nodelist:
68                 if node['hostname'] in fb['nodes'].keys():
69                         try:
70                                 if fb['nodes'][node['hostname']]['values']['state'] == "BOOT":
71                                         up = up + 1
72                         except:
73                                 pass
74         return up
75
76 def get(fb, path):
77         indexes = path.split("/")
78         values = fb
79         for index in indexes:
80                 if index in values:
81                         values = values[index]
82                 else:
83                         return None
84         return values
85
86 def collectStatusAndState(nodename, l_plcnodes):
87         global count
88
89         d_node = None
90         for node in l_plcnodes:
91                 if node['hostname'] == nodename:
92                         d_node = node
93                         break
94         if not d_node:
95                 return None
96
97         pf = PersistFlags(nodename, 1, db='node_persistflags')
98
99         if not pf.checkattr('last_changed'):
100                 pf.last_changed = time.time()
101                 
102         pf.last_checked = time.time()
103
104         if not pf.checkattr('status'):
105                 pf.status = "unknown"
106
107         state_path     = "nodes/" + nodename + "/values/state"
108         bootstate_path = "nodes/" + nodename + "/values/plcnode/boot_state"
109
110         if get(fb, state_path) == "BOOT":
111                 if pf.status != "good": pf.last_changed = time.time()
112                 pf.status = "good"
113         elif get(fb, state_path)  == "DEBUG":
114                 bs = get(fb, bootstate_path)
115                 if pf.status != bs: pf.last_changed = time.time()
116                 pf.status = bs
117         else:
118                 if pf.status != "down": pf.last_changed = time.time()
119                 pf.status = "down"
120
121         count += 1
122         print "%d %35s %s since(%s)" % (count, nodename, pf.status, diff_time(pf.last_changed))
123         # updated by other modules
124         #pf.enabled = 
125         #pf.suspended = 
126
127         pf.save()
128
129         return True
130
131 if __name__ == '__main__':
132         import parser as parsermodule
133         parser = parsermodule.getParser(['nodesets'])
134         parser.set_defaults(filename=None, node=None, nodeselect=False, nodegroup=None, 
135                                                 increment=False, dbname="nodebad", cachenodes=False)
136         
137         parser.add_option("", "--dbname", dest="dbname", metavar="FILE", 
138                                                 help="Specify the name of the database to which the information is saved")
139         parser.add_option("-i", "--increment", action="store_true", dest="increment", 
140                                                 help="Increment round number to force refresh or retry")
141         parser = parsermodule.getParser(['defaults'], parser)
142         config = parsermodule.parse_args(parser)
143
144         try:
145                 main(config)
146         except Exception, err:
147                 import traceback
148                 print traceback.print_exc()
149                 print "Exception: %s" % err
150                 print "Saving data... exitting."
151                 database.dbDump(config.dbname, externalState)
152                 sys.exit(0)