34
34
import sys
35
35
import time
36
36
import traceback
37
+ import typing as ty
37
38
38
39
from cinderclient import exceptions as cinder_exception
39
40
from cursive import exception as cursive_exception
@@ -239,15 +240,25 @@ def decorated_function(self, context, image_id, instance,
239
240
return decorated_function
240
241
241
242
243
+ # Each collection of events is a dict of eventlet Events keyed by a tuple of
244
+ # event name and associated tag
245
+ _InstanceEvents = ty.Dict[ty.Tuple[str, str], eventlet.event.Event]
246
+
247
+
242
248
class InstanceEvents(object):
243
249
def __init__(self):
244
- self ._events = {}
250
+ self._events: ty.Optional[ty.Dict[str, _InstanceEvents]] = {}
245
251
246
252
@staticmethod
247
- def _lock_name (instance ):
253
+ def _lock_name(instance) -> str :
248
254
return '%s-%s' % (instance.uuid, 'events')
249
255
250
- def prepare_for_instance_event (self , instance , name , tag ):
256
+ def prepare_for_instance_event(
257
+ self,
258
+ instance: 'objects.Instance',
259
+ name: str,
260
+ tag: str,
261
+ ) -> eventlet.event.Event:
251
262
"""Prepare to receive an event for an instance.
252
263
253
264
This will register an event for the given instance that we will
@@ -260,14 +271,14 @@ def prepare_for_instance_event(self, instance, name, tag):
260
271
:param tag: the tag associated with the event we're expecting
261
272
:returns: an event object that should be wait()'d on
262
273
"""
263
- if self ._events is None :
264
- # NOTE(danms): We really should have a more specific error
265
- # here, but this is what we use for our default error case
266
- raise exception .NovaException ('In shutdown, no new events '
267
- 'can be scheduled' )
268
-
269
274
@utils.synchronized(self._lock_name(instance))
270
275
def _create_or_get_event():
276
+ if self._events is None:
277
+ # NOTE(danms): We really should have a more specific error
278
+ # here, but this is what we use for our default error case
279
+ raise exception.NovaException(
280
+ 'In shutdown, no new events can be scheduled')
281
+
271
282
instance_events = self._events.setdefault(instance.uuid, {})
272
283
return instance_events.setdefault((name, tag),
273
284
eventlet.event.Event())
@@ -313,10 +324,16 @@ def _pop_event():
313
324
instance=instance)
314
325
return None
315
326
elif result is no_matching_event_sentinel:
316
- LOG .debug ('No event matching %(event)s in %(events)s' ,
317
- {'event' : event .key ,
318
- 'events' : self ._events .get (instance .uuid , {}).keys ()},
319
- instance = instance )
327
+ LOG.debug(
328
+ 'No event matching %(event)s in %(events)s',
329
+ {
330
+ 'event': event.key,
331
+ # mypy can't identify the none check in _pop_event
332
+ 'events': self._events.get( # type: ignore
333
+ instance.uuid, {}).keys(),
334
+ },
335
+ instance=instance,
336
+ )
320
337
return None
321
338
else:
322
339
return result
@@ -457,7 +474,7 @@ def wait_for_instance_event(self, instance, event_names, deadline=300,
457
474
early_events = set([objects.InstanceExternalEvent.make_key(n, t)
458
475
for n, t in e.events])
459
476
else:
460
- early_events = []
477
+ early_events = set([])
461
478
462
479
with eventlet.timeout.Timeout(deadline):
463
480
for event_name, event in events.items():
@@ -525,7 +542,7 @@ def __init__(self, compute_driver=None, *args, **kwargs):
525
542
self.network_api = neutron.API()
526
543
self.volume_api = cinder.API()
527
544
self.image_api = glance.API()
528
- self ._last_bw_usage_poll = 0
545
+ self._last_bw_usage_poll = 0.0
529
546
self._bw_usage_supported = True
530
547
self.compute_api = compute.API()
531
548
self.compute_rpcapi = compute_rpcapi.ComputeAPI()
@@ -1891,12 +1908,19 @@ def _default_block_device_names(self, instance, image_meta, block_devices):
1891
1908
if update_root_bdm:
1892
1909
root_bdm.save()
1893
1910
1894
- ephemerals = list (filter (block_device .new_format_is_ephemeral ,
1895
- block_devices ))
1896
- swap = list (filter (block_device .new_format_is_swap ,
1897
- block_devices ))
1898
- block_device_mapping = list (filter (
1899
- driver_block_device .is_block_device_mapping , block_devices ))
1911
+ ephemerals = []
1912
+ swap = []
1913
+ block_device_mapping = []
1914
+
1915
+ for device in block_devices:
1916
+ if block_device.new_format_is_ephemeral(device):
1917
+ ephemerals.append(device)
1918
+
1919
+ if block_device.new_format_is_swap(device):
1920
+ swap.append(device)
1921
+
1922
+ if driver_block_device.is_block_device_mapping(device):
1923
+ block_device_mapping.append(device)
1900
1924
1901
1925
self._default_device_names_for_instance(instance,
1902
1926
root_device_name,
@@ -5298,11 +5322,10 @@ def _reschedule_resize_or_reraise(self, context, instance, exc_info,
5298
5322
)
5299
5323
else:
5300
5324
# not re-scheduling
5301
- if exc_info [1 ] is None :
5302
- exc_info [1 ] = exc_info [0 ]()
5303
- if exc_info [1 ].__traceback__ is not exc_info [2 ]:
5304
- raise exc_info [1 ].with_traceback (exc_info [2 ])
5305
- raise exc_info [1 ]
5325
+ exc = exc_info[1] or exc_info[0]()
5326
+ if exc.__traceback__ is not exc_info[2]:
5327
+ raise exc.with_traceback(exc_info[2])
5328
+ raise exc
5306
5329
5307
5330
# TODO(stephenfin): Remove unused request_spec parameter in API v6.0
5308
5331
@messaging.expected_exceptions(exception.MigrationPreCheckError)
0 commit comments