Skip to content
2 changes: 1 addition & 1 deletion src/core/src/bootstrap/Constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions src/core/src/core_logic/PatchAssessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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")
Expand Down Expand Up @@ -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
Expand Down
10 changes: 9 additions & 1 deletion src/core/src/core_logic/PatchInstaller.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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...')

Expand Down Expand Up @@ -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...")
Expand Down
1 change: 0 additions & 1 deletion src/core/tests/Test_CoreMain.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import os
import re
import shutil
import time
import unittest
import uuid

Expand Down
10 changes: 10 additions & 0 deletions src/core/tests/Test_PatchAssessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import datetime
import json
import os
import sys
import unittest

from core.src.bootstrap.Constants import Constants
Expand All @@ -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):
Expand Down Expand Up @@ -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()

Expand Down
13 changes: 13 additions & 0 deletions src/core/tests/Test_PatchInstaller.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()