From cabe2634cd607475a07a6847168f6fff7fca3dbb Mon Sep 17 00:00:00 2001 From: fperez Date: Mon, 22 May 2023 09:20:37 -0300 Subject: [PATCH] Add function to read output script for subclouds Sysinv function to get the output from the migration scripts excecution at the activating or starting upgrade subcloud step. This allows the orchestrator to know the result of the migration scripts for each subcloud. Test plan: PASS: Modify migration script involving action = 'start' in order to make the starting upgrade step fail. Run subcloud upgrade strategy. Verify msg in /tmp/upgrade_fail_msg PASS: Modify migration script involving action = 'activate' in order to make the activating upgrade step fail. Run upgrade subcloud strategy. Verify msg in /tmp/upgrade_fail_msg PASS: Create (modifying) a new app tarball (platform-integ-apps) to make it recognizable but not applicable. Run strategy and verify msg in /tmp/upgrade_fail_msg Story: 2010768 Task: 48078 Signed-off-by: fperez Change-Id: I7e3547faeaa6c971afce7a6aa7445c8d71133558 --- .../controllerconfig/upgrades/utils.py | 51 ++++++++++++++++++- .../cgts-client/cgtsclient/v1/upgrade.py | 6 ++- .../sysinv/api/controllers/v1/upgrade.py | 15 +++++- 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/controllerconfig/controllerconfig/controllerconfig/upgrades/utils.py b/controllerconfig/controllerconfig/controllerconfig/upgrades/utils.py index 0e8f0c5db2..5dc7fe6127 100644 --- a/controllerconfig/controllerconfig/controllerconfig/upgrades/utils.py +++ b/controllerconfig/controllerconfig/controllerconfig/upgrades/utils.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2016-2022 Wind River Systems, Inc. +# Copyright (c) 2016-2023 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -41,6 +41,8 @@ CONTROLLER_1_HOSTNAME = "controller-1" DB_CONNECTION = "postgresql://%s:%s@127.0.0.1/%s\n" KUBERNETES_CONF_PATH = "/etc/kubernetes" KUBERNETES_ADMIN_CONF_FILE = "admin.conf" +PLATFORM_LOG = '/var/log/platform.log' +ERROR_FILE = '/tmp/upgrade_fail_msg' # well-known default domain name DEFAULT_DOMAIN_NAME = 'Default' @@ -104,10 +106,18 @@ def execute_migration_scripts(from_release, to_release, action, stdout=subprocess.PIPE, text=True) if ret.returncode != 0: + script_output = ret.stdout.splitlines() + output_list = [] + for item in script_output: + if item not in output_list: + output_list.append(item) + output_script = "\n".join(output_list) msg = MSG_SCRIPT_FAILURE % (migration_script, ret.returncode, - ret.stdout) + output_script) LOG.error(msg) + msg_temp = search_script_output(PLATFORM_LOG, f) + save_temp_file(msg, msg_temp) raise Exception(msg) except subprocess.CalledProcessError as e: @@ -122,6 +132,43 @@ def execute_migration_scripts(from_release, to_release, action, raise +def search_script_output(file_name, script): + cmd = [ + "awk", + "/{script}/ {{last_match = $0}} " + "END {{if (last_match) print last_match}}".format(script=script), + file_name + ] + try: + process = subprocess.Popen(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + output, error = process.communicate() + last_match = output.decode().strip() + except Exception: + LOG.error("Failed to exec cmd. \n %s" % error) + return None + return last_match + + +def save_temp_file(msg, error=None): + if os.path.isfile(ERROR_FILE): + os.remove(ERROR_FILE) + + MSG_FAILURE = '%s \n\n'\ + '%s \n\n'\ + 'Check specific service log or search for' \ + 'this app in sysinv.log for details' + msg = MSG_FAILURE % (msg, + error) + try: + with open(ERROR_FILE, 'w+') as error_file: + error_file.write(msg) + except Exception: + LOG.warning("Error opening file %s" % ERROR_FILE) + return None + + def get_db_connection(hiera_db_records, database): username = hiera_db_records[database]['username'] password = hiera_db_records[database]['password'] diff --git a/sysinv/cgts-client/cgts-client/cgtsclient/v1/upgrade.py b/sysinv/cgts-client/cgts-client/cgtsclient/v1/upgrade.py index 067a0cb24c..b5f3e3cdd1 100644 --- a/sysinv/cgts-client/cgts-client/cgtsclient/v1/upgrade.py +++ b/sysinv/cgts-client/cgts-client/cgtsclient/v1/upgrade.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2015 Wind River Systems, Inc. +# Copyright (c) 2015-2023 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -49,3 +49,7 @@ class UpgradeManager(base.Manager): def update(self, patch): return self._update(self._path(), patch) + + def get_upgrade_msg(self): + path = self._path() + '/get_upgrade_msg' + return self._json_get(path) diff --git a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/upgrade.py b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/upgrade.py index 805c7eb641..5b4d4b817b 100755 --- a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/upgrade.py +++ b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/upgrade.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2017 Wind River Systems, Inc. +# Copyright (c) 2015-2023 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -115,6 +115,7 @@ class UpgradeCollection(collection.Collection): return collection +ERROR_FILE = '/tmp/upgrade_fail_msg' LOCK_NAME = 'UpgradeController' @@ -125,6 +126,7 @@ class UpgradeController(rest.RestController): 'check_reinstall': ['GET'], 'in_upgrade': ['GET'], 'upgrade_in_progress': ['GET'], + 'get_upgrade_msg': ['GET'], } def __init__(self, parent=None, **kwargs): @@ -175,6 +177,17 @@ class UpgradeController(rest.RestController): return {'reinstall_necessary': reinstall_necessary} + @expose('json') + def get_upgrade_msg(self): + output = '' + try: + with open(ERROR_FILE, 'r') as error_file: + output = error_file.read() + except Exception: + LOG.warning("Error opening file %s" % ERROR_FILE) + + return {'error_msg:': output} + @wsme_pecan.wsexpose(UpgradeCollection, types.uuid, int, wtypes.text, wtypes.text) def get_all(self, marker=None, limit=None, sort_key='id', sort_dir='asc'):