[Pkg-nagios-changes] [SCM] UNNAMED PROJECT branch, debian/master, updated. 810edbdd3feedbfe37f4a65bee50b57b2f60fa2a

Naparuba naparuba at gmail.com
Tue Feb 28 22:18:14 UTC 2012


The following commit has been merged in the debian/master branch:
commit e4cafd7226b9970b8fef4d6ffd7ef6ca230f9d01
Author: Naparuba <naparuba at gmail.com>
Date:   Fri Feb 3 16:15:19 2012 +0100

    Fix : search invalid TP got problems in multi timerange format, and so got problems for DT

diff --git a/etc/templates.cfg b/etc/templates.cfg
index 2f8d123..6fc9d0f 100644
--- a/etc/templates.cfg
+++ b/etc/templates.cfg
@@ -40,6 +40,9 @@ define host{
 	event_handler_enabled		0
 	flap_detection_enabled		1
 	process_perf_data		1
+
+	# Maintenance period
+	#maintenance_period		workhours
 	
 	# Dispatching
 	#poller_tag			 DMZ
diff --git a/shinken/daterange.py b/shinken/daterange.py
index d4f1563..41986c4 100644
--- a/shinken/daterange.py
+++ b/shinken/daterange.py
@@ -182,9 +182,13 @@ class Daterange:
 
 
     def is_time_valid(self, t):
+        #print "****Look for time valid for", time.asctime(time.localtime(t))
         if self.is_time_day_valid(t):
+            #print "is time day valid"
             for tr in self.timeranges:
+                #print tr, "is valid?", tr.is_time_valid(t)
                 if tr.is_time_valid(t):
+                    #print "return True"
                     return True
         return False
 
@@ -318,8 +322,10 @@ class Daterange:
 
 
     def get_next_invalid_day(self, t):
+        #print "Look in", self.__dict__
         #print 'DR: get_next_invalid_day for', time.asctime(time.localtime(t))
         if self.is_time_day_invalid(t):
+            #print "EARLEY RETURN"
             return t
 
         next_future_timerange_invalid = self.get_next_future_timerange_invalid(t)
@@ -334,6 +340,9 @@ class Daterange:
             #print 'DR: get_next_future_timerange_invalid is', time.asctime(time.localtime(next_future_timerange_invalid))
             (start_time, end_time) = self.get_start_and_end_time(t)
 
+        #(start_time, end_time) = self.get_start_and_end_time(t)
+
+        #print "START", time.asctime(time.localtime(start_time)), "END", time.asctime(time.localtime(end_time))
         # The next invalid day can be t day if there a possible
         # invalid time range (timerange is not 00->24
         if next_future_timerange_invalid is not None:
@@ -341,6 +350,7 @@ class Daterange:
                 #print "Early Return next invalid day:", time.asctime(time.localtime(get_day(t)))
                 return get_day(t)
             if start_time >= t :
+                #print "start_time >= t :", time.asctime(time.localtime(get_day(start_time)))
                 return get_day(start_time)
         else:#Else, there is no possibility than in our start_time<->end_time we got
             #any invalid time (full period out). So it's end_time+1 sec (tomorow of end_time)
@@ -351,17 +361,23 @@ class Daterange:
 
 
     def get_next_invalid_time_from_t(self, t):
-        #print 'DR:get_next_invalid_time_from_t', time.asctime(time.localtime(t))
         if not self.is_time_valid(t):
-            #print "DR: cool, t is invalid",  time.asctime(time.localtime(t))
             return t
 
-
         # First we search fot the day of t
         t_day = self.get_next_invalid_day(t)
+        #print "FUCK NEXT DAY", time.asctime(time.localtime(t_day))
+
+        # We search for the min of all tr.start > sec_from_morning
+        # if it's the next day, use a start of the day search for timerange
+        if t < t_day:
+            sec_from_morning = self.get_next_future_timerange_invalid(t_day)
+        else: # t is in this day, so look from t (can be in the evening or so)
+            sec_from_morning = self.get_next_future_timerange_invalid(t)
+        #print "DR: sec from morning", sec_from_morning
 
         # tr can't be valid, or it will be return at the begining
-        sec_from_morning = self.get_next_future_timerange_invalid(t)
+        #sec_from_morning = self.get_next_future_timerange_invalid(t)
         
         # Ok we've got a next invalid day and a invalid possibility in
         # timerange, so the next invalid is this day+sec_from_morning
@@ -370,7 +386,7 @@ class Daterange:
             return t_day + sec_from_morning + 1
 
         # We've got a day but no sec_from_morning : the timerange is full (0->24h)
-        # so the next invalid is this day at the day_start
+        # so the next invalid is this day at the day_start 
         if t_day is not None and sec_from_morning is None:
             return t_day
 
diff --git a/shinken/objects/service.py b/shinken/objects/service.py
index 1d15e37..394e2e2 100644
--- a/shinken/objects/service.py
+++ b/shinken/objects/service.py
@@ -1067,8 +1067,8 @@ class Services(Items):
     # So service will take info from host if necessery
     def apply_implicit_inheritance(self, hosts):
         for prop in ( 'contacts', 'contact_groups', 'notification_interval',
-                         'notification_period', 'resultmodulations', 'business_impact_modulations', 'escalations',
-                         'poller_tag', 'reactionner_tag', 'check_period', 'business_impact' ):
+                      'notification_period', 'resultmodulations', 'business_impact_modulations', 'escalations',
+                      'poller_tag', 'reactionner_tag', 'check_period', 'business_impact', 'maintenance_period' ):
             for s in self:
                 if not s.is_tpl():
                     if not hasattr(s, prop) and hasattr(s, 'host_name'):
