Switch to synchronous power on

The power on action is a job.  Previously the powervm driver would start
the job but not wait for it to complete.  This caused issues with
automation that sat on top of the OpenStack that the driver was part of.
The issue occurred because the power on job would be issued, but then
OpenStack would 'sync the power state' before the job completed.  This
caused an inconsistency between the states in OpenStack and the VM
itself.

This flew under the radar for a while because the power on job is quite
quick.  But this has started popping up on novalinks that have done
thousands of deploys or are at a bit higher deploy load.

Change-Id: I7ebef04bed4060bd8df9fb238b5965cd685b2d03
Closes-Bug: 1654262
This commit is contained in:
Drew Thorstensen 2017-01-05 07:58:31 -05:00
parent 07bfcd9856
commit d8582acb97
2 changed files with 15 additions and 15 deletions

View File

@ -336,7 +336,7 @@ class TestPowerVMDriver(test.TestCase):
self.apt, self.drv.host_wrapper, self.inst, self.inst.get_flavor(),
nvram=None, slot_mgr=self.slot_mgr)
self.assertTrue(mock_pwron.called)
self.assertFalse(mock_pwron.call_args[1]['synchronous'])
self.assertTrue(mock_pwron.call_args[1]['synchronous'])
# Assert that tasks that are not supposed to be called are not called
self.assertFalse(mock_conn_vol.called)
self.assertFalse(mock_crt_cfg_drv.called)
@ -371,7 +371,7 @@ class TestPowerVMDriver(test.TestCase):
# Power on was called
self.assertTrue(mock_pwron.called)
self.assertFalse(mock_pwron.call_args[1]['synchronous'])
self.assertTrue(mock_pwron.call_args[1]['synchronous'])
self.scrub_stg.assert_called_with(mock.ANY, self.stg_ftsk,
lpars_exist=True)
@ -419,7 +419,7 @@ class TestPowerVMDriver(test.TestCase):
nvram=None, slot_mgr=self.slot_mgr)
# Power on was called
self.assertTrue(mock_pwron.called)
self.assertFalse(mock_pwron.call_args[1]['synchronous'])
self.assertTrue(mock_pwron.call_args[1]['synchronous'])
# Check that the connect volume was called
self.assertEqual(2, self.vol_drv.connect_volume.call_count)
@ -483,7 +483,7 @@ class TestPowerVMDriver(test.TestCase):
nvram=None, slot_mgr=self.slot_mgr)
# Power on was called
self.assertTrue(mock_pwron.called)
self.assertFalse(mock_pwron.call_args[1]['synchronous'])
self.assertTrue(mock_pwron.call_args[1]['synchronous'])
# Check that the connect volume was called
self.assertEqual(2, self.vol_drv.connect_volume.call_count)
@ -532,7 +532,7 @@ class TestPowerVMDriver(test.TestCase):
nvram=None, slot_mgr=self.slot_mgr)
# Power on was called
self.assertTrue(mock_pwron.called)
self.assertFalse(mock_pwron.call_args[1]['synchronous'])
self.assertTrue(mock_pwron.call_args[1]['synchronous'])
# Check that the connect volume was called
self.assertEqual(2, self.vol_drv.connect_volume.call_count)
@ -652,7 +652,7 @@ class TestPowerVMDriver(test.TestCase):
# Power on was called
self.assertTrue(mock_pwron.called)
self.assertFalse(mock_pwron.call_args[1]['synchronous'])
self.assertTrue(mock_pwron.call_args[1]['synchronous'])
# Validate the rollbacks were called
self.assertEqual(2, self.vol_drv.disconnect_volume.call_count)
@ -704,7 +704,7 @@ class TestPowerVMDriver(test.TestCase):
# Power on was called
self.assertTrue(mock_pwron.called)
self.assertFalse(mock_pwron.call_args[1]['synchronous'])
self.assertTrue(mock_pwron.call_args[1]['synchronous'])
# Check that the connect volume was called
self.assertEqual(2, self.vol_drv.connect_volume.call_count)
@ -758,7 +758,7 @@ class TestPowerVMDriver(test.TestCase):
self.inst_ibmi.get_flavor(), nvram=None, slot_mgr=self.slot_mgr)
self.assertTrue(mock_update_lod_src.called)
self.assertTrue(mock_pwron.called)
self.assertFalse(mock_pwron.call_args[1]['synchronous'])
self.assertTrue(mock_pwron.call_args[1]['synchronous'])
# Assert that tasks that are not supposed to be called are not called
self.assertFalse(mock_conn_vol.called)
self.assertFalse(mock_crt_cfg_drv.called)
@ -1506,7 +1506,7 @@ class TestPowerVMDriver(test.TestCase):
self.assertTrue(mock_disk_dvr.create_disk_from_image.called)
self.assertTrue(mock_disk_dvr.connect_disk.called)
self.assertTrue(mock_task_pwr.power_on.called)
self.assertFalse(mock_task_pwr.power_on.call_args[1]['synchronous'])
self.assertTrue(mock_task_pwr.power_on.call_args[1]['synchronous'])
@mock.patch('nova_powervm.virt.powervm.vm')
@mock.patch('nova_powervm.virt.powervm.tasks.vm.vm')
@ -1521,7 +1521,7 @@ class TestPowerVMDriver(test.TestCase):
self.assertTrue(mock_disk_dvr.disconnect_image_disk.called)
self.assertTrue(mock_disk_dvr.delete_disks.called)
self.assertTrue(mock_task_pwr.power_on.called)
self.assertFalse(mock_task_pwr.power_on.call_args[1]['synchronous'])
self.assertTrue(mock_task_pwr.power_on.call_args[1]['synchronous'])
@mock.patch('nova_powervm.virt.powervm.driver.LOG')
def test_log_op(self, mock_log):

View File

@ -196,7 +196,7 @@ class PowerOn(pvm_task.PowerVMTask):
"""The task to power on the instance."""
def __init__(self, adapter, host_uuid, instance, pwr_opts=None,
synchronous=False):
synchronous=True):
"""Create the Task for the power on of the LPAR.
Obtains LPAR info through requirement of lpar_wrap (provided by
@ -206,10 +206,10 @@ class PowerOn(pvm_task.PowerVMTask):
:param host_uuid: The host UUID.
:param instance: The nova instance.
:param pwr_opts: Additional parameters for the pypowervm PowerOn Job.
:param synchronous: (Optional) If False (the default), the Task
completes as soon as the pypowervm PowerOn Job has
successfully started. If True, the Task waits for
the pypowervm PowerOn Job to complete.
:param synchronous: (Optional) If False, the Task completes as soon as
the pypowervm PowerOn Job has successfully started.
If True (the default), the Task waits for the
pypowervm PowerOn Job to complete.
"""
super(PowerOn, self).__init__(
instance, 'pwr_vm', requires=['lpar_wrap'])