diff --git a/software/software/agent_hooks.py b/software/software/agent_hooks.py index c04e5f03..ebd47388 100644 --- a/software/software/agent_hooks.py +++ b/software/software/agent_hooks.py @@ -970,6 +970,38 @@ class FixedEtcMergeRollBackHook(FixedEtcMergeHook): LOG.info("FixedEtcMergeRollBackHook finished.") +class OOTDriverHook(BaseHook): + """ + Hook to remove out-of-tree driver kernel parameters during upgrade. + """ + + PARAM_NAME = "out-of-tree-drivers" + + def _remove_kernel_param(self): + try: + cmd = ( + "python /usr/local/bin/puppet-update-grub-env.py " + f"--remove-kernelparams {self.PARAM_NAME}" + ) + subprocess.run(cmd, shell=True, check=True, capture_output=True) + LOG.info("Removed kernel parameter: %s", self.PARAM_NAME) + except subprocess.CalledProcessError as e: + LOG.exception( + "Failed to remove kernel parameter %s: %s", + self.PARAM_NAME, str(e) + ) + + def run(self): + if self._from_release == "25.09": + # Upgrade path: remove kernel param + self._remove_kernel_param() + LOG.info("Upgrade OOTDriverHook completed.") + else: + LOG.info( + "OOTDriverHook: nothing to do for this release transition." + ) + + class HookManager(object): """ Object to manage the execution of agent hooks @@ -982,6 +1014,7 @@ class HookManager(object): AGENT_HOOKS = { MAJOR_RELEASE_UPGRADE: [ CreateUSMUpgradeInProgressFlag, + OOTDriverHook, EtcMerger, CopyPxeFilesHook, ReconfigureKernelHook, diff --git a/software/upgrade-scripts/04-remove-out-of-tree-service-parameter.py b/software/upgrade-scripts/04-remove-out-of-tree-service-parameter.py new file mode 100644 index 00000000..ba010f21 --- /dev/null +++ b/software/upgrade-scripts/04-remove-out-of-tree-service-parameter.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python +# Copyright (c) 2025 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# This script removes the out_of_tree_drivers service parameter +# from sysinv DB during upgrade from 25.09 to 26.03. +# + +import logging +import sys + +from packaging import version +import psycopg2 + +from software.utilities.utils import configure_logging + +DEFAULT_POSTGRES_PORT = 5432 +LOG = logging.getLogger('main_logger') + +PARAM_NAME = "out_of_tree_drivers" +PARAM_SERVICE = "platform" +PARAM_SECTION = "kernel" + + +def main(): + action = None + from_release = None + to_release = None + postgres_port = DEFAULT_POSTGRES_PORT + arg = 1 + while arg < len(sys.argv): + if arg == 1: + from_release = sys.argv[arg] + elif arg == 2: + to_release = sys.argv[arg] + elif arg == 3: + action = sys.argv[arg] + elif arg == 4: + postgres_port = sys.argv[arg] + else: + print("Invalid option %s." % sys.argv[arg]) + return 1 + arg += 1 + + configure_logging() + LOG.info( + "%s invoked from_release=%s to_release=%s action=%s", + sys.argv[0], from_release, to_release, action + ) + + res = 0 + to_release_version = version.Version(to_release) + target_version = version.Version("26.03") + + # Only remove service param on migrate to 26.03 + if action == 'migrate' and to_release_version == target_version: + try: + conn = psycopg2.connect( + "dbname=sysinv user=postgres port=%s" % postgres_port + ) + remove_service_param(conn) + conn.close() + except Exception as e: + LOG.exception("Error removing service parameter: %s", e) + res = 1 + + return res + + +def remove_service_param(conn): + """Remove out_of_tree_drivers service parameter from sysinv DB.""" + query = ( + "SELECT uuid, value FROM service_parameter " + "WHERE name='%s' AND service='%s' AND section='%s';" + % (PARAM_NAME, PARAM_SERVICE, PARAM_SECTION) + ) + rows = db_query(conn, query) + if not rows: + LOG.info( + "No service parameter '%s' found. Nothing to delete.", PARAM_NAME + ) + return + + for uuid, value in rows: + LOG.info( + "Deleting service parameter '%s' (uuid=%s, value=%s)", + PARAM_NAME, uuid, value + ) + delete_query = ( + "DELETE FROM service_parameter WHERE uuid='%s';" % uuid + ) + db_update(conn, delete_query) + + LOG.info( + "Service parameter '%s' removed successfully.", PARAM_NAME + ) + + +def db_query(conn, query): + """Execute a read-only query and return results.""" + result = [] + with conn.cursor() as cur: + cur.execute(query) + for rec in cur: + result.append(rec) + return result + + +def db_update(conn, query): + """Execute a write query and commit changes.""" + with conn.cursor() as cur: + cur.execute(query) + conn.commit() + + +if __name__ == "__main__": + try: + sys.exit(main()) + except Exception as e: + LOG.error("An error occurred: %s", e) + raise