Package ZenEvents :: Module Schedule
[hide private]
[frames] | no frames]

Source Code for Module ZenEvents.Schedule

  1  ########################################################################### 
  2  # 
  3  # This program is part of Zenoss Core, an open source monitoring platform. 
  4  # Copyright (C) 2007, Zenoss Inc. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify it 
  7  # under the terms of the GNU General Public License version 2 as published by 
  8  # the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 11  # 
 12  ########################################################################### 
 13  #! /usr/bin/env python  
 14   
 15  __doc__='''Schedule 
 16   
 17  Walk through the maintenance schedule. 
 18   
 19  $Id$ 
 20  ''' 
 21  import time 
 22  import logging 
 23  import transaction 
 24  from twisted.internet import reactor 
 25   
26 -class Schedule:
27
28 - def __init__(self, options, dmd):
29 "start executing the schedule" 30 self.dmd = dmd 31 self.maintenance = [] 32 self.options = options 33 self.log = logging.getLogger("zen.Schedule") 34 self.workList = [] 35 self.timer = None
36 37
38 - def buildOptions(self, parser):
39 "Set options in a borrowed parser"
40 41
42 - def start(self):
43 "Start working the schedule" 44 self.configCycle()
45 46
47 - def configCycle(self):
48 "Basic event-driven config loop" 49 self.run() 50 reactor.callLater(self.options.cycletime, self.configCycle)
51 52
53 - def sync(self):
54 "Synch with the database" 55 self.dmd._p_jar.sync()
56
57 - def getWindows(self):
58 result = [] 59 for dev in self.dmd.Devices.getSubDevices(): 60 result.extend(dev.maintenanceWindows()) 61 for name in 'Systems', 'Locations', 'Groups', 'Devices': 62 organizer = getattr(self.dmd, name) 63 for c in organizer.getSubOrganizers(): 64 result.extend(c.maintenanceWindows()) 65 result.extend(organizer.maintenanceWindows()) 66 67 for us in self.dmd.ZenUsers.getAllUserSettings(): 68 for ar in us.objectValues(spec="ActionRule"): 69 result.extend([w for w in ar.windows() if w.enabled]) 70 return result
71
72 - def run(self):
73 "Re-read work list from the database" 74 self.sync() 75 self.workList = self.getWindows() 76 self.runEvents()
77
78 - def makeWorkList(self, now, workList):
79 work = [(mw.nextEvent(now), mw) for mw in workList] 80 work.sort() 81 # note that None is less than any number of seconds 82 while len(work): 83 t, mw = work[0] 84 if t: break 85 if mw.enabled: 86 self.log.debug("Never going to run Maintenance " 87 "Window %s for %s again", 88 mw.getId(), mw.target().getId()) 89 if mw.started: 90 mw.end() 91 work.pop(0) 92 return work
93
94 - def now(self):
95 return time.time()
96
97 - def runEvents(self):
98 "Execute all the maintanance windows at the proper time" 99 100 if self.timer and not self.timer.called: 101 self.timer.cancel() 102 103 # sort events by the next occurance of something to do 104 now = self.now() 105 work = self.makeWorkList(now, self.workList) 106 self.workList = [mw for t, mw in work] 107 108 # fire events that should be done now 109 for next, mw in work: 110 if next <= now: 111 how = {True:'stopping', False:'starting'}[bool(mw.started)] 112 self.log.debug("Maintenance window " 113 "%s %s for %s", 114 how, mw.getId(), mw.target().getId()) 115 self.executeMaintenanceWindow(mw, next) 116 else: 117 break 118 119 work = self.makeWorkList(now, self.workList) 120 if work: 121 wait = max(0, work[0][0] - now) 122 self.log.debug("Waiting %f seconds", wait) 123 self.timer = self.callLater(wait) 124 self.commit()
125
126 - def commit(self):
128
129 - def callLater(self, seconds):
130 return reactor.callLater(seconds, self.runEvents)
131
132 - def executeMaintenanceWindow(self, mw, timestamp):
133 mw.execute(timestamp)
134 135 if __name__ == "__main__":
136 - class MySchedule(Schedule):
137 currentTime = time.time() 138 objs = None
139 - def now(self):
140 return self.currentTime
141 - def callLater(self, seconds):
142 self.currentTime += seconds
143 - def executeMaintenanceWindow(self, mw, timestamp):
144 print 'executing', mw.id, time.ctime(timestamp) 145 mw.execute(timestamp)
146 - def getWindows(self):
147 if self.workList: 148 return self.workList 149 return Schedule.getWindows(self)
150 - def commit(self):
151 pass
152 sync = commit
153 154 import Globals 155 from Products.ZenUtils.ZCmdBase import ZCmdBase 156 157 cmd = ZCmdBase()
158 - class Options: pass
159 s = MySchedule(Options(), cmd.dmd) 160 # compute the schedule for 30 days 161 end = s.currentTime + 60*60*24*30 162 while s.currentTime < end: 163 s.run() 164