X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=policy.py;h=cdd311c043fd2547c465b7ff10577a419f78ff74;hb=e283978522ef1017ed3591bdbd2aa194a59de5b1;hp=4befbd94b3452fe6bed2c39bc76e29c4ab61abeb;hpb=c9d06f3b274ecbc092a0b3eb1f5ceb6c0f734aad;p=monitor.git diff --git a/policy.py b/policy.py index 4befbd9..cdd311c 100755 --- a/policy.py +++ b/policy.py @@ -27,13 +27,13 @@ from monitor.wrapper import plccache from monitor.database.info.model import * from monitor.database.info.interface import * -from nodequery import verify,query_to_dict,node_select +from monitor.query import verify,query_to_dict,node_select api = plc.getAuthAPI() def logic(): - plc.nodeBootState(host, 'rins') + plc.nodeBootState(host, 'reinstall') node_end_record(host) def main(hostnames, sitenames): @@ -47,6 +47,7 @@ def main(hostnames, sitenames): lb = plccache.plcdb_hn2lb[host] except: print "unknown host in plcdb_hn2lb %s" % host + email_exception(host) continue nodeblack = BlacklistRecord.get_by(hostname=host) @@ -64,38 +65,88 @@ def main(hostnames, sitenames): print "%s %s %s" % (i, nodehist.hostname, nodehist.status) if nodehist.status == 'good' and \ changed_lessthan(nodehist.last_changed, 1.0) and \ + found_within(recent_actions, 'down_notice', 7.0) and \ not found_within(recent_actions, 'online_notice', 0.5): + # NOTE: chronicly flapping nodes will not get 'online' notices + # since, they are never up long enough to be 'good'. + # NOTE: searching for down_notice proves that the node has + # gone through a 'down' state first, rather than just + # flapping through: good, offline, online, ... + # # NOTE: there is a narrow window in which this command must be - # evaluated, otherwise the notice will not go out. this is not ideal. - sitehist.sendMessage('online_notice', hostname=host, viart=False) + # evaluated, otherwise the notice will not go out. + # this is not ideal. + sitehist.sendMessage('online_notice', hostname=host, viart=False, saveact=True) print "send message for host %s online" % host - pass - if ( nodehist.status == 'offline' or nodehist.status == 'down' ) and \ + # if a node is offline and doesn't have a PCU, remind the user that they should have one. + #if not nodehist.haspcu and nodehist.status in ['offline', 'down'] and \ + # changed_greaterthan(nodehist.last_changed,1.0) and \ + # not found_within(recent_actions, 'pcumissing_notice', 7.0): + # + # sitehist.sendMessage('pcumissing_notice', hostname=host) + # print "send message for host %s pcumissing_notice" % host + + # if it is offline and HAS a PCU, then try to use it. + if nodehist.haspcu and nodehist.status in ['offline', 'down'] and \ changed_greaterthan(nodehist.last_changed,1.0) and \ - not found_between(recent_actions, 'first_try_reboot', 3.5, 1): + not nodehist.firewall and \ + not found_between(recent_actions, 'try_reboot', 3.5, 1): - sitehist.attemptReboot(host) - print "send message for host %s first_try_reboot" % host - pass + # TODO: there MUST be a better way to do this... + # get fb node record for pcuid + fbpcu = None + fbnode = FindbadNodeRecord.get_latest_by(hostname=host) + if fbnode: + fbpcu = FindbadPCURecord.get_latest_by(plc_pcuid=fbnode.plc_pcuid) - # NOTE: non-intuitive is that found_between(first_try_reboot, 3.5, 1) + sitehist.attemptReboot(host) + print "send message for host %s try_reboot" % host + if not fbpcu.test_is_ok() and \ + not found_within(recent_actions, 'pcuerror_notice', 3.0): + + args = {} + if fbpcu: + args['pcu_name'] = fbpcu.pcu_name() + args['pcu_errors'] = fbpcu.pcu_errors() + args['plc_pcuid'] = fbpcu.plc_pcuid + else: + args['pcu_name'] = "error looking up pcu name" + args['pcu_errors'] = "" + args['plc_pcuid'] = 0 + + args['hostname'] = host + sitehist.sendMessage('pcuerror_notice', **args) + print "send message for host %s PCU Failure" % host + + + # NOTE: non-intuitive is that found_between(try_reboot, 3.5, 1) # will be false for a day after the above condition is satisfied - if ( nodehist.status == 'offline' or nodehist.status == 'down' ) and \ + if nodehist.haspcu and nodehist.status in ['offline', 'down'] and \ changed_greaterthan(nodehist.last_changed,1.5) and \ - found_between(recent_actions, 'first_try_reboot', 3.5, 1) and \ + not nodehist.firewall and \ + found_between(recent_actions, 'try_reboot', 3.5, 1) and \ not found_within(recent_actions, 'pcufailed_notice', 3.5): - # found_within(recent_actions, 'first_try_reboot', 3.5) and \ + # TODO: there MUST be a better way to do this... + # get fb node record for pcuid + fbpcu = None + fbnode = FindbadNodeRecord.get_latest_by(hostname=host) + if fbnode: + fbpcu = FindbadPCURecord.get_latest_by(plc_pcuid=fbnode.plc_pcuid) + if fbpcu: + pcu_name = fbpcu.pcu_name() + else: + pcu_name = "error looking up pcu name" + + # get fb pcu record for pcuid # send pcu failure message - #act = ActionRecord(**kwargs) - sitehist.sendMessage('pcufailed_notice', hostname=host) + sitehist.sendMessage('pcufailed_notice', hostname=host, pcu_name=pcu_name) print "send message for host %s PCU Failure" % host - pass - if nodehist.status == 'monitordebug' and \ - changed_greaterthan(nodehist.last_changed, 1) and \ + if nodehist.status == 'failboot' and \ + changed_greaterthan(nodehist.last_changed, 0.25) and \ not found_between(recent_actions, 'bootmanager_restore', 0.5, 0): # send down node notice # delay 0.5 days before retrying... @@ -105,23 +156,33 @@ def main(hostnames, sitenames): # sitehist.sendMessage('retry_bootman', hostname=host) if nodehist.status == 'down' and \ - changed_greaterthan(nodehist.last_changed, 2) and \ - not found_within(recent_actions, 'down_notice', 3.5): - # send down node notice - - sitehist.sendMessage('down_notice', hostname=host) - print "send message for host %s down" % host - pass + changed_greaterthan(nodehist.last_changed, 2): + if not nodehist.firewall and not found_within(recent_actions, 'down_notice', 3.5): + # send down node notice + sitehist.sendMessage('down_notice', hostname=host) + print "send message for host %s down" % host + + if nodehist.firewall and not found_within(recent_actions, 'firewall_notice', 3.5): + # send down node notice + #email_exception(host, "firewall_notice") + sitehist.sendMessage('firewall_notice', hostname=host) + print "send message for host %s down" % host node_count = node_count + 1 + print "time: ", time.strftime('%Y-%m-%d %H:%M:%S') + sys.stdout.flush() session.flush() for i,site in enumerate(sitenames): sitehist = SiteInterface.get_or_make(loginbase=site) siteblack = BlacklistRecord.get_by(loginbase=site) + skip_due_to_blacklist=False if siteblack and not siteblack.expired(): print "skipping %s due to blacklist. will expire %s" % (site, siteblack.willExpire() ) + skip_due_to_blacklist=True + sitehist.clearPenalty() + sitehist.applyPenalty() continue # TODO: make query only return records within a certin time range, @@ -129,14 +190,30 @@ def main(hostnames, sitenames): recent_actions = sitehist.getRecentActions(loginbase=site) print "%s %s %s" % (i, sitehist.db.loginbase, sitehist.db.status) + if sitehist.db.status == 'down': - if not found_within(recent_actions, 'pause_penalty', 30) and \ + if sitehist.db.penalty_pause and \ + changed_greaterthan(sitehist.db.penalty_pause_time, 30): + + email_exception("", "clear pause penalty for site: %s" % sitehist.db.loginbase) + sitehist.closeTicket() + # NOTE: but preserve the penalty status. + sitehist.clearPenaltyPause() + + if sitehist.db.message_id != 0 and \ + sitehist.db.message_status == 'open' and \ + not sitehist.db.penalty_pause: + + email_exception("", "pause penalty for site: %s" % sitehist.db.loginbase) + sitehist.setPenaltyPause() + + if not sitehist.db.penalty_pause and \ not found_within(recent_actions, 'increase_penalty', 7) and \ changed_greaterthan(sitehist.db.last_changed, 7): # TODO: catch errors sitehist.increasePenalty() - #sitehist.applyPenalty() + sitehist.applyPenalty() sitehist.sendMessage('increase_penalty') print "send message for site %s penalty increase" % site @@ -145,26 +222,21 @@ def main(hostnames, sitenames): # clear penalty # NOTE: because 'all clear' should have an indefinite status, we # have a boolean value rather than a 'recent action' - if sitehist.db.penalty_applied: + if sitehist.db.penalty_applied or sitehist.db.penalty_pause: # send message that penalties are cleared. sitehist.clearPenalty() - #sitehist.applyPenalty() + sitehist.applyPenalty() sitehist.sendMessage('clear_penalty') sitehist.closeTicket() print "send message for site %s penalty cleared" % site - # find all ticket ids for site ( could be on the site record? ) - # determine if there are penalties within the last 30 days? - # if so, add a 'pause_penalty' action. - if sitehist.db.message_id != 0 and sitehist.db.message_status == 'open' and sitehist.db.penalty_level > 0: - # pause escalation - print "Pausing penalties for %s" % site - sitehist.pausePenalty() site_count = site_count + 1 + print "time: ", time.strftime('%Y-%m-%d %H:%M:%S') + sys.stdout.flush() session.flush() session.flush() @@ -227,11 +299,12 @@ if __name__ == "__main__": try: main(hostnames, sitenames) + session.flush() except KeyboardInterrupt: print "Killed by interrupt" session.flush() sys.exit(0) except: - #email_exception() + email_exception() print traceback.print_exc(); print "fail all..."