update/software/software/deploy_host_state.py

70 lines
2.2 KiB
Python

"""
Copyright (c) 2024 Wind River Systems, Inc.
SPDX-License-Identifier: Apache-2.0
"""
import logging
from software.db.api import get_instance
from software.exceptions import InvalidOperation
from software.states import DEPLOY_HOST_STATES
LOG = logging.getLogger('main_logger')
deploy_host_state_transition = {
DEPLOY_HOST_STATES.PENDING: [DEPLOY_HOST_STATES.DEPLOYING],
DEPLOY_HOST_STATES.DEPLOYING: [DEPLOY_HOST_STATES.DEPLOYED, DEPLOY_HOST_STATES.FAILED],
DEPLOY_HOST_STATES.FAILED: [DEPLOY_HOST_STATES.DEPLOYING],
DEPLOY_HOST_STATES.DEPLOYED: []
}
class DeployHostState(object):
_callbacks = []
@staticmethod
def register_event_listener(callback):
if callback not in DeployHostState._callbacks:
LOG.info("Register event listener %s", callback.__qualname__)
DeployHostState._callbacks.append(callback)
def __init__(self, hostname):
self._hostname = hostname
def check_transition(self, target_state: DEPLOY_HOST_STATES):
db_api = get_instance()
deploy_host = db_api.get_deploy_host_by_hostname(self._hostname)
if deploy_host is not None:
cur_state = DEPLOY_HOST_STATES(deploy_host['state'])
if target_state in deploy_host_state_transition[cur_state]:
return True
else:
LOG.error('Host %s is not part of deployment' % self._hostname)
return False
def transform(self, target_state: DEPLOY_HOST_STATES):
db_api = get_instance()
db_api.begin_update()
try:
if self.check_transition(target_state):
db_api.update_deploy_host(self._hostname, target_state)
for callback in DeployHostState._callbacks:
callback(self._hostname, target_state)
else:
msg = "Host can not transform to %s from current state" % target_state.value
raise InvalidOperation(msg)
finally:
db_api.end_update()
def deploy_started(self):
self.transform(DEPLOY_HOST_STATES.DEPLOYING)
def deployed(self):
self.transform(DEPLOY_HOST_STATES.DEPLOYED)
def deploy_failed(self):
self.transform(DEPLOY_HOST_STATES.FAILED)