From c908b9625d9b958d92065c988ca32fbbaec5c16f Mon Sep 17 00:00:00 2001 From: Al Bailey Date: Tue, 30 May 2023 17:02:49 +0000 Subject: [PATCH] Remove polling from two kube upgrade steps The kube-upgrade strategy invokes a synchronous POST operation to start and cleanup a kubernetes upgrade. kube-upgrade-start takes about 3 seconds. kube-upgrade-complete takes about one second. The old code would ignore the results of those REST API calls, and enter a polling mode to check the host state. This could take up to two minutes to complete. Polling is un-neccessary (for these steps), and by using the results from the NFV plugin being invoked, the step can quickly be completed. This reduces the time of a kube-upgrade strategy by over three minutes. Test Plan: PASS: AIO-SX kube upgrade Story: 2010565 Task: 48152 Signed-off-by: Al Bailey Change-Id: Icb511e70eea445b0d07a139d437e018fb3c505f3 --- .../nfvi_plugins/openstack/sysinv.py | 37 +++++-------------- .../nfv_vim/strategy/_strategy_steps.py | 11 +++++- 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/nfv/nfv-plugins/nfv_plugins/nfvi_plugins/openstack/sysinv.py b/nfv/nfv-plugins/nfv_plugins/nfvi_plugins/openstack/sysinv.py index bb6a2599..428d97cd 100755 --- a/nfv/nfv-plugins/nfv_plugins/nfvi_plugins/openstack/sysinv.py +++ b/nfv/nfv-plugins/nfv_plugins/nfvi_plugins/openstack/sysinv.py @@ -16,7 +16,6 @@ DLOG = debug.debug_get_logger('nfv_plugins.nfvi_plugins.openstack.sysinv') # file for the nfvi plugins. REST_API_REQUEST_TIMEOUT = 60 - KUBE_ROOTCA_UPDATE_ENDPOINT = "/kube_rootca_update" KUBE_ROOTCA_UPDATE_GENERATE_CERT_ENDPOINT = \ KUBE_ROOTCA_UPDATE_ENDPOINT + "/generate_cert" @@ -25,6 +24,8 @@ KUBE_ROOTCA_UPDATE_HOSTS_ENDPOINT = KUBE_ROOTCA_UPDATE_ENDPOINT + "/hosts" KUBE_ROOTCA_UPDATE_UPLOAD_CERT_ENDPOINT = \ KUBE_ROOTCA_UPDATE_ENDPOINT + "/upload_cert" +KUBE_UPGRADE_ENDPOINT = "/kube_upgrade" + # todo(abailey): refactor _api_get, etc.. into rest_api.py def _api_cmd(token, endpoint): @@ -98,6 +99,11 @@ def _api_post(token, endpoint, api_cmd_payload): return response +def _api_data_patch(path, value, op="replace"): + # the 'path' is prefixed with a leading '/' + return {'path': '/' + path, 'value': value, 'op': op} + + def get_datanetworks(token, host_uuid): """ Get all data networks on a host. @@ -357,35 +363,12 @@ def kube_upgrade_start(token, to_version, force=False, alarm_ignore_list=None): """ Ask System Inventory to start a kube upgrade """ - # todo(abailey): refactor using _post_api_request - url = token.get_service_url(PLATFORM_SERVICE.SYSINV) - if url is None: - raise ValueError("OpenStack SysInv URL is invalid") - - api_cmd = url + "/kube_upgrade" - - api_cmd_headers = dict() - api_cmd_headers['Content-Type'] = "application/json" - api_cmd_headers['User-Agent'] = "vim/1.0" - api_cmd_payload = dict() api_cmd_payload['to_version'] = to_version api_cmd_payload['force'] = force if alarm_ignore_list is not None: api_cmd_payload['alarm_ignore_list'] = copy.copy(alarm_ignore_list) - - response = rest_api_request(token, - "POST", - api_cmd, - api_cmd_headers, - json.dumps(api_cmd_payload), - timeout_in_secs=REST_API_REQUEST_TIMEOUT) - return response - - -def api_data_patch(path, value, op="replace"): - # the 'path' is prefixed with a leading '/' - return {'path': '/' + path, 'value': value, 'op': op} + return _api_post(token, KUBE_UPGRADE_ENDPOINT, api_cmd_payload) def _patch_kube_upgrade_state(token, new_value, hostname=None): @@ -400,10 +383,10 @@ def _patch_kube_upgrade_state(token, new_value, hostname=None): api_cmd_headers['User-Agent'] = "vim/1.0" api_cmd_payload = list() - api_cmd_payload.append(api_data_patch('state', new_value)) + api_cmd_payload.append(_api_data_patch('state', new_value)) # some kube upgrade patch commands take a hostname if hostname is not None: - api_cmd_payload.append(api_data_patch('hostname', hostname)) + api_cmd_payload.append(_api_data_patch('hostname', hostname)) return rest_api_request(token, "PATCH", diff --git a/nfv/nfv-vim/nfv_vim/strategy/_strategy_steps.py b/nfv/nfv-vim/nfv_vim/strategy/_strategy_steps.py index 2454e93e..d481d252 100755 --- a/nfv/nfv-vim/nfv_vim/strategy/_strategy_steps.py +++ b/nfv/nfv-vim/nfv_vim/strategy/_strategy_steps.py @@ -3958,10 +3958,13 @@ class KubeUpgradeStartStep(AbstractKubeUpgradeStep): response = (yield) DLOG.debug("%s callback response=%s." % (self._name, response)) + # kube-upgrade-start will return a result when it completes, + # so we do not want to use handle_event if response['completed']: if self.strategy is not None: self.strategy.nfvi_kube_upgrade = response['result-data'] - # We do not set 'success' here, let the handle_event do this + result = strategy.STRATEGY_STEP_RESULT.SUCCESS + self.stage.step_complete(result, "") else: result = strategy.STRATEGY_STEP_RESULT.FAILED self.stage.step_complete(result, response['reason']) @@ -3995,6 +3998,8 @@ class KubeUpgradeCleanupStep(AbstractKubeUpgradeStep): response = (yield) DLOG.debug("%s callback response=%s." % (self._name, response)) + # kube-upgrade-cleanup will return a result when it completes, + # so we do not want to use handle_event if response['completed']: if self.strategy is not None: # cleanup deletes the kube upgrade, clear it from the strategy @@ -4031,9 +4036,13 @@ class KubeUpgradeCompleteStep(AbstractKubeUpgradeStep): response = (yield) DLOG.debug("%s callback response=%s." % (self._name, response)) + # kube-upgrade-complete will return a result when it completes, + # so we do not want to use handle_event if response['completed']: if self.strategy is not None: self.strategy.nfvi_kube_upgrade = response['result-data'] + result = strategy.STRATEGY_STEP_RESULT.SUCCESS + self.stage.step_complete(result, "") else: result = strategy.STRATEGY_STEP_RESULT.FAILED self.stage.step_complete(result, response['reason'])