From 31f8d980997710facb44df75b4541906eda61901 Mon Sep 17 00:00:00 2001 From: Rajasi Rane Date: Tue, 24 Mar 2020 14:22:35 -0700 Subject: [PATCH 1/2] Bug fixes --- src/core/src/bootstrap/EnvLayer.py | 6 ++++-- src/core/src/core_logic/PatchAssessor.py | 2 +- src/core/src/core_logic/PatchInstaller.py | 2 +- src/core/src/package_managers/PackageManager.py | 13 +++++++++++++ src/core/src/service_interfaces/LifecycleManager.py | 4 ++-- src/extension/src/manifest.xml | 2 +- 6 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/core/src/bootstrap/EnvLayer.py b/src/core/src/bootstrap/EnvLayer.py index 2060b925..cca08f63 100644 --- a/src/core/src/bootstrap/EnvLayer.py +++ b/src/core/src/bootstrap/EnvLayer.py @@ -66,6 +66,7 @@ def run_command_output(self, cmd, no_output=False, chk_err=False): start = time.time() code, output = self.__run_command_output_raw(cmd, no_output, chk_err) self.__write_record(operation, code, output, delay=(time.time()-start)) + return code, output else: return self.__read_record(operation) @@ -271,7 +272,7 @@ def open(self, file_path, mode): def __obtain_file_handle(self, file_path_or_handle, mode='a+'): """ Pass-through for handle. For path, resolution and handle open with retry. """ is_path = False - if isinstance(file_path_or_handle, str): + if isinstance(file_path_or_handle, str) or isinstance(file_path_or_handle, unicode): is_path = True file_path_or_handle = self.open(file_path_or_handle, mode) file_handle = file_path_or_handle @@ -300,6 +301,7 @@ def write_with_retry(self, file_path_or_handle, data, mode='a+'): for i in range(0, Constants.MAX_FILE_OPERATION_RETRY_COUNT): try: file_handle.write(str(data)) + break except Exception as error: if i <= Constants.MAX_FILE_OPERATION_RETRY_COUNT: time.sleep(i + 1) @@ -359,7 +361,7 @@ def total_minutes_from_time_delta(time_delta): @staticmethod def utc_to_standard_datetime(utc_datetime): """ Converts string of format '"%Y-%m-%dT%H:%M:%SZ"' to datetime object """ - return datetime.datetime.strptime(utc_datetime.split(".")[0], "%Y-%m-%dT%H:%M:%SZ") + return datetime.datetime.strptime(utc_datetime.split(".")[0], "%Y-%m-%dT%H:%M:%S") # endregion - DateTime emulator and extensions # region - Core Emulator support functions diff --git a/src/core/src/core_logic/PatchAssessor.py b/src/core/src/core_logic/PatchAssessor.py index 433fb844..537f5a6b 100644 --- a/src/core/src/core_logic/PatchAssessor.py +++ b/src/core/src/core_logic/PatchAssessor.py @@ -20,7 +20,7 @@ def start_assessment(self): self.composite_logger.log('\nStarting patch assessment...') self.status_handler.set_assessment_substatus_json(status=Constants.STATUS_TRANSITIONING) - self.composite_logger.log("\nMachine Id: " + self.env_layer.platform.machine_id) + self.composite_logger.log("\nMachine Id: " + self.env_layer.platform.node()) self.composite_logger.log("Activity Id: " + self.execution_config.activity_id) self.composite_logger.log("Operation request time: " + self.execution_config.start_time) diff --git a/src/core/src/core_logic/PatchInstaller.py b/src/core/src/core_logic/PatchInstaller.py index 13b31b88..fc542596 100644 --- a/src/core/src/core_logic/PatchInstaller.py +++ b/src/core/src/core_logic/PatchInstaller.py @@ -28,7 +28,7 @@ def start_installation(self, simulate=False): """ Kick off a patch installation run """ self.composite_logger.log('\nStarting patch installation...') - self.composite_logger.log("\nMachine Id: " + self.env_layer.platform.machine_id) + self.composite_logger.log("\nMachine Id: " + self.env_layer.platform.node()) self.composite_logger.log("Activity Id: " + self.execution_config.activity_id) self.composite_logger.log("Operation request time: " + self.execution_config.start_time + ", Maintenance Window Duration: " + self.execution_config.duration) diff --git a/src/core/src/package_managers/PackageManager.py b/src/core/src/package_managers/PackageManager.py index 8ca90811..7f270702 100644 --- a/src/core/src/package_managers/PackageManager.py +++ b/src/core/src/package_managers/PackageManager.py @@ -1,4 +1,5 @@ """The is base package manager, which defines the package management relevant operations""" +import os from abc import ABCMeta, abstractmethod from src.bootstrap.Constants import Constants import time @@ -300,3 +301,15 @@ def set_package_manager_setting(self, setting_key, setting_value=""): def do_processes_require_restart(self): """Signals whether processes require a restart due to updates to files""" pass + + def is_reboot_pending(self): + """ Checks if there is a pending reboot on the machine. """ + try: + pending_file_exists = os.path.isfile(self.REBOOT_PENDING_FILE_PATH) + pending_processes_exists = self.do_processes_require_restart() + self.composite_logger.log_debug(" - Reboot required debug flags: " + str(pending_file_exists) + ", " + str(pending_processes_exists) + ".") + return pending_file_exists or pending_processes_exists + except Exception as error: + self.composite_logger.log_error('Error while checking for reboot pending: ' + repr(error)) + return True # defaults for safety + diff --git a/src/core/src/service_interfaces/LifecycleManager.py b/src/core/src/service_interfaces/LifecycleManager.py index 33a8931d..c014a5e9 100644 --- a/src/core/src/service_interfaces/LifecycleManager.py +++ b/src/core/src/service_interfaces/LifecycleManager.py @@ -62,7 +62,7 @@ def read_extension_sequence(self): # Read (with retries for only IO Errors) for i in range(0, Constants.MAX_FILE_OPERATION_RETRY_COUNT): try: - with self.env_layer.file_system.open(self.ext_state_file_path) as file_handle: + with self.env_layer.file_system.open(self.ext_state_file_path, mode="r") as file_handle: return json.load(file_handle)['extensionSequence'] except Exception as error: if i <= Constants.MAX_FILE_OPERATION_RETRY_COUNT: @@ -85,7 +85,7 @@ def read_core_sequence(self): # Read (with retries for only IO Errors) - TODO: Refactor common code for i in range(0, Constants.MAX_FILE_OPERATION_RETRY_COUNT): try: - with self.env_layer.file_system.open(self.core_state_file_path) as file_handle: + with self.env_layer.file_system.open(self.core_state_file_path, mode="r") as file_handle: core_sequence = json.load(file_handle)['coreSequence'] print(str(core_sequence)) return core_sequence diff --git a/src/extension/src/manifest.xml b/src/extension/src/manifest.xml index 7d20490c..20083270 100644 --- a/src/extension/src/manifest.xml +++ b/src/extension/src/manifest.xml @@ -2,7 +2,7 @@ Microsoft.CPlat.Core LinuxPatchExtension - 1.4.23 + 1.4.24 VmRole From 8f7aa6c1338943fd2c674dcc7672c10da9aa74fd Mon Sep 17 00:00:00 2001 From: Rajasi Rane Date: Tue, 24 Mar 2020 15:44:15 -0700 Subject: [PATCH 2/2] Fix for Core Packager: adding __main__.py to MsftLinuxPatchCore.py --- src/tools/Package-Core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/Package-Core.py b/src/tools/Package-Core.py index a6bc9b9b..8244345d 100644 --- a/src/tools/Package-Core.py +++ b/src/tools/Package-Core.py @@ -26,7 +26,7 @@ def read_python_module(source_code_path, module_name): for line in py_file: if line.startswith('import'): imports.append(line) - elif line.strip().startswith('class') or line.strip().startswith('def main(argv):'): + elif line.strip().startswith('class') or line.strip().startswith('def main(argv):') or line.strip().startswith('if __name__ == "__main__"'): is_code_body = True if is_code_body is True: