From 67c214a4e4ac234ceab33d1514f550eea41ae928 Mon Sep 17 00:00:00 2001 From: John Kung Date: Thu, 29 Apr 2021 07:55:55 -0500 Subject: [PATCH] Clear host config_target on upgrade migration The host config_target is taken as a snapshot on the upgrade-start. This can lead to config out of date condition if the N controller issues subsequent config requests. This is more likely in duplex controllers, however, for consistency the config_target is reset to track when the N+1 controller is active. Clear the config target of all hosts on upgrade migration. The N+1 controller will resume tracking the config by generating config_target when configuration is issued. Condition for upgrade activation-complete is updated to account for potential None config_target. Verified upgrade complete on AIO-SX and Duplex systems. Change-Id: I4dd44e6548a45d32ab6a0b6735a04d624da7caad Closes-Bug: 1926512 Signed-off-by: John Kung --- .../upgrade-scripts/97-reset-config-target.py | 63 +++++++++++++++++++ .../sysinv/sysinv/sysinv/conductor/manager.py | 3 +- 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100755 controllerconfig/controllerconfig/upgrade-scripts/97-reset-config-target.py diff --git a/controllerconfig/controllerconfig/upgrade-scripts/97-reset-config-target.py b/controllerconfig/controllerconfig/upgrade-scripts/97-reset-config-target.py new file mode 100755 index 0000000000..a16f5d3dd4 --- /dev/null +++ b/controllerconfig/controllerconfig/upgrade-scripts/97-reset-config-target.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# Copyright (c) 2021 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# This script will clear the host config target. +# This is required in order to ensure tracking is aligned with config +# requests in N+1 release and not due to potential stale configuration +# from N release. + +import psycopg2 +import sys + +from psycopg2.extras import RealDictCursor +from controllerconfig.common import log + +LOG = log.get_logger(__name__) + + +def main(): + action = None + from_release = None + to_release = None + arg = 1 + + while arg < len(sys.argv): + if arg == 1: + from_release = sys.argv[arg] + elif arg == 2: + to_release = sys.argv[arg] # noqa + elif arg == 3: + action = sys.argv[arg] + else: + print ("Invalid option %s." % sys.argv[arg]) + return 1 + arg += 1 + + log.configure() + + LOG.debug("%s invoked with from_release = %s to_release = %s action = %s" + % (sys.argv[0], from_release, to_release, action)) + + # This host table data migration will likely be required for each release + if action == "migrate": + try: + reset_config_target() + except Exception as ex: + LOG.exception(ex) + return 1 + + +def reset_config_target(): + + conn = psycopg2.connect("dbname=sysinv user=postgres") + with conn: + with conn.cursor(cursor_factory=RealDictCursor) as cur: + cur.execute("update i_host set config_target=NULL where " + "recordtype!='profile'",) + + LOG.info("Reset host config_target completed") + +if __name__ == "__main__": + sys.exit(main()) diff --git a/sysinv/sysinv/sysinv/sysinv/conductor/manager.py b/sysinv/sysinv/sysinv/sysinv/conductor/manager.py index be5f429f2f..0395701be8 100644 --- a/sysinv/sysinv/sysinv/sysinv/conductor/manager.py +++ b/sysinv/sysinv/sysinv/sysinv/conductor/manager.py @@ -5225,7 +5225,8 @@ class ConductorManager(service.PeriodicService): if upgrade.state == constants.UPGRADE_ACTIVATING_HOSTS: hosts = self.dbapi.ihost_get_list() - out_of_date_hosts = [host for host in hosts if host.config_target != host.config_applied] + out_of_date_hosts = [host for host in hosts + if host.config_target and host.config_target != host.config_applied] if not out_of_date_hosts: LOG.info("Manifests applied. Upgrade activation complete.") self.dbapi.software_upgrade_update(