diff --git a/shinken/objects/timeperiod.py b/shinken/objects/timeperiod.py
index effef64..0ced11e 100644
--- a/shinken/objects/timeperiod.py
+++ b/shinken/objects/timeperiod.py
@@ -116,6 +116,7 @@ class Timeperiod(Item):
                 self.unresolved.append(key+' '+params[key])
 
         self.cache = {} #For tunning purpose only
+        self.invalid_cache = {} #same but for invalid search
         self.configuration_errors = []
         self.configuration_warnings = []
         # By default the tp is None so we know we just start
@@ -166,6 +167,14 @@ class Timeperiod(Item):
         except KeyError:
             return None
 
+
+    def find_next_invalid_time_from_cache(self, t):
+        try:
+            return self.invalid_cache[t]
+        except KeyError:
+            return None
+
+
     # will look for active/un-active change. And log it
     # [1327392000] TIMEPERIOD TRANSITION: <name>;<from>;<to>
     # from is -1 on startup.  to is 1 if the timeperiod starts 
@@ -205,6 +214,15 @@ class Timeperiod(Item):
         for t in t_to_del:
             del self.cache[t]
 
+        # same for the invalid cache
+        t_to_del = []
+        for t in self.invalid_cache:
+            if t < now:
+                t_to_del.append(t)
+        for t in t_to_del:
+            del self.invalid_cache[t]
+
+
 
     def get_next_valid_time_from_t(self, t):
         #first find from cache
@@ -273,8 +291,7 @@ class Timeperiod(Item):
                     still_loop = False
                     local_min = None
 
-        #print "We got it!"
-        #Ok, we update the cache...
+        # Ok, we update the cache...
         self.cache[original_t] = local_min
         return local_min
 
@@ -285,6 +302,12 @@ class Timeperiod(Item):
         original_t = t
         still_loop = True
 
+        # First try to find in cache
+        res_from_cache = self.find_next_invalid_time_from_cache(t)
+        if res_from_cache is not None:
+            return res_from_cache
+
+        #Then look, maybe t is already invalid
         if not self.is_time_valid(t):
             return t
 
@@ -294,23 +317,9 @@ class Timeperiod(Item):
         while still_loop:
             #print "Invalid loop with", time.asctime(time.localtime(local_min))
 
-#            #Ok, not in cache...
-#            #print self.get_name(), "Begin loop with", time.asctime(time.localtime(local_min))
-#            next_exclude = None
-#            for dr in self.exclude:
-#                m = dr.get_next_valid_time_from_t(local_min)
-#                if m != None:
-#                    #print time.asctime(time.localtime(m))
-#                    if next_exclude == None or m <= next_exclude:
-#                        next_exclude = m
-
-#            #Maybe the min of exclude is not valid, it is the min we can find.
-#            if next_exclude != None and not self.is_time_valid(next_exclude):
-#                #print self.get_name(), "find a possible early exit for invalid ! with", time.asctime(time.localtime(next_exclude))
-#                res = next_exclude
-#                still_loop = False
-
             dr_mins = []
