Skip to content

Commit 16449cb

Browse files
committed
Grab fresh power state info from the driver
In drivers that use a cache to store the node info (presently only ironic since [1]), the "_get_power_state" function called during instance actions like start or stop grabs the information from the node cache and saves it in the nova database instead of getting fresh information from the driver. This leads to inconsistency between the vm_state and power_state for an instance in the nova database (which remains until a power_sync happens between nova and ironic). This can be confusing for a user when doing "nova list" where the power_state might still be shutdown when the vm_state has already become active. On a default environment this inconsistency lasts for about ten minutes which is the default value for the sync_power_state_interval interval. This patch changes the "use_cache" to False in the compute manager when triggering an action on an instance like start/stop/reboot. [1] I0069cbc327d952d42dbb8fe54949faab89995a7e Change-Id: I8bca5d84c37d02331d2f9968a674f3398c1a8f5b Closes-Bug: #1832720 (cherry picked from commit 5b1c9dd)
1 parent 31adec5 commit 16449cb

File tree

2 files changed

+18
-3
lines changed

2 files changed

+18
-3
lines changed

nova/compute/manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1289,7 +1289,7 @@ def _get_power_state(self, context, instance):
12891289
"""Retrieve the power state for the given instance."""
12901290
LOG.debug('Checking state', instance=instance)
12911291
try:
1292-
return self.driver.get_info(instance).state
1292+
return self.driver.get_info(instance, use_cache=False).state
12931293
except exception.InstanceNotFound:
12941294
return power_state.NOSTATE
12951295

nova/tests/unit/compute/test_compute_mgr.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,8 +1172,9 @@ def _test_init_instance_reverts_crashed_migrations(self,
11721172
mock_finish.assert_called_once_with(self.context, instance,
11731173
[], [], power_on)
11741174
mock_save.assert_called_once_with()
1175-
mock_get_info.assert_has_calls([mock.call(instance),
1176-
mock.call(instance)])
1175+
mock_get_info.assert_has_calls(
1176+
[mock.call(instance, use_cache=False),
1177+
mock.call(instance, use_cache=False)])
11771178
self.assertIsNone(instance.task_state)
11781179

11791180
def test_init_instance_reverts_crashed_migration_from_active(self):
@@ -1645,6 +1646,20 @@ def test_init_instance_retries_power_off_silent_exception(self):
16451646
self.compute.stop_instance.assert_has_calls([call])
16461647
self.assertIsNone(init_return)
16471648

1649+
def test_get_power_state(self):
1650+
instance = objects.Instance(self.context)
1651+
instance.uuid = uuids.instance
1652+
instance.id = 1
1653+
instance.vm_state = vm_states.STOPPED
1654+
instance.task_state = None
1655+
instance.host = self.compute.host
1656+
with mock.patch.object(self.compute.driver, 'get_info') as mock_info:
1657+
mock_info.return_value = hardware.InstanceInfo(
1658+
state=power_state.SHUTDOWN)
1659+
res = self.compute._get_power_state(self.context, instance)
1660+
mock_info.assert_called_once_with(instance, use_cache=False)
1661+
self.assertEqual(res, power_state.SHUTDOWN)
1662+
16481663
@mock.patch('nova.objects.InstanceList.get_by_filters')
16491664
def test_get_instances_on_driver(self, mock_instance_list):
16501665
driver_instances = []

0 commit comments

Comments
 (0)