70 lines
2.2 KiB
Python
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)
|