Merge "Correctly reset instance task state in rebooting hard"
This commit is contained in:
commit
6bd99eb2ea
@ -1159,6 +1159,8 @@ class ComputeManager(manager.Manager):
|
|||||||
try_reboot, reboot_type = self._retry_reboot(
|
try_reboot, reboot_type = self._retry_reboot(
|
||||||
instance, current_power_state)
|
instance, current_power_state)
|
||||||
|
|
||||||
|
# NOTE(amorin)
|
||||||
|
# If the instance is in power_state_SHUTDOWN, we will try_reboot
|
||||||
if try_reboot:
|
if try_reboot:
|
||||||
LOG.debug("Instance in transitional state (%(task_state)s) at "
|
LOG.debug("Instance in transitional state (%(task_state)s) at "
|
||||||
"start-up and power state is (%(power_state)s), "
|
"start-up and power state is (%(power_state)s), "
|
||||||
@ -1181,9 +1183,14 @@ class ComputeManager(manager.Manager):
|
|||||||
reboot_type=reboot_type)
|
reboot_type=reboot_type)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# NOTE(plestang): an instance might be in power_state.RUNNING with a
|
||||||
|
# transient state when a host is brutally shutdown or rebooted while a
|
||||||
|
# reboot/pause/unpause is scheduled on client side
|
||||||
elif (current_power_state == power_state.RUNNING and
|
elif (current_power_state == power_state.RUNNING and
|
||||||
instance.task_state in [task_states.REBOOT_STARTED,
|
instance.task_state in [task_states.REBOOT_STARTED,
|
||||||
task_states.REBOOT_STARTED_HARD,
|
task_states.REBOOT_STARTED_HARD,
|
||||||
|
task_states.REBOOTING_HARD,
|
||||||
|
task_states.REBOOTING,
|
||||||
task_states.PAUSING,
|
task_states.PAUSING,
|
||||||
task_states.UNPAUSING]):
|
task_states.UNPAUSING]):
|
||||||
LOG.warning("Instance in transitional state "
|
LOG.warning("Instance in transitional state "
|
||||||
@ -1343,7 +1350,9 @@ class ComputeManager(manager.Manager):
|
|||||||
current_task_state == task_states.REBOOT_PENDING_HARD and
|
current_task_state == task_states.REBOOT_PENDING_HARD and
|
||||||
instance.vm_state in vm_states.ALLOW_HARD_REBOOT)
|
instance.vm_state in vm_states.ALLOW_HARD_REBOOT)
|
||||||
started_not_running = (current_task_state in
|
started_not_running = (current_task_state in
|
||||||
[task_states.REBOOT_STARTED,
|
[task_states.REBOOTING,
|
||||||
|
task_states.REBOOTING_HARD,
|
||||||
|
task_states.REBOOT_STARTED,
|
||||||
task_states.REBOOT_STARTED_HARD] and
|
task_states.REBOOT_STARTED_HARD] and
|
||||||
current_power_state != power_state.RUNNING)
|
current_power_state != power_state.RUNNING)
|
||||||
|
|
||||||
|
@ -2278,18 +2278,30 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
|||||||
instance.host = self.compute.host
|
instance.host = self.compute.host
|
||||||
with test.nested(
|
with test.nested(
|
||||||
mock.patch.object(self.compute, '_get_power_state',
|
mock.patch.object(self.compute, '_get_power_state',
|
||||||
return_value=power_state.RUNNING),
|
return_value=instance.power_state),
|
||||||
mock.patch.object(instance, 'save', autospec=True),
|
mock.patch.object(instance, 'save', autospec=True),
|
||||||
mock.patch.object(objects.Instance, 'get_network_info')
|
mock.patch.object(objects.Instance, 'get_network_info'),
|
||||||
|
mock.patch.object(self.compute, 'reboot_instance'),
|
||||||
) as (
|
) as (
|
||||||
_get_power_state,
|
_get_power_state,
|
||||||
instance_save,
|
instance_save,
|
||||||
get_network_info
|
get_network_info,
|
||||||
|
reboot_instance,
|
||||||
):
|
):
|
||||||
self.compute._init_instance(self.context, instance)
|
self.compute._init_instance(self.context, instance)
|
||||||
instance_save.assert_called_once_with()
|
# If instance was running, the instance should stay running,
|
||||||
self.assertIsNone(instance.task_state)
|
# and tasks are discarded
|
||||||
self.assertEqual(vm_states.ACTIVE, instance.vm_state)
|
if instance.power_state == power_state.RUNNING:
|
||||||
|
instance_save.assert_called_once_with()
|
||||||
|
self.assertIsNone(instance.task_state)
|
||||||
|
self.assertEqual(vm_states.ACTIVE, instance.vm_state)
|
||||||
|
# If instance was not running, but we request to reboot it,
|
||||||
|
# we should try a reboot
|
||||||
|
else:
|
||||||
|
call = mock.call(self.context, instance,
|
||||||
|
block_device_info=None, reboot_type=mock.ANY)
|
||||||
|
reboot_instance.assert_has_calls([call])
|
||||||
|
self.assertEqual(vm_states.STOPPED, instance.vm_state)
|
||||||
|
|
||||||
def test_init_instance_cleans_image_state_reboot_started(self):
|
def test_init_instance_cleans_image_state_reboot_started(self):
|
||||||
instance = objects.Instance(self.context)
|
instance = objects.Instance(self.context)
|
||||||
@ -2307,37 +2319,13 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
|||||||
instance.power_state = power_state.RUNNING
|
instance.power_state = power_state.RUNNING
|
||||||
self._test_init_instance_cleans_reboot_state(instance)
|
self._test_init_instance_cleans_reboot_state(instance)
|
||||||
|
|
||||||
def _test_init_instance_cleans_reboot_state_reproducer(self, instance,
|
|
||||||
task_state):
|
|
||||||
instance.host = self.compute.host
|
|
||||||
with test.nested(
|
|
||||||
mock.patch.object(self.compute, '_get_power_state',
|
|
||||||
return_value=power_state.RUNNING),
|
|
||||||
mock.patch.object(instance, 'save', autospec=True),
|
|
||||||
mock.patch.object(objects.Instance, 'get_network_info')
|
|
||||||
) as (
|
|
||||||
_get_power_state,
|
|
||||||
instance_save,
|
|
||||||
get_network_info
|
|
||||||
):
|
|
||||||
self.compute._init_instance(self.context, instance)
|
|
||||||
# By checking save method is not called we confirm that the init
|
|
||||||
# instance does not take into account this use case
|
|
||||||
instance_save.assert_not_called()
|
|
||||||
# So the instance task_state is still task_state
|
|
||||||
self.assertEqual(task_state, instance.task_state)
|
|
||||||
self.assertEqual(vm_states.ACTIVE, instance.vm_state)
|
|
||||||
|
|
||||||
def test_init_instance_cleans_image_state_rebooting(self):
|
def test_init_instance_cleans_image_state_rebooting(self):
|
||||||
instance = objects.Instance(self.context)
|
instance = objects.Instance(self.context)
|
||||||
instance.uuid = uuids.instance
|
instance.uuid = uuids.instance
|
||||||
instance.vm_state = vm_states.ACTIVE
|
instance.vm_state = vm_states.ACTIVE
|
||||||
instance.task_state = task_states.REBOOTING
|
instance.task_state = task_states.REBOOTING
|
||||||
instance.power_state = power_state.RUNNING
|
instance.power_state = power_state.RUNNING
|
||||||
# To uncomment once bug #1999674 is fixed and remove all the code below
|
self._test_init_instance_cleans_reboot_state(instance)
|
||||||
# self._test_init_instance_cleans_reboot_state(instance)
|
|
||||||
self._test_init_instance_cleans_reboot_state_reproducer(instance,
|
|
||||||
task_states.REBOOTING)
|
|
||||||
|
|
||||||
def test_init_instance_cleans_image_state_rebooting_hard(self):
|
def test_init_instance_cleans_image_state_rebooting_hard(self):
|
||||||
instance = objects.Instance(self.context)
|
instance = objects.Instance(self.context)
|
||||||
@ -2345,10 +2333,39 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
|||||||
instance.vm_state = vm_states.ACTIVE
|
instance.vm_state = vm_states.ACTIVE
|
||||||
instance.task_state = task_states.REBOOTING_HARD
|
instance.task_state = task_states.REBOOTING_HARD
|
||||||
instance.power_state = power_state.RUNNING
|
instance.power_state = power_state.RUNNING
|
||||||
# To uncomment once bug #1999674 is fixed and remove all the code below
|
self._test_init_instance_cleans_reboot_state(instance)
|
||||||
# self._test_init_instance_cleans_reboot_state(instance)
|
|
||||||
self._test_init_instance_cleans_reboot_state_reproducer(instance,
|
def test_init_instance_cleans_shutdown_reboot_started(self):
|
||||||
task_states.REBOOTING_HARD)
|
instance = objects.Instance(self.context)
|
||||||
|
instance.uuid = uuids.instance
|
||||||
|
instance.vm_state = vm_states.STOPPED
|
||||||
|
instance.task_state = task_states.REBOOT_STARTED
|
||||||
|
instance.power_state = power_state.SHUTDOWN
|
||||||
|
self._test_init_instance_cleans_reboot_state(instance)
|
||||||
|
|
||||||
|
def test_init_instance_cleans_shutdown_reboot_started_hard(self):
|
||||||
|
instance = objects.Instance(self.context)
|
||||||
|
instance.uuid = uuids.instance
|
||||||
|
instance.vm_state = vm_states.STOPPED
|
||||||
|
instance.task_state = task_states.REBOOT_STARTED_HARD
|
||||||
|
instance.power_state = power_state.SHUTDOWN
|
||||||
|
self._test_init_instance_cleans_reboot_state(instance)
|
||||||
|
|
||||||
|
def test_init_instance_cleans_shutdown_rebooting(self):
|
||||||
|
instance = objects.Instance(self.context)
|
||||||
|
instance.uuid = uuids.instance
|
||||||
|
instance.vm_state = vm_states.STOPPED
|
||||||
|
instance.task_state = task_states.REBOOTING
|
||||||
|
instance.power_state = power_state.SHUTDOWN
|
||||||
|
self._test_init_instance_cleans_reboot_state(instance)
|
||||||
|
|
||||||
|
def test_init_instance_cleans_shutdown_rebooting_hard(self):
|
||||||
|
instance = objects.Instance(self.context)
|
||||||
|
instance.uuid = uuids.instance
|
||||||
|
instance.vm_state = vm_states.STOPPED
|
||||||
|
instance.task_state = task_states.REBOOTING_HARD
|
||||||
|
instance.power_state = power_state.SHUTDOWN
|
||||||
|
self._test_init_instance_cleans_reboot_state(instance)
|
||||||
|
|
||||||
def test_init_instance_retries_power_off(self):
|
def test_init_instance_retries_power_off(self):
|
||||||
instance = objects.Instance(self.context)
|
instance = objects.Instance(self.context)
|
||||||
|
Loading…
Reference in New Issue
Block a user