bmc: assume powering-on state is ACTIVE

Inside newer deployments of OpenStack, it's possible that powering
on takes quite sometime especially with a large amount of ports
attached to the VM.  This is because Nova has to unplug and plug
all of the ports which can take a period of time.

During the period of time that Nova is starting the instance up,
the state of the VM is 'powering-on' and eventually it becomes
ACTIVE.  However, the IPMI status value presented is still offline
which is inaccurate.

In order to model this more towards a real bare metal environment,
we now maintain that 'powering-up' means the instance is active
which will let tools be able to move on with other steps like
PXE boot which was going to take sometime anyways.

If the booting fails, the instance will likely timeout and fail to
provision anyways, so we don't really lose much and on the next
refresh we'll figure out that state is SHUTOFF with no task state.

Change-Id: Ifa4d0152ec3086ef2e2b65e03a4499798964b78e
This commit is contained in:
Mohammed Naser 2019-12-09 16:05:13 -05:00
parent 07debc3613
commit 1b10ffd405
2 changed files with 28 additions and 5 deletions

View File

@ -88,6 +88,7 @@ class OpenStackBmc(bmc.Bmc):
self.instance = None
self.cache_status = cache_status
self.cached_status = None
self.cached_task = None
self.target_status = None
# At times the bmc service is started before important things like
# networking have fully initialized. Keep trying to find the
@ -154,11 +155,23 @@ class OpenStackBmc(bmc.Bmc):
sys.exit(0)
def _instance_active(self):
if (self.cached_status is None or
self.cached_status != self.target_status or
not self.cache_status):
self.cached_status = self.novaclient.servers.get(self.instance).status # noqa: E501
return self.cached_status == 'ACTIVE'
no_cached_data = (self.cached_status is None)
instance_changing_state = (self.cached_status != self.target_status)
cache_disabled = (not self.cache_status)
if (no_cached_data or instance_changing_state or cache_disabled):
instance = self.novaclient.servers.get(self.instance)
self.cached_status = instance.status
self.cached_task = getattr(instance, 'OS-EXT-STS:task_state')
instance_is_active = (self.cached_status == 'ACTIVE')
instance_is_shutoff = (self.cached_status == 'SHUTOFF')
instance_is_powering_on = (self.cached_task == 'powering-on')
return (
instance_is_active or
(instance_is_shutoff and instance_is_powering_on)
)
def get_power_state(self):
"""Returns the current power state of the managed instance"""

View File

@ -259,6 +259,7 @@ class TestOpenStackBmc(unittest.TestCase):
self.bmc.novaclient = self.mock_client
self.bmc.instance = 'abc-123'
self.bmc.cached_status = None
self.bmc.cached_task = None
self.bmc.target_status = None
self.bmc.cache_status = False
@ -369,6 +370,15 @@ class TestOpenStackBmc(unittest.TestCase):
self.assertTrue(self.bmc._instance_active())
self.assertFalse(self.mock_client.servers.get.called)
def test_instance_active_while_powering_on(self, mock_nova, mock_log,
mock_init):
self._create_bmc(mock_nova)
mock_server = mock.Mock()
mock_server.status = 'SHUTOFF'
setattr(mock_server, 'OS-EXT-STS:task_state', 'powering-on')
self.mock_client.servers.get.return_value = mock_server
self.assertTrue(self.bmc._instance_active())
def test_cache_disabled(self, mock_nova, mock_log, mock_init):
self._create_bmc(mock_nova)
self.bmc.target_status = 'ACTIVE'