From 279d55725c44550da610d7e29b0e38bbdcf9fab0 Mon Sep 17 00:00:00 2001 From: Nageswara Nandigam <84482346+nagworld9@users.noreply.github.com> Date: Fri, 13 Oct 2023 10:04:35 -0700 Subject: [PATCH] Cache daemon version (#2942) * cache daemon version * address comments * test update --- azurelinuxagent/common/version.py | 12 +++++++----- azurelinuxagent/ga/agent_update_handler.py | 13 +++++++++++-- tests/common/test_version.py | 10 +++++++--- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/azurelinuxagent/common/version.py b/azurelinuxagent/common/version.py index 73d9ad8e28..cfe175ef57 100644 --- a/azurelinuxagent/common/version.py +++ b/azurelinuxagent/common/version.py @@ -56,14 +56,16 @@ def get_daemon_version(): else: # The agent process which execute the extensions can have different version(after upgrades) and importing version from that process may provide wrong version for daemon. # so launching new process with sys.executable python provides the correct version for daemon which preinstalled in the image. + daemon_version = "0.0.0.0" try: cmd = ["{0}".format(sys.executable), "-c", "from azurelinuxagent.common.version import AGENT_VERSION; print(AGENT_VERSION)"] - version = shellutil.run_command(cmd) - return FlexibleVersion(version) - except Exception as e: # Make the best effort to get the daemon version, but don't fail the update if we can't. So default to 2.2.53 as env variable is not set < 2.2.53 + daemon_version = shellutil.run_command(cmd) + except Exception as e: # Make the best effort to get the daemon version, otherwise default to 0.0.0.0(unknown) logger.warn("Failed to get the daemon version: {0}", ustr(e)) - return FlexibleVersion("2.2.53") - + # set the daemon version to the environment variable to cache it for future calls. + set_daemon_version(daemon_version) + return FlexibleVersion(os.environ[__DAEMON_VERSION_ENV_VARIABLE]) + def get_f5_platform(): """ diff --git a/azurelinuxagent/ga/agent_update_handler.py b/azurelinuxagent/ga/agent_update_handler.py index a8390c1c7d..013585b3e1 100644 --- a/azurelinuxagent/ga/agent_update_handler.py +++ b/azurelinuxagent/ga/agent_update_handler.py @@ -9,7 +9,7 @@ from azurelinuxagent.common.future import ustr from azurelinuxagent.common.logger import LogLevel from azurelinuxagent.common.protocol.extensions_goal_state import GoalStateSource -from azurelinuxagent.common.protocol.restapi import VMAgentUpdateStatuses, VMAgentUpdateStatus +from azurelinuxagent.common.protocol.restapi import VMAgentUpdateStatuses, VMAgentUpdateStatus, VERSION_0 from azurelinuxagent.common.utils import fileutil, textutil from azurelinuxagent.common.utils.flexible_version import FlexibleVersion from azurelinuxagent.common.version import get_daemon_version, CURRENT_VERSION, AGENT_NAME, AGENT_DIR_PATTERN @@ -113,6 +113,15 @@ def __get_agent_upgrade_type(requested_version): return AgentUpgradeType.Hotfix return AgentUpgradeType.Normal + @staticmethod + def __get_daemon_version_for_update(): + daemon_version = get_daemon_version() + if daemon_version != FlexibleVersion(VERSION_0): + return daemon_version + # We return 0.0.0.0 if we failed to retrieve daemon version. In that case, + # use the min version as 2.2.53 as we started setting the daemon version starting 2.2.53. + return FlexibleVersion("2.2.53") + def __get_next_upgrade_times(self, now): """ Get the next upgrade times @@ -329,7 +338,7 @@ def run(self, goal_state): if not self.__check_if_downgrade_is_requested_and_allowed(requested_version): return - daemon_version = get_daemon_version() + daemon_version = self.__get_daemon_version_for_update() if requested_version < daemon_version: # Don't process the update if the requested version is less than daemon version, # as historically we don't support downgrades below daemon versions. So daemon will not pickup that requested version rather start with diff --git a/tests/common/test_version.py b/tests/common/test_version.py index bdc07c0046..89156f65c1 100644 --- a/tests/common/test_version.py +++ b/tests/common/test_version.py @@ -137,11 +137,15 @@ def test_get_daemon_version_should_return_the_version_that_was_previously_set(se os.environ.pop(DAEMON_VERSION_ENV_VARIABLE) def test_get_daemon_version_from_fallback_when_the_version_has_not_been_set(self): - with patch("azurelinuxagent.common.utils.shellutil.run_command", return_value=FlexibleVersion("2.2.53")): + with patch("azurelinuxagent.common.utils.shellutil.run_command", return_value="2.3.53") as mock_run_command: self.assertEqual( - FlexibleVersion("2.2.53"), get_daemon_version(), - "The daemon version should not be defined. Environment={0}".format(os.environ) + FlexibleVersion("2.3.53"), get_daemon_version(), + "The daemon version should be defined. Environment={0}".format(os.environ) ) + self.assertEqual(FlexibleVersion("2.3.53"), get_daemon_version(), "The daemon version should be 2.3.53") + self.assertEqual(1, mock_run_command.call_count, "The daemon version should be read from env value on second time") + + os.environ.pop(DAEMON_VERSION_ENV_VARIABLE) class TestCurrentAgentName(AgentTestCase):