Files
distcloud/distributedcloud/dcmanager/manager/states/unlock_host.py
albailey 5e5c416a9b Implement import-load and starting-upgrade strategy states
This commit allows the state machine to be defined through an
ordered list of states. The states are mapped to by a dictionary
to state handler classes.

This greatly simplifies the software upgrade orch thread so that it
can be refactored in the future to share functionality with other orch
thread strategy types.

The following states have been implemented:
 - 'importing load'
 - 'starting upgrade'
 - 'activating upgrade'
 - 'completing upgrade'

The 'installing license' state now uses this design pattern.
Its functionality and unit tests are now in their own files.

The 'unlocking' state requires additional changes for the
'activating' and 'completing' states to pass.

Change-Id: Iedc40bdea406461dd4c2ce3887a37be6ec3c999f
Story: 2007403
Task: 40001
Signed-off-by: albailey <Al.Bailey@windriver.com>
2020-06-09 15:34:27 -05:00

78 lines
3.0 KiB
Python

#
# Copyright (c) 2020 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
import time
from dcmanager.common.consts import ADMIN_UNLOCKED
from dcmanager.manager.states.base import BaseState
DEFAULT_MAX_QUERIES = 6
DEFAULT_SLEEP_DURATION = 10
class UnlockHostState(BaseState):
"""Orchestration state for unlocking a host"""
def __init__(self,
hostname='controller-0',
max_queries=DEFAULT_MAX_QUERIES,
sleep_duration=DEFAULT_SLEEP_DURATION):
super(UnlockHostState, self).__init__()
self.target_hostname = hostname
# max time to wait (in seconds) is: sleep_duration * max_queries
self.sleep_duration = sleep_duration
self.max_queries = max_queries
def check_async_counter(self, counter):
if counter >= self.max_queries:
raise Exception("Timeout waiting for unlock to complete")
time.sleep(self.sleep_duration)
def perform_state_action(self, strategy_step):
"""Unlocks a host on the subcloud
Any exceptions raised by this method set the strategy to FAILED
Returning normally from this method set the strategy to the next step
"""
# Create a sysinv client on the subcloud
ks_client = self.get_keystone_client(strategy_step.subcloud.name)
sysinv_client = self.get_sysinv_client(strategy_step.subcloud.name,
ks_client.session)
host = sysinv_client.get_host(self.target_hostname)
# if the host is already in the desired state, no need for action
if host.administrative == ADMIN_UNLOCKED:
msg = "Host: %s already: %s." % (self.target_hostname,
host.administrative)
self.info_log(strategy_step, msg)
return True
# Invoke the action
# ihost_action is 'unlock' and task is set to 'Unlocking'
response = sysinv_client.unlock_host(host.id)
if (response.ihost_action != 'unlock' or response.task != 'Unlocking'):
raise Exception("Unable to unlock host %s" % self.target_hostname)
# this action is asynchronous, query until it completes or times out
async_counter = 0
while True:
# query the administrative state to see if it is the new state.
host = sysinv_client.get_host(self.target_hostname)
if host.administrative == ADMIN_UNLOCKED:
msg = "Host: %s is now: %s" % (self.target_hostname,
host.administrative)
self.info_log(strategy_step, msg)
break
async_counter += 1
# check_async_counter throws exception if loops exceeded or aborted
self.check_async_counter(async_counter)
# If we are here, the loop broke out cleanly and the action succeeded
# When we return from this method without throwing an exception, the
# state machine can proceed to the next state
return True