+            #val_valids = []
+            #val_inval = []
             #But maybe we can find a better solution with next invalid of standart dateranges
             #print self.get_name(), "After valid of exclude, local_min =", time.asctime(time.localtime(local_min))
             for dr in self.dateranges:
@@ -318,28 +327,56 @@ class Timeperiod(Item):
                 #print dr.__dict__
                 m = dr.get_next_invalid_time_from_t(local_min)
 
-                #print self.get_name(), "Dr give me next invalid", time.asctime(time.localtime(m))
+                #print self.get_name(), "Dr", dr.__dict__,  "give me next invalid", time.asctime(time.localtime(m))
                 if m is not None:
-                    #But maybe it's invalid for this dr, but valid for other ones.
-                    if not self.is_time_valid(m):
-                    #print "Final : Got a next invalid at", time.asctime(time.localtime(m))
-                        dr_mins.append(m)
+                    # But maybe it's invalid for this dr, but valid for other ones.
+                    #if not self.is_time_valid(m):
+                        #print "Final : Got a next invalid at", time.asctime(time.localtime(m))
+                    dr_mins.append(m)
+                    #if not self.is_time_valid(m):
+                    #    val_inval.append(m)
+                    #else:
+                    #    val_valids.append(m)
                         #print "Add a m", time.asctime(time.localtime(m))
 #                    else:
 #                        print dr.__dict__
 #                        print "FUCK bad result\n\n\n"
+            #print "Inval"
+            #for v in val_inval:
+            #    print "\t", time.asctime(time.localtime(v))
+            #print "Valid"
+            #for v in val_valids:
+            #    print "\t", time.asctime(time.localtime(v))
 
             if dr_mins != []:
                 local_min = min(dr_mins)
-                #print "After dr : found invalid local min:", time.asctime(time.localtime(local_min)), "is valid", self.is_time_valid(local_min)
-
-            #print self.get_name(), 'Invalid: local min', time.asctime(time.localtime(local_min))
-            #We do not loop unless the local_min is not valid
-            still_loop = False
-
-            #if we've got a real value, we check it with the exclude
+                # Take the minimum valid as lower for next search
+                #local_min_valid = 0
+                #if val_valids != []:
+                #    local_min_valid = min(val_valids)
+                #if local_min_valid != 0:
+                #    local_min = local_min_valid
+                #else:
+                #    local_min = min(dr_mins)
+                #print "UPDATE After dr : found invalid local min:", time.asctime(time.localtime(local_min)), "is valid", self.is_time_valid(local_min)
+
+            #print self.get_name(), 'Invalid: local min', local_min#time.asctime(time.localtime(local_min))
+            # We do not loop unless the local_min is not valid
+            if not self.is_time_valid(local_min):
+                still_loop = False
+            else: # continue until we reach too far..., in one minute
+                # After one month, go quicker...
+                if local_min > original_t + 3600*24*30:
+                    local_min += 3600
+                else: # else search for 1min precision
+                    local_min += 60
+                # after one year, stop.
+                if local_min > original_t + 3600*24*366 + 1:#60*24*366 + 1:
+                    still_loop = False
+            #print "Loop?", still_loop
+            # if we've got a real value, we check it with the exclude
             if local_min is not None:
-                #Now check if local_min is not valid
+                # Now check if local_min is not valid
                 for tp in self.exclude:
                     #print self.get_name(),"we check for invalid", time.asctime(time.localtime(local_min)), 'with tp', tp.name
                     if tp.is_time_valid(local_min):
@@ -357,6 +394,8 @@ class Timeperiod(Item):
                     res = local_min
 
         #print "Finished Return the next invalid", time.asctime(time.localtime(local_min))
+        # Ok, we update the cache...
+        self.invalid_cache[original_t] = local_min
         return local_min
 
 
diff --git a/shinken/scheduler.py b/shinken/scheduler.py
index 6d08c07..3b59d08 100644
--- a/shinken/scheduler.py
+++ b/shinken/scheduler.py
@@ -1202,6 +1202,7 @@ class Scheduler:
         for elt in [y for y in [x for x in self.hosts] + [x for x in self.services] if y.maintenance_period is not None]:
             if not hasattr(elt, 'in_maintenance'):
                 setattr(elt, 'in_maintenance', False)
