diff --git a/src/core/src/bootstrap/Constants.py b/src/core/src/bootstrap/Constants.py index 7348541c..a59fb58d 100644 --- a/src/core/src/bootstrap/Constants.py +++ b/src/core/src/bootstrap/Constants.py @@ -300,7 +300,7 @@ class TelemetryTaskName(EnumBackport): TELEMETRY_NOT_COMPATIBLE_ERROR_MSG = "Unsupported older Azure Linux Agent version. To resolve: http://aka.ms/UpdateLinuxAgent" TELEMETRY_COMPATIBLE_MSG = "Minimum Azure Linux Agent version prerequisite met" - + PYTHON_NOT_COMPATIBLE_ERROR_MSG = "Unsupported older Python version. Minimum Python version required is 2.7. [DetectedPythonVersion={0}]" UTC_DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ" # EnvLayer Constants diff --git a/src/core/src/core_logic/PatchAssessor.py b/src/core/src/core_logic/PatchAssessor.py index 3ee0c991..50d49584 100644 --- a/src/core/src/core_logic/PatchAssessor.py +++ b/src/core/src/core_logic/PatchAssessor.py @@ -19,6 +19,7 @@ import json import os import shutil +import sys import time from core.src.bootstrap.Constants import Constants from core.src.core_logic.Stopwatch import Stopwatch @@ -43,6 +44,7 @@ def start_assessment(self): """ Start a patch assessment """ self.status_handler.set_current_operation(Constants.ASSESSMENT) self.raise_if_telemetry_unsupported() + self.raise_if_min_python_version_not_met() if self.execution_config.exec_auto_assess_only and not self.should_auto_assessment_run(): self.composite_logger.log("\nSkipping automatic patch assessment... [ShouldAutoAssessmentRun=False]\n") @@ -129,6 +131,13 @@ def raise_if_telemetry_unsupported(self): self.composite_logger.log("{0}".format(Constants.TELEMETRY_COMPATIBLE_MSG)) + def raise_if_min_python_version_not_met(self): + if sys.version_info < (2, 7): + error_msg = Constants.PYTHON_NOT_COMPATIBLE_ERROR_MSG.format(sys.version_info) + self.composite_logger.log_error(error_msg) + self.status_handler.set_assessment_substatus_json(status=Constants.STATUS_ERROR) + raise Exception(error_msg) + # region - Auto-assessment extensions def should_auto_assessment_run(self): # get last start time diff --git a/src/core/src/core_logic/PatchInstaller.py b/src/core/src/core_logic/PatchInstaller.py index a97523ca..a80c1436 100644 --- a/src/core/src/core_logic/PatchInstaller.py +++ b/src/core/src/core_logic/PatchInstaller.py @@ -17,7 +17,7 @@ """ The patch install orchestrator """ import datetime import math -import os +import sys import time from core.src.bootstrap.Constants import Constants from core.src.core_logic.Stopwatch import Stopwatch @@ -56,6 +56,7 @@ def start_installation(self, simulate=False): """ Kick off a patch installation run """ self.status_handler.set_current_operation(Constants.INSTALLATION) self.raise_if_telemetry_unsupported() + self.raise_if_min_python_version_not_met() self.composite_logger.log('\nStarting patch installation...') @@ -140,6 +141,13 @@ def raise_if_telemetry_unsupported(self): self.composite_logger.log("{0}".format(Constants.TELEMETRY_COMPATIBLE_MSG)) + def raise_if_min_python_version_not_met(self): + if sys.version_info < (2, 7): + error_msg = Constants.PYTHON_NOT_COMPATIBLE_ERROR_MSG.format(sys.version_info) + self.composite_logger.log_error(error_msg) + self.status_handler.set_installation_substatus_json(status=Constants.STATUS_ERROR) + raise Exception(error_msg) + def install_updates(self, maintenance_window, package_manager, simulate=False): """wrapper function of installing updates""" self.composite_logger.log("\n\nGetting available updates...") diff --git a/src/core/tests/Test_CoreMain.py b/src/core/tests/Test_CoreMain.py index 6395e6c2..922fa900 100644 --- a/src/core/tests/Test_CoreMain.py +++ b/src/core/tests/Test_CoreMain.py @@ -19,7 +19,6 @@ import os import re import shutil -import time import unittest import uuid diff --git a/src/core/tests/Test_PatchAssessor.py b/src/core/tests/Test_PatchAssessor.py index 96c0684c..40f1c22d 100644 --- a/src/core/tests/Test_PatchAssessor.py +++ b/src/core/tests/Test_PatchAssessor.py @@ -16,6 +16,7 @@ import datetime import json import os +import sys import unittest from core.src.bootstrap.Constants import Constants @@ -28,8 +29,10 @@ class TestPatchAssessor(unittest.TestCase): def setUp(self): self.runtime = RuntimeCompositor(ArgumentComposer().get_composed_arguments(), legacy_mode=True) self.container = self.runtime.container + self.original_version_info = sys.version_info def tearDown(self): + sys.version_info = self.original_version_info self.runtime.stop() def test_assessment_success(self): @@ -171,6 +174,13 @@ def test_stopwatch_properties_assessment_fail(self): self.assertTrue(self.runtime.patch_assessor.stopwatch.time_taken_in_secs is not None) self.assertTrue(self.runtime.patch_assessor.stopwatch.task_details is not None) + def test_raise_if_min_python_version_not_met(self): + sys.version_info = (2, 6) + # Assert that an exception is raised + with self.assertRaises(Exception) as context: + self.runtime.patch_assessor.start_assessment() + self.assertEqual(str(context.exception), Constants.PYTHON_NOT_COMPATIBLE_ERROR_MSG.format(sys.version_info)) + def raise_ex(self): raise Exception() diff --git a/src/core/tests/Test_PatchInstaller.py b/src/core/tests/Test_PatchInstaller.py index 12068df6..6d6a81e7 100644 --- a/src/core/tests/Test_PatchInstaller.py +++ b/src/core/tests/Test_PatchInstaller.py @@ -16,6 +16,7 @@ import datetime import json +import sys import unittest from core.src.bootstrap.Constants import Constants from core.tests.Test_UbuntuProClient import MockUpdatesResult, MockVersionResult @@ -651,6 +652,18 @@ def test_write_installer_perf_logs_runs_successfully_if_exception_in_get_percent self.assertTrue(runtime.patch_installer.write_installer_perf_logs(True, 1, 1, runtime.maintenance_window, False, Constants.TaskStatus.SUCCEEDED, "")) runtime.stop() + def test_raise_if_min_python_version_not_met(self): + runtime = RuntimeCompositor(ArgumentComposer().get_composed_arguments(), legacy_mode=True) + original_version = sys.version_info + sys.version_info = (2, 6) + # Assert that an exception is raised + with self.assertRaises(Exception) as context: + runtime.patch_installer.start_installation() + self.assertEqual(str(context.exception), Constants.PYTHON_NOT_COMPATIBLE_ERROR_MSG.format(sys.version_info)) + + # reset sys.version to original + sys.version_info = original_version + runtime.stop() if __name__ == '__main__': unittest.main()