3434import sys
3535import time
3636import traceback
37+ import typing as ty
3738
3839from cinderclient import exceptions as cinder_exception
3940from cursive import exception as cursive_exception
@@ -239,15 +240,25 @@ def decorated_function(self, context, image_id, instance,
239240 return decorated_function
240241
241242
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+
242248class InstanceEvents(object):
243249 def __init__(self):
244- self ._events = {}
250+ self._events: ty.Optional[ty.Dict[str, _InstanceEvents]] = {}
245251
246252 @staticmethod
247- def _lock_name (instance ):
253+ def _lock_name(instance) -> str :
248254 return '%s-%s' % (instance.uuid, 'events')
249255
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:
251262 """Prepare to receive an event for an instance.
252263
253264 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):
260271 :param tag: the tag associated with the event we're expecting
261272 :returns: an event object that should be wait()'d on
262273 """
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-
269274 @utils.synchronized(self._lock_name(instance))
270275 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+
271282 instance_events = self._events.setdefault(instance.uuid, {})
272283 return instance_events.setdefault((name, tag),
273284 eventlet.event.Event())
@@ -313,10 +324,16 @@ def _pop_event():
313324 instance=instance)
314325 return None
315326 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+ )
320337 return None
321338 else:
322339 return result
@@ -457,7 +474,7 @@ def wait_for_instance_event(self, instance, event_names, deadline=300,
457474 early_events = set([objects.InstanceExternalEvent.make_key(n, t)
458475 for n, t in e.events])
459476 else:
460- early_events = []
477+ early_events = set([])
461478
462479 with eventlet.timeout.Timeout(deadline):
463480 for event_name, event in events.items():
@@ -525,7 +542,7 @@ def __init__(self, compute_driver=None, *args, **kwargs):
525542 self.network_api = neutron.API()
526543 self.volume_api = cinder.API()
527544 self.image_api = glance.API()
528- self ._last_bw_usage_poll = 0
545+ self._last_bw_usage_poll = 0.0
529546 self._bw_usage_supported = True
530547 self.compute_api = compute.API()
531548 self.compute_rpcapi = compute_rpcapi.ComputeAPI()
@@ -1891,12 +1908,19 @@ def _default_block_device_names(self, instance, image_meta, block_devices):
18911908 if update_root_bdm:
18921909 root_bdm.save()
18931910
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)
19001924
19011925 self._default_device_names_for_instance(instance,
19021926 root_device_name,
@@ -5298,11 +5322,10 @@ def _reschedule_resize_or_reraise(self, context, instance, exc_info,
52985322 )
52995323 else:
53005324 # 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
53065329
53075330 # TODO(stephenfin): Remove unused request_spec parameter in API v6.0
53085331 @messaging.expected_exceptions(exception.MigrationPreCheckError)
0 commit comments