@@ -31,7 +31,9 @@ def __init__(self):
3131 self .worker_api = worker_api .WorkerAPI ()
3232 self .blazar = blazar .BlazarClient ()
3333
34- def create_reservation (self , context , reservation ):
34+ def create_reservation (
35+ self , context , reservation , bypass_maintenance = False
36+ ):
3537 flavor = db .session .query (models .Flavor ).get (reservation .flavor_id )
3638 if not flavor .active :
3739 raise exceptions .InvalidReservation ("Flavor is not available" )
@@ -66,28 +68,30 @@ def create_reservation(self, context, reservation):
6668 f"reservation end time of { reservation .end } "
6769 )
6870
69- maintenance_windows = (
70- db .session .query (models .MaintenanceWindow )
71- .filter (models .MaintenanceWindow .end >= reservation .start )
72- .filter (models .MaintenanceWindow .start <= reservation .end )
73- .filter (
74- models .MaintenanceWindow .flavors .any (
75- models .Flavor .id == flavor .id
71+ if not bypass_maintenance :
72+ maintenance_windows = (
73+ db .session .query (models .MaintenanceWindow )
74+ .filter (models .MaintenanceWindow .end >= reservation .start )
75+ .filter (models .MaintenanceWindow .start <= reservation .end )
76+ .filter (
77+ models .MaintenanceWindow .flavors .any (
78+ models .Flavor .id == flavor .id
79+ )
7680 )
81+ .count ()
7782 )
78- .count ()
79- )
80- if maintenance_windows > 0 :
81- raise exceptions .InvalidReservation (
82- "Reservation conflicts with a maintenance window"
83- )
83+ if maintenance_windows > 0 :
84+ raise exceptions .InvalidReservation (
85+ "Reservation conflicts with a maintenance window"
86+ )
8487
8588 free_slots = self .flavor_free_slots (
8689 context ,
8790 flavor ,
8891 reservation .start ,
8992 reservation .end ,
9093 reservation ,
94+ include_maintenance = not bypass_maintenance ,
9195 )
9296
9397 if free_slots :
@@ -168,14 +172,24 @@ def delete_flavor(self, context, flavor):
168172 db .session .delete (flavor )
169173 db .session .commit ()
170174
171- def flavor_free_slots (self , context , flavor , start , end , reservation = None ):
175+ def flavor_free_slots (
176+ self ,
177+ context ,
178+ flavor ,
179+ start ,
180+ end ,
181+ reservation = None ,
182+ include_maintenance = True ,
183+ ):
172184 """Get the free slots of a flavor
173185 Algorithm:
174186 1. Get slots from flavor table as the total resource
175187 2. Get all reservations of current flavor
176188 3. Calculate the free slots
177189
178190 reservation - used to exclude an existing reservation when extending
191+ include_maintenance - when False, treat maintenance windows as not
192+ occupying any slots (admin bypass for testing during a window)
179193 """
180194 if not flavor .active :
181195 return []
@@ -209,17 +223,20 @@ def flavor_free_slots(self, context, flavor, start, end, reservation=None):
209223 query = query .filter (models .Reservation .id != reservation .id )
210224 reservations = query .all ()
211225
212- maintenance_windows = (
213- db .session .query (models .MaintenanceWindow )
214- .filter (models .MaintenanceWindow .end >= start )
215- .filter (models .MaintenanceWindow .start <= end )
216- .filter (
217- models .MaintenanceWindow .flavors .any (
218- models .Flavor .id == flavor .id
226+ if include_maintenance :
227+ maintenance_windows = (
228+ db .session .query (models .MaintenanceWindow )
229+ .filter (models .MaintenanceWindow .end >= start )
230+ .filter (models .MaintenanceWindow .start <= end )
231+ .filter (
232+ models .MaintenanceWindow .flavors .any (
233+ models .Flavor .id == flavor .id
234+ )
219235 )
236+ .all ()
220237 )
221- . all ()
222- )
238+ else :
239+ maintenance_windows = []
223240
224241 # the real thing begins here
225242 # Pass 1: segmentation and marking
0 commit comments