From bfe2fd5693353b7acb92413b0d19f1f12e8f21b0 Mon Sep 17 00:00:00 2001 From: Don Penney Date: Wed, 27 Nov 2019 16:35:21 -0500 Subject: [PATCH] Improved patching robustness on AIO-SX This update includes the following: - Ensure the sw-patch init script does nothing on AIO-SX before initial configuration is complete. This protects against misleading alarms indicating patch installation failure, stemming from pre-configuration networking issues. - Enhance install-local support to allow for patch installation after ansible bootstrap playbook is applied, but before system configuration has been completed. Change-Id: Id7a5b4f120449fd3f6e71c83167586dc66e8a91e Closes-Bug: 1847872 Depends-On: https://review.opendev.org/696410 Signed-off-by: Don Penney --- cgcs-patch/bin/sw-patch-init.sh | 6 +++++ .../cgcs-patch/cgcs_patch/patch_agent.py | 17 ++++++++++---- .../cgcs-patch/cgcs_patch/patch_client.py | 23 +++++++++++++------ 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/cgcs-patch/bin/sw-patch-init.sh b/cgcs-patch/bin/sw-patch-init.sh index 2428edb2..b163cc0a 100644 --- a/cgcs-patch/bin/sw-patch-init.sh +++ b/cgcs-patch/bin/sw-patch-init.sh @@ -79,6 +79,12 @@ if [ ! -f /var/run/.rpmdb_cleaned ]; then touch /var/run/.rpmdb_cleaned fi +# For AIO-SX, abort if config is not yet applied and this is running in init +if [ "${system_mode}" = "simplex" -a ! -f ${INITIAL_CONTROLLER_CONFIG_COMPLETE} -a "$1" = "start" ]; then + LOG_TO_FILE "Config is not yet applied. Skipping init patching" + exit 0 +fi + # If the management interface is bonded, it may take some time # before communications can be properly setup. # Allow up to $DELAY_SEC seconds to reach controller. diff --git a/cgcs-patch/cgcs-patch/cgcs_patch/patch_agent.py b/cgcs-patch/cgcs-patch/cgcs_patch/patch_agent.py index cafc6d54..b95b79d0 100644 --- a/cgcs-patch/cgcs-patch/cgcs_patch/patch_agent.py +++ b/cgcs-patch/cgcs-patch/cgcs_patch/patch_agent.py @@ -49,6 +49,8 @@ run_insvc_patch_scripts_cmd = "/usr/sbin/run-patch-scripts" pa = None +http_port_real = http_port + # Smart commands smart_cmd = ["/usr/bin/smart"] smart_quiet = smart_cmd + ["--quiet"] @@ -81,7 +83,7 @@ def clearflag(fname): def check_install_uuid(): - controller_install_uuid_url = "http://controller:%s/feed/rel-%s/install_uuid" % (http_port, SW_VERSION) + controller_install_uuid_url = "http://controller:%s/feed/rel-%s/install_uuid" % (http_port_real, SW_VERSION) try: req = requests.get(controller_install_uuid_url) if req.status_code != 200: @@ -366,11 +368,11 @@ class PatchAgent(PatchService): {'channel': 'base', 'type': 'rpm-md', 'name': 'Base', - 'baseurl': "http://controller:%s/feed/rel-%s" % (http_port, SW_VERSION)}, + 'baseurl': "http://controller:%s/feed/rel-%s" % (http_port_real, SW_VERSION)}, {'channel': 'updates', 'type': 'rpm-md', 'name': 'Patches', - 'baseurl': "http://controller:%s/updates/rel-%s" % (http_port, SW_VERSION)}] + 'baseurl': "http://controller:%s/updates/rel-%s" % (http_port_real, SW_VERSION)}] updated = False @@ -593,7 +595,7 @@ class PatchAgent(PatchService): self.missing_pkgs = [] installed_pkgs = [] - groups_url = "http://controller:%s/updates/rel-%s/comps.xml" % (http_port, SW_VERSION) + groups_url = "http://controller:%s/updates/rel-%s/comps.xml" % (http_port_real, SW_VERSION) try: req = requests.get(groups_url) if req.status_code != 200: @@ -1066,6 +1068,13 @@ def main(): if len(sys.argv) <= 1: pa.run() elif sys.argv[1] == "--install": + if not check_install_uuid(): + # In certain cases, the lighttpd server could still be running using + # its default port 80, as opposed to the port configured in platform.conf + global http_port_real + LOG.info("Failed install_uuid check via http_port=%s. Trying with default port 80" % http_port_real) + http_port_real = 80 + pa.handle_install(verbose_to_stdout=True, disallow_insvc_patch=True) elif sys.argv[1] == "--status": rc = 0 diff --git a/cgcs-patch/cgcs-patch/cgcs_patch/patch_client.py b/cgcs-patch/cgcs-patch/cgcs_patch/patch_client.py index ace24ad9..6d612046 100644 --- a/cgcs-patch/cgcs-patch/cgcs_patch/patch_client.py +++ b/cgcs-patch/cgcs-patch/cgcs_patch/patch_client.py @@ -25,6 +25,7 @@ import cgcs_patch.constants as constants import cgcs_patch.utils as utils from tsconfig.tsconfig import SW_VERSION as RUNNING_SW_VERSION +from tsconfig.tsconfig import INITIAL_CONTROLLER_CONFIG_COMPLETE api_addr = "127.0.0.1:5487" auth_token = None @@ -1073,12 +1074,18 @@ def patch_upload_dir_req(debug, args): def patch_install_local(debug, args): """ This function is used to trigger patch installation prior to configuration """ - # First, check to see if the controller hostname is already known. - if utils.gethostbyname(constants.CONTROLLER_FLOATING_HOSTNAME): - # If this is successful, disallow the install + # Check to see if initial configuration has completed + if os.path.isfile(INITIAL_CONTROLLER_CONFIG_COMPLETE): + # Disallow the install print("Error: This function can only be used before initial system configuration.", file=sys.stderr) return 1 + update_hosts_file = False + + # Check to see if the controller hostname is already known. + if not utils.gethostbyname(constants.CONTROLLER_FLOATING_HOSTNAME): + update_hosts_file = True + # Ignore interrupts during this function signal.signal(signal.SIGINT, signal.SIG_IGN) @@ -1089,8 +1096,9 @@ def patch_install_local(debug, args): rc = 0 - # Make a backup of /etc/hosts - shutil.copy2('/etc/hosts', '/etc/hosts.patchbak') + if update_hosts_file: + # Make a backup of /etc/hosts + shutil.copy2('/etc/hosts', '/etc/hosts.patchbak') # Update /etc/hosts with open('/etc/hosts', 'a') as f: @@ -1105,8 +1113,9 @@ def patch_install_local(debug, args): print("Error: Failed to install patches. Please check /var/log/patching.log for details", file=sys.stderr) rc = 1 - # Restore /etc/hosts - os.rename('/etc/hosts.patchbak', '/etc/hosts') + if update_hosts_file: + # Restore /etc/hosts + os.rename('/etc/hosts.patchbak', '/etc/hosts') if rc == 0: print("Patch installation is complete.")