Merge "Support resuming an instance with shares (compute manager part)"
This commit is contained in:
@@ -7203,6 +7203,13 @@ class ComputeManager(manager.Manager):
|
||||
block_device_info = self._get_instance_block_device_info(
|
||||
context, instance, bdms=bdms)
|
||||
|
||||
# This allows passing share_info to the resume operation for
|
||||
# futur usage. However, this scenario is currently not possible
|
||||
# because suspending an instance with a share is not permitted
|
||||
# by libvirt. As a result, the suspend action involving a share
|
||||
# is blocked by the API.
|
||||
share_info = self._get_share_info(context, instance)
|
||||
|
||||
compute_utils.notify_about_instance_action(context, instance,
|
||||
self.host, action=fields.NotificationAction.RESUME,
|
||||
phase=fields.NotificationPhase.START, bdms=bdms)
|
||||
@@ -7212,7 +7219,7 @@ class ComputeManager(manager.Manager):
|
||||
with self._error_out_instance_on_exception(context, instance,
|
||||
instance_state=instance.vm_state):
|
||||
self.driver.resume(context, instance, network_info,
|
||||
block_device_info)
|
||||
block_device_info, share_info)
|
||||
|
||||
instance.power_state = self._get_power_state(instance)
|
||||
|
||||
|
||||
@@ -2877,12 +2877,17 @@ class ComputeTestCase(BaseTestCase,
|
||||
action='unpause', phase='end')])
|
||||
self.compute.terminate_instance(self.context, instance, [])
|
||||
|
||||
@mock.patch('nova.virt.fake.FakeDriver.resume')
|
||||
@mock.patch('nova.compute.manager.ComputeManager._get_share_info')
|
||||
@mock.patch('nova.compute.utils.notify_about_instance_action')
|
||||
@mock.patch('nova.context.RequestContext.elevated')
|
||||
def test_suspend(self, mock_context, mock_notify):
|
||||
def test_suspend(self, mock_context, mock_notify, mock_get_share_info,
|
||||
mock_resume):
|
||||
# ensure instance can be suspended and resumed.
|
||||
context = self.context
|
||||
mock_context.return_value = context
|
||||
share_info = objects.ShareMappingList()
|
||||
mock_get_share_info.return_value = share_info
|
||||
instance = self._create_fake_instance_obj()
|
||||
self.compute.build_and_run_instance(context, instance, {}, {}, {},
|
||||
[], block_device_mapping=[])
|
||||
@@ -2906,6 +2911,57 @@ class ComputeTestCase(BaseTestCase,
|
||||
action='suspend', phase='start'),
|
||||
mock.call(context, instance, 'fake-mini',
|
||||
action='suspend', phase='end')])
|
||||
|
||||
mock_get_share_info.assert_called_once_with(context, instance)
|
||||
|
||||
mock_resume.assert_called_once_with(
|
||||
self.context, instance, mock.ANY, mock.ANY, share_info)
|
||||
|
||||
self.compute.terminate_instance(self.context, instance, [])
|
||||
|
||||
@mock.patch('nova.compute.manager.ComputeManager.deny_share')
|
||||
@mock.patch('nova.virt.fake.FakeDriver.resume')
|
||||
@mock.patch('nova.compute.manager.ComputeManager._get_share_info')
|
||||
@mock.patch('nova.compute.utils.notify_about_instance_action')
|
||||
@mock.patch('nova.context.RequestContext.elevated')
|
||||
def test_suspend_with_share(self, mock_context, mock_notify,
|
||||
mock_get_share_info, mock_resume, mock_deny_share):
|
||||
# ensure instance can be suspended and resumed.
|
||||
context = self.context
|
||||
mock_context.return_value = context
|
||||
share_info = self.fake_share_info()
|
||||
mock_get_share_info.return_value = share_info
|
||||
instance = self._create_fake_instance_obj()
|
||||
self.compute.build_and_run_instance(context, instance, {}, {}, {},
|
||||
[], block_device_mapping=[])
|
||||
instance.task_state = task_states.SUSPENDING
|
||||
instance.save()
|
||||
self.compute.suspend_instance(context, instance)
|
||||
instance.task_state = task_states.RESUMING
|
||||
instance.save()
|
||||
self.compute.resume_instance(context, instance)
|
||||
|
||||
self.assertEqual(len(self.notifier.notifications), 6)
|
||||
|
||||
msg = self.notifier.notifications[2]
|
||||
self.assertEqual(msg.event_type,
|
||||
'compute.instance.suspend.start')
|
||||
msg = self.notifier.notifications[3]
|
||||
self.assertEqual(msg.event_type,
|
||||
'compute.instance.suspend.end')
|
||||
mock_notify.assert_has_calls([
|
||||
mock.call(context, instance, 'fake-mini',
|
||||
action='suspend', phase='start'),
|
||||
mock.call(context, instance, 'fake-mini',
|
||||
action='suspend', phase='end')])
|
||||
|
||||
mock_get_share_info.assert_called_once_with(context, instance)
|
||||
|
||||
mock_resume.assert_called_once_with(
|
||||
self.context, instance, mock.ANY, mock.ANY, share_info)
|
||||
|
||||
# Because we have shares, terminate the instance requires
|
||||
# to deny the share, so mocking is required
|
||||
self.compute.terminate_instance(self.context, instance, [])
|
||||
|
||||
def test_suspend_error(self):
|
||||
|
||||
Reference in New Issue
Block a user