+
             if not elt.in_maintenance:
                 if elt.maintenance_period.is_time_valid(now):
                     start_dt = elt.maintenance_period.get_next_valid_time_from_t(now)
diff --git a/shinken/util.py b/shinken/util.py
index 3968549..78dcd41 100644
--- a/shinken/util.py
+++ b/shinken/util.py
@@ -105,6 +105,7 @@ def get_start_of_day(year, month_id, day):
     except OverflowError:
         # Windows mktime sometimes crashes on (1970, 1, 1, ...)
         start_time_epoch = 0.0
+
     return start_time_epoch
 
 
diff --git a/test/test_maintenance_period.py b/test/test_maintenance_period.py
index 95657e3..9ee56da 100755
--- a/test/test_maintenance_period.py
+++ b/test/test_maintenance_period.py
@@ -29,7 +29,7 @@ from shinken_test import *
 from shinken.objects.timeperiod import Timeperiod
 
 
-class TestConfig(ShinkenTest):
+class TestMaintPeriod(ShinkenTest):
     def setUp(self):
         self.setup_with_file('etc/nagios_maintenance_period.cfg')
 
@@ -50,12 +50,11 @@ class TestConfig(ShinkenTest):
         self.assert_(test_host_0.maintenance_period is None)
         self.assert_(test_nobody.maintenance_period is None)
 
-        #Now inplicit inheritance
-        #This one is defined in the service conf
+        # Now inplicit inheritance
+        # This one is defined in the service conf
         self.assert_(svc1.maintenance_period == a_24_7)
-        #This one is empty, because maintenance_period are not inherited from the
-        #host like check/notification_periods
-        self.assert_(svc2.maintenance_period is None)
+        # And others are implicitly inherited
+        self.assert_(svc2.maintenance_period is a_24_7)
         #This one got nothing :)
         self.assert_(svc3.maintenance_period is None)
 
diff --git a/test/test_timeperiods.py b/test/test_timeperiods.py
index 647139e..093c513 100755
--- a/test/test_timeperiods.py
+++ b/test/test_timeperiods.py
@@ -120,6 +120,18 @@ class TestTimeperiods(ShinkenTest):
         t_next = time.asctime(time.localtime(t_next))
         print "RES:", t_next
         self.assert_(t_next == "Mon Jul 12 21:30:00 2010")
+        # what about the next invalid?
+        t_next_inv = t.get_next_invalid_time_from_t(july_the_12)
+        t_next_inv = time.asctime(time.localtime(t_next_inv))
+        print "RES:", t_next_inv
+        self.assert_(t_next_inv == "Mon Jul 12 15:00:00 2010")
+        # what about a valid time and ask next invalid? Like at 22:00h?
+        print "GO"*10
+        july_the_12 = time.mktime(time.strptime("12 Jul 2010 22:00:00", "%d %b %Y %H:%M:%S"))
+        t_next_inv = t.get_next_invalid_time_from_t(july_the_12)
+        t_next_inv = time.asctime(time.localtime(t_next_inv))
+        print "RES:", t_next_inv#, t.is_time_valid(july_the_12)
+        self.assert_(t_next_inv == "Tue Jul 13 07:01:00 2010")        
 
         # Now ask about at 00:00 time?
         july_the_12 = time.mktime(time.strptime("12 Jul 2010 00:00:00", "%d %b %Y %H:%M:%S"))
@@ -135,6 +147,16 @@ class TestTimeperiods(ShinkenTest):
         self.assert_(t_next == "Mon Jul 12 00:00:00 2010")
 
 
+        # Now look for the never case
+        print "24x7"*10
+        t = self.conf.timeperiods.find_by_name('24x7')
+        self.assert_(t is not None)
+        t_next_inv = t.get_next_invalid_time_from_t(july_the_12)
+        t_next_inv = time.asctime(time.localtime(t_next_inv))
+        print "RES:", t_next_inv#, t.is_time_valid(july_the_12)
+        self.assert_(t_next_inv == 'Wed Jul 13 00:01:00 2011')
+
+
 
 
     def test_simple_timeperiod_with_exclude(self):

-- 
UNNAMED PROJECT



More information about the Pkg-nagios-changes mailing list