sw-deploy API for simplex deployment

sw-deploy API implementation and create
strategy validations.

Test Plan:
PASSED: On a DX system, when active alarm is present
perform precheck on an in-service patch, precheck fails.
PASSED: On a DX system, there is no active alarm and
system is in healthy state, perform precheck on an
in-service patch, precheck is successful.
PASSED: On a DX system, there is no active alarm and
system is in healthy state, perform precheck on in-service
patch, precheck is successful.
PASSED: On a DX system, try to perform precheck on
an in-service patch when there is another minor release
which is in 'deploy-start' state, precheck fails.
PASSED: On a DX system, perfrom software deploy start on
an in-service patch,with change in release state,
start API is successful.
PASSED: On DX system, perform software deploy start
on an in-service patch, with no change in release state,
start API fails.
PASSED: On SX system, perform end to end sw-deploy strategy
update using in-service patch.

Story: 2011045
Task: 49911

Change-Id: I265c8a1f9fbadf04275e0af788614d094c23315c
Signed-off-by: Vanathi.Selvaraju <vanathi.selvaraju@windriver.com>
This commit is contained in:
Vanathi.Selvaraju 2024-04-22 11:43:42 -04:00
parent 6142d9f116
commit 371092ce9c
11 changed files with 269 additions and 143 deletions

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2015-2016 Wind River Systems, Inc.
# Copyright (c) 2015-2016,2024 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
@ -9,6 +9,8 @@ from nfv_common.tasks._task_work import TaskWork
DLOG = debug.debug_get_logger('nfv_common.tasks.task_future')
TASK_TIMEOUT = 600
class TaskFuture(object):
"""
@ -57,7 +59,9 @@ class TaskFuture(object):
if timeout_in_secs is None:
# WARNING: Any change to the default timeout must be reflected in
# the timeouts used for any work being done.
timeout_in_secs = 20
# The timeout to be changed back to 20sec when the start
# software-api is async for patch-release
timeout_in_secs = TASK_TIMEOUT
elif 0 >= timeout_in_secs:
timeout_in_secs = None # No timeout wanted, wait forever

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2015-2016 Wind River Systems, Inc.
# Copyright (c) 2015-2016,2024 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
@ -94,7 +94,7 @@ class Thread(object):
self._stall_timestamp_ms = \
timers.get_monotonic_timestamp_in_ms()
DLOG.error("Thread %s stalled, progress_marker=%s, "
DLOG.warn("Thread %s stalled, progress_marker=%s, "
"elapsed_secs=%s." % (self._name,
self._progress_marker.value,
self.stall_elapsed_secs))

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2015-2018 Wind River Systems, Inc.
# Copyright (c) 2015-2018,2024 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
@ -125,3 +125,4 @@ glance.upload_image_data_by_file=180
glance.upload_image_data_by_url=180
sysinv=60
patching.apply_patch=180
usm=60

View File

@ -2234,7 +2234,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
return
release_data = future.result.data
release_info = release_data["metadata"].get(release, None)
release_info = release_data
future.work(usm.sw_deploy_host_list, self._platform_token)
future.result = (yield)
@ -2244,11 +2244,13 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
return
hosts_info_data = future.result.data
if hosts_info_data == []:
hosts_info_data = None
upgrade_obj = nfvi.objects.v1.Upgrade(
release,
release_info,
hosts_info_data["data"],
hosts_info_data,
)
response['result-data'] = upgrade_obj
@ -2297,17 +2299,13 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
future.work(usm.sw_deploy_precheck, self._platform_token, release)
future.result = (yield)
if not future.result.is_complete():
DLOG.error("USM software deploy precheck did not complete.")
return
upgrade_obj = nfvi.objects.v1.Upgrade(
release,
None,
None)
precheck_data = future.result.data['error']
response['result-data'] = upgrade_obj
response['result-data'] = precheck_data
response['completed'] = True
except exceptions.OpenStackRestAPIException as e:
@ -2328,7 +2326,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
callback.send(response)
callback.close()
def upgrade_start(self, future, release, callback):
def sw_deploy_start(self, future, release, callback):
"""
Start a USM software deploy
"""
@ -2337,9 +2335,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
response['reason'] = ''
try:
upgrade_data = future.result.data
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
if self._platform_token is None or \
self._platform_token.is_expired():
future.work(openstack.get_token, self._platform_directory)
@ -2354,15 +2350,33 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
future.work(usm.sw_deploy_start, self._platform_token, release)
future.result = (yield)
if not future.result.is_complete():
DLOG.error("USM software deploy start did not complete.")
return
# TODO(vselvara): remove the state check here once the api is changed
# to async. state check to be done in _strategy_steps.py
future.work(usm.sw_deploy_host_list, self._platform_token)
future.result = (yield)
if not future.result.is_complete():
DLOG.error("USM software deploy host list did not complete.")
return
hosts_info_data = future.result.data
future.work(usm.sw_deploy_show, self._platform_token)
future.result = (yield)
if not future.result.is_complete():
DLOG.error("USM software deploy host show did not complete.")
return
state_info = future.result.data
upgrade_obj = nfvi.objects.v1.Upgrade(
release,
upgrade_data,
None)
state_info,
hosts_info_data,
)
response['result-data'] = upgrade_obj
response['completed'] = True
@ -2385,7 +2399,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
callback.send(response)
callback.close()
def upgrade_activate(self, future, release, callback):
def sw_deploy_activate(self, future, release, callback):
"""
Activate a USM software deployement
"""
@ -2408,17 +2422,25 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
self._platform_token = future.result.data
future.work(usm.sw_deploy_activate, self._platform_token, release)
future.work(usm.sw_deploy_activate, self._platform_token)
future.result = (yield)
if not future.result.is_complete():
DLOG.error("USM software deploy activate did not complete.")
return
upgrade_data = future.result.data
future.work(usm.sw_deploy_show, self._platform_token)
future.result = (yield)
if not future.result.is_complete():
DLOG.error("USM software deploy show did not complete.")
return
state_info = future.result.data
upgrade_obj = nfvi.objects.v1.Upgrade(
release,
upgrade_data,
state_info,
None)
response['result-data'] = upgrade_obj
@ -2442,7 +2464,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
callback.send(response)
callback.close()
def upgrade_complete(self, future, release, callback):
def sw_deploy_complete(self, future, release, callback):
"""
Complete a USM software deployement
"""
@ -2465,17 +2487,25 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
self._platform_token = future.result.data
future.work(usm.sw_deploy_complete, self._platform_token, release)
future.work(usm.sw_deploy_complete, self._platform_token)
future.result = (yield)
if not future.result.is_complete():
DLOG.error("USM software deploy complete did not complete.")
return
upgrade_data = future.result.data
future.work(usm.sw_deploy_get_release, self._platform_token, release)
future.result = (yield)
if not future.result.is_complete():
DLOG.error("USM software deploy get release did not complete.")
return
state_info = future.result.data
upgrade_obj = nfvi.objects.v1.Upgrade(
release,
upgrade_data,
state_info,
None)
response['result-data'] = upgrade_obj
@ -3659,6 +3689,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
future.result = (yield)
if not future.result.is_complete():
DLOG.error("USM software deploy host did not complete.")
return
response['completed'] = True

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2015-2023 Wind River Systems, Inc.
# Copyright (c) 2015-2024 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
@ -32,6 +32,8 @@ from nfv_plugins.nfvi_plugins.openstack.openstack_log import log_info
DLOG = debug.debug_get_logger('nfv_plugins.nfvi_plugins.openstack.rest_api')
REST_API_TIMEOUT = 600
class RestAPIRequestDispatcher(BaseHTTPServer.BaseHTTPRequestHandler):
"""
@ -473,7 +475,7 @@ def rest_api_request(token,
api_cmd,
api_cmd_headers=None,
api_cmd_payload=None,
timeout_in_secs=20,
timeout_in_secs=REST_API_TIMEOUT,
file_to_post=None):
"""
Make a rest-api request using the given token

View File

@ -56,7 +56,18 @@ def _api_post(token, url, payload, headers=None):
url,
headers,
json.dumps(payload),
timeout_in_secs=REST_API_REQUEST_TIMEOUT)
timeout_in_secs=600)
return response
def sw_deploy_get_all_release(token):
"""
Query USM for information about all releases
"""
uri = f"query?show=all" # noqa:F541 pylint: disable=W1309
url = _usm_api_cmd(token, uri)
response = _api_get(token, url)
return response
@ -65,7 +76,18 @@ def sw_deploy_get_release(token, release):
Query USM for information about a specific upgrade
"""
uri = f"show/{release}"
uri = f"show/{release}" # noqa:F541 pylint: disable=W1309
url = _usm_api_cmd(token, uri)
response = _api_get(token, url)
return response
def sw_deploy_show(token):
"""
Query USM for information about a specific upgrade
"""
uri = f"deploy" # noqa:F541 pylint: disable=W1309
url = _usm_api_cmd(token, uri)
response = _api_get(token, url)
return response
@ -88,7 +110,8 @@ def sw_deploy_precheck(token, release, force=False):
Ask USM to precheck before a deployment
"""
uri = f"deploy_precheck/{release}/force" if force else f"deploy_precheck/{release}"
uri = (f"deploy_precheck/{release}/force?region_name=RegionOne" if
force else f"deploy_precheck/{release}?region_name=RegionOne")
url = _usm_api_cmd(token, uri)
response = _api_post(token, url, {})
return response
@ -116,23 +139,23 @@ def sw_deploy_execute(token, host_name):
return response
def sw_deploy_activate(token, release):
def sw_deploy_activate(token):
"""
Ask USM activate a deployment
"""
uri = f"deploy_activate/{release}"
uri = f"deploy_activate" # noqa:F541 pylint: disable=W1309
url = _usm_api_cmd(token, uri)
response = _api_post(token, url, {})
return response
def sw_deploy_complete(token, release):
def sw_deploy_complete(token):
"""
Ask USM complete a deployment
"""
uri = f"deploy_complete/{release}"
uri = f"deploy_complete" # noqa:F541 pylint: disable=W1309
url = _usm_api_cmd(token, uri)
response = _api_post(token, url, {})
return response

View File

@ -189,10 +189,12 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
release=release,
nfvi_upgrade=nfvi.objects.v1.Upgrade(
release,
{
[
{
'state': 'available',
'reboot_required': 'N',
},
}
],
None,
)
)
@ -205,11 +207,9 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
'total_stages': 1,
'stages': [
{'name': 'sw-upgrade-start',
'total_steps': 4,
'total_steps': 3,
'steps': [
{'name': 'query-alarms'},
{'name': 'sw-deploy-precheck',
'release': release},
{'name': 'start-upgrade',
'release': release},
{'name': 'system-stabilize',
@ -237,10 +237,12 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
release=release,
nfvi_upgrade=nfvi.objects.v1.Upgrade(
release,
{
[
{
'state': 'available',
'reboot_required': 'N',
},
}
],
None,
)
)
@ -253,11 +255,9 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
'total_stages': 1,
'stages': [
{'name': 'sw-upgrade-start',
'total_steps': 4,
'total_steps': 3,
'steps': [
{'name': 'query-alarms'},
{'name': 'sw-deploy-precheck',
'release': release},
{'name': 'start-upgrade',
'release': release},
{'name': 'system-stabilize',
@ -286,10 +286,12 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
release=release,
nfvi_upgrade=nfvi.objects.v1.Upgrade(
release,
{
[
{
'state': 'available',
'reboot_required': 'N',
},
}
],
None,
)
)
@ -302,13 +304,11 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
'total_stages': 1,
'stages': [
{'name': 'sw-upgrade-start',
'total_steps': 6,
'total_steps': 5,
'steps': [
{'name': 'query-alarms'},
{'name': 'swact-hosts',
'entity_names': ['controller-1']},
{'name': 'sw-deploy-precheck',
'release': release},
{'name': 'start-upgrade',
'release': release},
{'name': 'system-stabilize',
@ -340,10 +340,12 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
release=release,
nfvi_upgrade=nfvi.objects.v1.Upgrade(
release,
{
[
{
'state': 'available',
'reboot_required': 'N',
},
}
],
None,
)
)
@ -388,10 +390,10 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
release=release,
nfvi_upgrade=nfvi.objects.v1.Upgrade(
release,
{
[{
'state': 'available',
'reboot_required': 'N',
},
}],
None,
)
)
@ -437,10 +439,10 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
release=release,
nfvi_upgrade=nfvi.objects.v1.Upgrade(
release,
{
[{
'state': 'available',
'reboot_required': 'N',
},
}],
None,
)
)
@ -889,7 +891,7 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
_, strategy = self._gen_aiosx_hosts_and_strategy(
nfvi_upgrade=nfvi.objects.v1.Upgrade(
'13.01',
{'state': 'deployed'},
[{'state': 'deployed'}],
None,
)
)
@ -916,7 +918,7 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
_, strategy = self._gen_aiosx_hosts_and_strategy(
nfvi_upgrade=nfvi.objects.v1.Upgrade(
'13.01',
{'state': 'committed'},
[{'state': 'committed'}],
None,
)
)
@ -975,10 +977,12 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
release=release,
nfvi_upgrade=nfvi.objects.v1.Upgrade(
release,
{
[
{
'state': 'available',
'reboot_required': 'N',
},
}
],
None,
)
)
@ -994,10 +998,9 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
'stages': [
{
'name': 'sw-upgrade-start',
'total_steps': 4,
'total_steps': 3,
'steps': [
{'name': 'query-alarms'},
{'name': 'sw-deploy-precheck', 'release': release},
{'name': 'start-upgrade', 'release': release},
{'name': 'system-stabilize', 'timeout': 60},
],
@ -1041,10 +1044,10 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
release=release,
nfvi_upgrade=nfvi.objects.v1.Upgrade(
release,
{
[{
'state': 'available',
'reboot_required': 'Y',
},
}],
None,
)
)
@ -1060,10 +1063,9 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
'stages': [
{
'name': 'sw-upgrade-start',
'total_steps': 4,
'total_steps': 3,
'steps': [
{'name': 'query-alarms'},
{'name': 'sw-deploy-precheck', 'release': release},
{'name': 'start-upgrade', 'release': release},
{'name': 'system-stabilize', 'timeout': 60},
],
@ -1111,10 +1113,10 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
release=release,
nfvi_upgrade=nfvi.objects.v1.Upgrade(
release,
{
[{
'state': 'available',
'reboot_required': 'N',
},
}],
None,
)
)
@ -1130,10 +1132,9 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
'stages': [
{
'name': 'sw-upgrade-start',
'total_steps': 4,
'total_steps': 3,
'steps': [
{'name': 'query-alarms'},
{'name': 'sw-deploy-precheck', 'release': release},
{'name': 'start-upgrade', 'release': release},
{'name': 'system-stabilize', 'timeout': 60},
],
@ -1186,10 +1187,10 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
release=release,
nfvi_upgrade=nfvi.objects.v1.Upgrade(
release,
{
[{
'state': 'available',
'reboot_required': 'Y',
},
}],
None,
)
)
@ -1205,10 +1206,9 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
'stages': [
{
'name': 'sw-upgrade-start',
'total_steps': 4,
'total_steps': 3,
'steps': [
{'name': 'query-alarms'},
{'name': 'sw-deploy-precheck', 'release': release},
{'name': 'start-upgrade', 'release': release},
{'name': 'system-stabilize', 'timeout': 60},
],
@ -1273,10 +1273,10 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
release=release,
nfvi_upgrade=nfvi.objects.v1.Upgrade(
release,
{
[{
'state': 'available',
'reboot_required': 'N',
},
}],
None,
)
)
@ -1292,10 +1292,9 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
'stages': [
{
'name': 'sw-upgrade-start',
'total_steps': 4,
'total_steps': 3,
'steps': [
{'name': 'query-alarms'},
{'name': 'sw-deploy-precheck', 'release': release},
{'name': 'start-upgrade', 'release': release},
{'name': 'system-stabilize', 'timeout': 60},
],
@ -1370,10 +1369,10 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
release=release,
nfvi_upgrade=nfvi.objects.v1.Upgrade(
release,
{
[{
'state': 'available',
'reboot_required': 'Y',
},
}],
None,
)
)
@ -1389,10 +1388,9 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
'stages': [
{
'name': 'sw-upgrade-start',
'total_steps': 4,
'total_steps': 3,
'steps': [
{'name': 'query-alarms'},
{'name': 'sw-deploy-precheck', 'release': release},
{'name': 'start-upgrade', 'release': release},
{'name': 'system-stabilize', 'timeout': 60},
],

View File

@ -76,10 +76,10 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
if nfvi_upgrade is True:
nfvi_upgrade = nfvi.objects.v1.Upgrade(
release,
{
[{
'state': 'available',
'reboot_required': 'Y',
},
}],
None,
)
@ -1400,11 +1400,9 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
'total_stages': 8,
'stages': [
{'name': 'sw-upgrade-start',
'total_steps': 4,
'total_steps': 3,
'steps': [
{'name': 'query-alarms'},
{'name': 'sw-deploy-precheck',
'release': strategy.nfvi_upgrade.release},
{'name': 'start-upgrade',
'release': strategy.nfvi_upgrade.release},
{'name': 'system-stabilize',
@ -1570,13 +1568,11 @@ class TestSwUpgradeStrategy(sw_update_testcase.SwUpdateStrategyTestCase):
'total_stages': 6,
'stages': [
{'name': 'sw-upgrade-start',
'total_steps': 6,
'total_steps': 5,
'steps': [
{'name': 'query-alarms'},
{'name': 'swact-hosts',
'entity_names': ['controller-1']},
{'name': 'sw-deploy-precheck',
'release': strategy.nfvi_upgrade.release},
{'name': 'start-upgrade',
'release': strategy.nfvi_upgrade.release},
{'name': 'system-stabilize',

View File

@ -33,17 +33,17 @@ class Upgrade(ObjectData):
@property
def state(self):
if self.release_info is None:
if not self.release_info:
return None
return self.release_info["state"]
return self.release_info[0]["state"]
@property
def reboot_required(self):
if self.release_info is None:
if not self.release_info:
return None
return self.release_info["reboot_required"] == USM_REBOOT_REQUIRED
return self.release_info[0]["reboot_required"] == USM_REBOOT_REQUIRED
@property
def is_available(self):

View File

@ -10,6 +10,7 @@ import weakref
from nfv_common import debug
from nfv_common.helpers import Constant
from nfv_common.helpers import Constants
from nfv_common.helpers import coroutine
from nfv_common.helpers import get_local_host_name
from nfv_common.helpers import Singleton
from nfv_common import strategy
@ -1804,6 +1805,49 @@ class SwUpgradeStrategy(
"""
self._nfvi_upgrade = nfvi_upgrade
@coroutine
def _sw_deploy_precheck_callback(self):
"""
Software deploy precheck callback
"""
response = (yield)
DLOG.debug("sw-deploy precheck callback response=%s." % response)
if response['completed']:
if not response['result-data']:
DLOG.debug("sw-deploy precheck completed %s" % response['result-data'])
else:
reason = "sw-deploy precheck failed"
# todo: (vselvara) to display the entire erorr response
# reason = response['result-data']
DLOG.warn(reason)
self._state = strategy.STRATEGY_STATE.BUILD_FAILED
self.build_phase.result = strategy.STRATEGY_PHASE_RESULT.FAILED
self.build_phase.result_reason = reason
self.sw_update_obj.strategy_build_complete(
False, self.build_phase.result_reason)
self.save()
else:
reason = "sw-deploy precheck operation not completed"
DLOG.warn(reason)
self._state = strategy.STRATEGY_STATE.BUILD_FAILED
self.build_phase.result = strategy.STRATEGY_PHASE_RESULT.FAILED
self.build_phase.result_reason = reason
self.sw_update_obj.strategy_build_complete(
False, self.build_phase.result_reason)
self.save()
return
def sw_deploy_precheck(self, release):
"""
Software deploy precheck
"""
from nfv_vim import nfvi
DLOG.info("Software deploy precheck for %s." % release)
nfvi._nfvi_infrastructure_module.nfvi_sw_deploy_precheck(release,
self._sw_deploy_precheck_callback())
def build(self):
"""
Build the strategy
@ -1812,6 +1856,7 @@ class SwUpgradeStrategy(
stage = strategy.StrategyStage(strategy.STRATEGY_STAGE_NAME.SW_UPGRADE_QUERY)
stage.add_step(strategy.QueryAlarmsStep(ignore_alarms=self._ignore_alarms))
self.sw_deploy_precheck(release=self._release)
stage.add_step(strategy.QueryUpgradeStep(release=self._release))
self.build_phase.add_stage(stage)
@ -1852,7 +1897,6 @@ class SwUpgradeStrategy(
if self.nfvi_upgrade.is_available:
# sw-deploy start must be done on controller-0
self._swact_fix(stage, HOST_NAME.CONTROLLER_1)
stage.add_step(strategy.SwDeployPrecheckStep(release=self._release))
stage.add_step(strategy.UpgradeStartStep(release=self._release))
stage.add_step(strategy.SystemStabilizeStep())
# sw-deploy host must first be on controller-1
@ -1890,8 +1934,7 @@ class SwUpgradeStrategy(
if result in [strategy.STRATEGY_RESULT.SUCCESS,
strategy.STRATEGY_RESULT.DEGRADED]:
if self.nfvi_upgrade.release_info is None:
if not self.nfvi_upgrade.release_info:
reason = "Software release does not exist."
DLOG.warn(reason)
self._state = strategy.STRATEGY_STATE.BUILD_FAILED

View File

@ -24,6 +24,11 @@ KUBE_CERT_UPDATE_TRUSTBOTHCAS = "trust-both-cas"
KUBE_CERT_UPDATE_TRUSTNEWCA = "trust-new-ca"
KUBE_CERT_UPDATE_UPDATECERTS = "update-certs"
# sw-deploy strategy constants
SW_DEPLOY_START = 'start-done'
SW_HOST_DEPLOYED = 'deployed'
SW_DEPLOY_ACTIVATE_DONE = 'activate-done'
@six.add_metaclass(Singleton)
class StrategyStepNames(Constants):
@ -930,26 +935,37 @@ class UpgradeHostsStep(strategy.StrategyStep):
self._host_names.append(host.name)
self._host_uuids.append(host.uuid)
self._wait_time = 0
self._query_inprogress = False
def _total_hosts_upgraded(self):
@coroutine
def _get_upgrade_callback(self):
"""
Returns the number of hosts that are upgraded
Get Upgrade Callback
"""
# TODO(jkraitbe): Use deploy/host_list instead
total_hosts_upgraded = 0
host_table = tables.tables_get_host_table()
for host_name in self._host_names:
host = host_table.get(host_name, None)
if host is None:
return -1
if (host.is_online() and
host.target_load == self.strategy.nfvi_upgrade.release and
host.software_load == self.strategy.nfvi_upgrade.release):
total_hosts_upgraded += 1
return total_hosts_upgraded
response = (yield)
DLOG.debug("Query-Upgrade callback response=%s." % response)
self._query_inprogress = False
if response['completed']:
self.strategy.nfvi_upgrade = response['result-data']
host_count = 0
match_count = 0
host_info_list = self.strategy.nfvi_upgrade['hosts_info']
for host_name in self._host_names:
for host in host_info_list:
if (host_name == host['hostname']) and (host['host_state'] == SW_HOST_DEPLOYED):
match_count += 1
host_count += 1
if match_count == len(self._host_names):
result = strategy.STRATEGY_STEP_RESULT.SUCCESS
DLOG.info("Upgrade Hosts completed")
self.stage.step_complete(result, "")
else:
# keep waiting for Upgrade host state to change
pass
else:
result = strategy.STRATEGY_STEP_RESULT.FAILED
DLOG.info("Host Upgrade failed")
self.stage.step_complete(result, response['reason'])
def apply(self):
"""
@ -972,6 +988,8 @@ class UpgradeHostsStep(strategy.StrategyStep):
"""
Handle Host events
"""
from nfv_vim import nfvi
DLOG.debug("Step (%s) handle event (%s)." % (self._name, event))
if event == STRATEGY_EVENT.HOST_UPGRADE_FAILED:
@ -989,19 +1007,11 @@ class UpgradeHostsStep(strategy.StrategyStep):
secs_expired = (now_ms - self._wait_time) // 1000
# Wait at least 2 minutes for the host to go offline before
# checking whether the upgrade is complete.
if 120 <= secs_expired:
total_hosts_upgraded = self._total_hosts_upgraded()
if -1 == total_hosts_upgraded:
result = strategy.STRATEGY_STEP_RESULT.FAILED
self.stage.step_complete(result, "host no longer exists")
return True
if total_hosts_upgraded == len(self._host_names):
result = strategy.STRATEGY_STEP_RESULT.SUCCESS
self.stage.step_complete(result, '')
return True
if 120 <= secs_expired and not self._query_inprogress:
self._query_inprogress = True
release = self.strategy.nfvi_upgrade['release']
nfvi.nfvi_get_upgrade(release, self._get_upgrade_callback())
return True
return False
def from_dict(self, data):
@ -1020,6 +1030,7 @@ class UpgradeHostsStep(strategy.StrategyStep):
self._hosts.append(host)
self._host_uuids.append(host.uuid)
self._wait_time = 0
self._query_inprogress = False
return self
def as_dict(self):
@ -1107,15 +1118,21 @@ class UpgradeStartStep(strategy.StrategyStep):
"""
response = (yield)
DLOG.debug("Start-Upgrade callback response=%s." % response)
if response['completed']:
# TODO(jkraitbe): Consider updating self.strategy.nfvi_upgrade.hosts_info
result = strategy.STRATEGY_STEP_RESULT.SUCCESS
self.stage.step_complete(result, "")
state_info = response['result-data']['release_info'][0]['state']
if state_info == SW_DEPLOY_START:
result = strategy.STRATEGY_STEP_RESULT.SUCCESS
self.stage.step_complete(result, "")
else:
reason = "Software deploy not started. Current state:%s" % state_info
result = strategy.STRATEGY_STEP_RESULT.FAILED
self.stage.step_complete(result, reason)
else:
# TODO(jkraitbe): Add error message
reason = "Software deploy start not completed"
result = strategy.STRATEGY_STEP_RESULT.FAILED
self.stage.step_complete(result, "")
self.stage.step_complete(result, reason)
def apply(self):
"""
@ -1165,15 +1182,20 @@ class UpgradeActivateStep(strategy.StrategyStep):
Activate Upgrade Callback
"""
response = (yield)
DLOG.debug("Activate-Upgrade callback response=%s." % response)
self.strategy.nfvi_upgrade = response['result-data']
if response['completed']:
result = strategy.STRATEGY_STEP_RESULT.SUCCESS
self.stage.step_complete(result, "")
state_info = self.strategy.nfvi_upgrade['release_info'][0]['state']
if state_info == SW_DEPLOY_ACTIVATE_DONE:
result = strategy.STRATEGY_STEP_RESULT.SUCCESS
self.stage.step_complete(result, "")
else:
reason = "SW Deploy Activate not successful. Current state:%s" % state_info
result = strategy.STRATEGY_STEP_RESULT.FAILED
self.stage.step_complete(result, reason)
else:
# TODO(jkraitbe): Add error message
reason = "SW Deploy Activate not complete. Current response:%s" % response['result-data']
result = strategy.STRATEGY_STEP_RESULT.FAILED
self.stage.step_complete(result, "")
self.stage.step_complete(result, reason)
def apply(self):
"""
@ -1224,14 +1246,20 @@ class UpgradeCompleteStep(strategy.StrategyStep):
"""
response = (yield)
DLOG.debug("Complete-Upgrade callback response=%s." % response)
self.strategy.nfvi_upgrade = response['result-data']
if response['completed']:
result = strategy.STRATEGY_STEP_RESULT.SUCCESS
self.stage.step_complete(result, "")
state_info = self.strategy.nfvi_upgrade['release_info'][0]['state']
if state_info == SW_HOST_DEPLOYED:
result = strategy.STRATEGY_STEP_RESULT.SUCCESS
self.stage.step_complete(result, "")
else:
reason = "SW Deploy completed failed. Current state:%s" % state_info
result = strategy.STRATEGY_STEP_RESULT.FAILED
self.stage.step_complete(result, reason)
else:
# TODO(jkraitbe): Add error message
reason = "SW Deploy did not complete. Current response:%s" % response['result-data']
result = strategy.STRATEGY_STEP_RESULT.FAILED
self.stage.step_complete(result, "")
self.stage.step_complete(result, reason)
def apply(self):
"""