From d38ffe4b781fdfd0edab24912f242963033dab46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Rebollo=20P=C3=A9rez?= Date: Thu, 9 May 2024 17:32:22 +0100 Subject: [PATCH 1/9] feat: include retry for install package logic --- .../wazuh_testing/tools/system.py | 80 +++++++++++++++---- 1 file changed, 65 insertions(+), 15 deletions(-) diff --git a/deps/wazuh_testing/wazuh_testing/tools/system.py b/deps/wazuh_testing/wazuh_testing/tools/system.py index 5e3611f95f..b88e1aa483 100644 --- a/deps/wazuh_testing/wazuh_testing/tools/system.py +++ b/deps/wazuh_testing/wazuh_testing/tools/system.py @@ -10,6 +10,7 @@ import xml.dom.minidom as minidom from threading import Thread from typing import List, Union +from time import sleep import testinfra import yaml @@ -493,30 +494,79 @@ def install_package(self, host, url, system): Example: host_manager.install_package('my_host', 'http://example.com/package.deb', system='ubuntu') """ - extension = '.msi' - result = None + def install_msi_package(host, url): + result = self.get_host(host).ansible("win_package", + f"path={url} arguments=/passive", check=False) + return result - if system == 'windows': - if url.lower().endswith(extension): - result = self.get_host(host).ansible("win_package", f"path={url} arguments=/passive", check=False) - else: - result = self.get_host(host).ansible("win_package", f"path={url} arguments=/S", check=False) - elif system == 'ubuntu': + def install_exe_package(host, url): + result = self.get_host(host).ansible("win_package", f"path={url} arguments=/S", check=False) + + return result + + def install_apt_package(host, url): result = self.get_host(host).ansible("apt", f"deb={url}", check=False) - elif system == 'centos': + + return result + + def install_yum_package(host, url): result = self.get_host(host).ansible("yum", f"name={url} state=present " - 'disable_gpg_check=True', check=False) - elif system == 'macos': + 'disable_gpg_check=True', check=False) + return result + + def install_pkg_package(host, url): package_name = url.split('/')[-1] result = self.get_host(host).ansible("command", f"curl -LO {url}", check=False) cmd = f"installer -pkg {package_name} -target /" result = self.get_host(host).ansible("command", cmd, check=False) - else: - raise ValueError(f"Unsupported system: {system}") - logging.info(f"Package installed result {result}") + return result + + retry_installation_errors = { + "corrupted_download": 'The downloaded file could not be read. Verify that the file' + 'exists and that you can access it.' + } + number_max_retries = 3 + sleep_time_between_retries = 10 + result = {} + + extension = url.lower().split('.')[-1] + + for _ in range(number_max_retries): + if system == 'windows': + if extension == 'msi': + result = install_msi_package(host, url) + elif extension == 'exe': + result = install_exe_package(host, url) + else: + raise ValueError(f"Unsupported extension: {extension} for Windows systems") + elif system == 'ubuntu': + if extension == 'deb': + result = install_apt_package(host, url) + else: + raise ValueError(f"Unsupported extension: {extension} for Ubuntu systems") + elif system == 'centos': + if extension == 'rpm': + result = install_yum_package(host, url) + else: + raise ValueError(f"Unsupported extension: {extension} for CentOS systems") + elif system == 'macos': + if extension == '.pkg': + result = install_pkg_package(host, url) + else: + raise ValueError(f"Unsupported extension: {extension} for MacOS systems") + else: + raise ValueError(f"Unsupported system: {system}") + + if result.get('msg') == retry_installation_errors["corrupted_download"]: + logging.error(f"Error installing {url} in {host}:" + 'Corrupted download detected. Retrying installation...') + sleep(sleep_time_between_retries) + else: + break - if not (result['changed'] or result.get('rc') == 0) or not (result['changed'] or result.get('stderr', None) == ''): + if not (result.get('changed', False) or result.get('rc') == 0) or \ + not (result.get('changed', False) or result.get('rc') == 0 or result.get('stderr', None) == ''): raise RuntimeError(f"Failed to install package in {host}: {result}") def install_npm_package(self, host, url, system='ubuntu'): From 5aed3b1658fd4618f88e481e18a1f3d06ee57e99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Rebollo=20P=C3=A9rez?= Date: Fri, 10 May 2024 15:35:26 +0100 Subject: [PATCH 2/9] fix: improve retry error logic --- .../wazuh_testing/tools/system.py | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/deps/wazuh_testing/wazuh_testing/tools/system.py b/deps/wazuh_testing/wazuh_testing/tools/system.py index b88e1aa483..5daccad559 100644 --- a/deps/wazuh_testing/wazuh_testing/tools/system.py +++ b/deps/wazuh_testing/wazuh_testing/tools/system.py @@ -8,6 +8,8 @@ import sys import tempfile import xml.dom.minidom as minidom +import re + from threading import Thread from typing import List, Union from time import sleep @@ -497,6 +499,7 @@ def install_package(self, host, url, system): def install_msi_package(host, url): result = self.get_host(host).ansible("win_package", f"path={url} arguments=/passive", check=False) + return result def install_exe_package(host, url): @@ -522,10 +525,10 @@ def install_pkg_package(host, url): return result - retry_installation_errors = { - "corrupted_download": 'The downloaded file could not be read. Verify that the file' - 'exists and that you can access it.' - } + retry_installation_errors = [ + 'This installation package could not be opened', + ] + number_max_retries = 3 sleep_time_between_retries = 10 result = {} @@ -558,15 +561,20 @@ def install_pkg_package(host, url): else: raise ValueError(f"Unsupported system: {system}") - if result.get('msg') == retry_installation_errors["corrupted_download"]: + if any(re.search(error, result.get('msg', '')) for error in retry_installation_errors): logging.error(f"Error installing {url} in {host}:" 'Corrupted download detected. Retrying installation...') sleep(sleep_time_between_retries) else: + logging.error("Installation failed. Installation will not be retried.") break - if not (result.get('changed', False) or result.get('rc') == 0) or \ - not (result.get('changed', False) or result.get('rc') == 0 or result.get('stderr', None) == ''): + failed_installation = not (result.get('changed', False) or result.get('rc') == 0) \ + or not (result.get('changed', False) or result.get('rc') == 0 or result.get('stderr', None) == '') + + logging.debug(f"Package installation result {result}") + + if failed_installation: raise RuntimeError(f"Failed to install package in {host}: {result}") def install_npm_package(self, host, url, system='ubuntu'): @@ -691,7 +699,7 @@ def remove_package(self, host, system, package_uninstall_name=None, custom_unins or not (remove_operation_result['changed'] or remove_operation_result.get('stderr', None) == ''): raise RuntimeError(f"Failed to remove package in {host}: {remove_operation_result}") - logging.info(f"Package removed result {remove_operation_result}") + logging.debug(f"Package removed result {remove_operation_result}") return remove_operation_result From 2f0801df7bd316da152073d5625f8880969709e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Rebollo=20P=C3=A9rez?= Date: Fri, 10 May 2024 15:41:19 +0100 Subject: [PATCH 3/9] feat: improve logging message --- deps/wazuh_testing/wazuh_testing/tools/system.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/wazuh_testing/wazuh_testing/tools/system.py b/deps/wazuh_testing/wazuh_testing/tools/system.py index 5daccad559..08642cc3c1 100644 --- a/deps/wazuh_testing/wazuh_testing/tools/system.py +++ b/deps/wazuh_testing/wazuh_testing/tools/system.py @@ -563,7 +563,7 @@ def install_pkg_package(host, url): if any(re.search(error, result.get('msg', '')) for error in retry_installation_errors): logging.error(f"Error installing {url} in {host}:" - 'Corrupted download detected. Retrying installation...') + 'Corrupted package detected. Retrying installation...') sleep(sleep_time_between_retries) else: logging.error("Installation failed. Installation will not be retried.") From 44bdb7802523f3c946ae5297a460b2962aeed3ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Rebollo=20P=C3=A9rez?= Date: Fri, 10 May 2024 15:44:11 +0100 Subject: [PATCH 4/9] feat: move retry variables to param --- deps/wazuh_testing/wazuh_testing/tools/system.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/deps/wazuh_testing/wazuh_testing/tools/system.py b/deps/wazuh_testing/wazuh_testing/tools/system.py index 08642cc3c1..f78c4b5940 100644 --- a/deps/wazuh_testing/wazuh_testing/tools/system.py +++ b/deps/wazuh_testing/wazuh_testing/tools/system.py @@ -480,7 +480,7 @@ def download_file(self, host, url, dest_path, mode='755'): return result - def install_package(self, host, url, system): + def install_package(self, host, url, system, retry=3, retry_delay=5): """ Installs a package on the specified host. @@ -529,13 +529,11 @@ def install_pkg_package(host, url): 'This installation package could not be opened', ] - number_max_retries = 3 - sleep_time_between_retries = 10 result = {} extension = url.lower().split('.')[-1] - for _ in range(number_max_retries): + for _ in range(retry): if system == 'windows': if extension == 'msi': result = install_msi_package(host, url) @@ -564,7 +562,7 @@ def install_pkg_package(host, url): if any(re.search(error, result.get('msg', '')) for error in retry_installation_errors): logging.error(f"Error installing {url} in {host}:" 'Corrupted package detected. Retrying installation...') - sleep(sleep_time_between_retries) + sleep(retry_delay) else: logging.error("Installation failed. Installation will not be retried.") break From cb85957772dc489b1356660dbb247013f05ad0af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Rebollo=20P=C3=A9rez?= Date: Fri, 10 May 2024 15:52:19 +0100 Subject: [PATCH 5/9] docs: include 5363 changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff2f43ed12..2160366709 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,7 @@ All notable changes to this project will be documented in this file. ### Fixed +- Fix E2E Vulnerability Detection Windows package installation error ([#5363](https://github.com/wazuh/wazuh-qa/pull/5363)) \- (Framework) - Fix test cases in Vulnerability Detection E2E test by adding new packages ([#5349](https://github.com/wazuh/wazuh-qa/pull/5349)) \- (Tests) - Fix macOS alert collection for E2E Vulnerability Detection tests ([#5337](https://github.com/wazuh/wazuh-qa/pull/5337)) \- (Framework) - Fix packages in Windows and macOS upgrade cases ([#5223](https://github.com/wazuh/wazuh-qa/pull/5223)) \- (Framework + Tests) From dae2ba162aa1cd8c70dd6e0a96828952a7046a31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Rebollo=20P=C3=A9rez?= Date: Fri, 10 May 2024 15:52:48 +0100 Subject: [PATCH 6/9] fix: improve failed message logic --- .../wazuh_testing/tools/system.py | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/deps/wazuh_testing/wazuh_testing/tools/system.py b/deps/wazuh_testing/wazuh_testing/tools/system.py index f78c4b5940..26a9c88efe 100644 --- a/deps/wazuh_testing/wazuh_testing/tools/system.py +++ b/deps/wazuh_testing/wazuh_testing/tools/system.py @@ -559,21 +559,19 @@ def install_pkg_package(host, url): else: raise ValueError(f"Unsupported system: {system}") - if any(re.search(error, result.get('msg', '')) for error in retry_installation_errors): - logging.error(f"Error installing {url} in {host}:" - 'Corrupted package detected. Retrying installation...') - sleep(retry_delay) - else: - logging.error("Installation failed. Installation will not be retried.") - break + failed_installation = not (result.get('changed', False) or result.get('rc') == 0) \ + or not (result.get('changed', False) or result.get('rc') == 0 or result.get('stderr', None) == '') - failed_installation = not (result.get('changed', False) or result.get('rc') == 0) \ - or not (result.get('changed', False) or result.get('rc') == 0 or result.get('stderr', None) == '') + logging.debug(f"Package installation result {result}") - logging.debug(f"Package installation result {result}") - - if failed_installation: - raise RuntimeError(f"Failed to install package in {host}: {result}") + if failed_installation: + if any(re.search(error, result.get('msg', '')) for error in retry_installation_errors): + logging.error(f"Error installing {url} in {host}:" + 'Corrupted package detected. Retrying installation...') + sleep(retry_delay) + else: + logging.error("Installation failed. Installation will not be retried.") + raise RuntimeError(f"Failed to install package in {host}: {result}") def install_npm_package(self, host, url, system='ubuntu'): """ From 8027569184c1d81f9e9c75828719e8d37dbe2793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Rebollo=20P=C3=A9rez?= Date: Fri, 10 May 2024 15:54:25 +0100 Subject: [PATCH 7/9] fix: install_package error logic --- deps/wazuh_testing/wazuh_testing/tools/system.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/deps/wazuh_testing/wazuh_testing/tools/system.py b/deps/wazuh_testing/wazuh_testing/tools/system.py index 26a9c88efe..b8a59ea373 100644 --- a/deps/wazuh_testing/wazuh_testing/tools/system.py +++ b/deps/wazuh_testing/wazuh_testing/tools/system.py @@ -569,9 +569,11 @@ def install_pkg_package(host, url): logging.error(f"Error installing {url} in {host}:" 'Corrupted package detected. Retrying installation...') sleep(retry_delay) + else: + logging.error("Installation failed. Installation will not be retried.") + raise RuntimeError(f"Failed to install package in {host}: {result}") else: - logging.error("Installation failed. Installation will not be retried.") - raise RuntimeError(f"Failed to install package in {host}: {result}") + break def install_npm_package(self, host, url, system='ubuntu'): """ From 3d321d911daef2cfb21504baee275a5f919675eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Rebollo=20P=C3=A9rez?= Date: Fri, 10 May 2024 16:31:51 +0100 Subject: [PATCH 8/9] refac: install package method --- .../wazuh_testing/tools/system.py | 62 +++++++++---------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/deps/wazuh_testing/wazuh_testing/tools/system.py b/deps/wazuh_testing/wazuh_testing/tools/system.py index b8a59ea373..a089223ce2 100644 --- a/deps/wazuh_testing/wazuh_testing/tools/system.py +++ b/deps/wazuh_testing/wazuh_testing/tools/system.py @@ -530,51 +530,50 @@ def install_pkg_package(host, url): ] result = {} + failed_installation = False extension = url.lower().split('.')[-1] + system_supported = ['windows', 'ubuntu', 'centos', 'macos'] + installer_map = { + 'msi': install_msi_package, + 'exe': install_exe_package, + 'deb': install_apt_package, + 'rpm': install_yum_package, + 'pkg': install_pkg_package + } + + if system not in system_supported: + raise ValueError(f"Unsupported system: {system}") + for _ in range(retry): - if system == 'windows': - if extension == 'msi': - result = install_msi_package(host, url) - elif extension == 'exe': - result = install_exe_package(host, url) - else: - raise ValueError(f"Unsupported extension: {extension} for Windows systems") - elif system == 'ubuntu': - if extension == 'deb': - result = install_apt_package(host, url) - else: - raise ValueError(f"Unsupported extension: {extension} for Ubuntu systems") - elif system == 'centos': - if extension == 'rpm': - result = install_yum_package(host, url) - else: - raise ValueError(f"Unsupported extension: {extension} for CentOS systems") - elif system == 'macos': - if extension == '.pkg': - result = install_pkg_package(host, url) - else: - raise ValueError(f"Unsupported extension: {extension} for MacOS systems") - else: - raise ValueError(f"Unsupported system: {system}") + installer_func = installer_map.get(extension, None) - failed_installation = not (result.get('changed', False) or result.get('rc') == 0) \ - or not (result.get('changed', False) or result.get('rc') == 0 or result.get('stderr', None) == '') + if not installer_func: + raise ValueError(f"Unsupported extension: {extension} for Windows systems") + + result = installer_func(host, url) logging.debug(f"Package installation result {result}") + failed_installation = not (result.get('changed', False) or result.get('rc') == 0) \ + or not (result.get('changed', False) or result.get('rc') == 0 or result.get('stderr', None) == '') if failed_installation: - if any(re.search(error, result.get('msg', '')) for error in retry_installation_errors): - logging.error(f"Error installing {url} in {host}:" - 'Corrupted package detected. Retrying installation...') - sleep(retry_delay) - else: + if not any(re.search(error, result.get('msg', '')) for error in retry_installation_errors): logging.error("Installation failed. Installation will not be retried.") raise RuntimeError(f"Failed to install package in {host}: {result}") + + logging.error(f"Error installing {url} in {host}:" + 'Corrupted package detected. Retrying installation...') + sleep(retry_delay) else: break + if failed_installation: + raise RuntimeError(f"Failed to install package in {host}: {result}") + + return result + def install_npm_package(self, host, url, system='ubuntu'): """ Installs a package on the specified host using npm. @@ -665,7 +664,6 @@ def remove_package(self, host, system, package_uninstall_name=None, custom_unins host_manager.remove_package('my_host', 'my_package', system='ubuntu') """ logging.info(f"Removing package {package_uninstall_name} from host {host}") - logging.info(f"System: {system}") remove_operation_result = False From b2744532148e76c797de04b7994fca197e92af4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Rebollo=20P=C3=A9rez?= Date: Fri, 10 May 2024 16:34:03 +0100 Subject: [PATCH 9/9] fix: logging message --- deps/wazuh_testing/wazuh_testing/tools/system.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/wazuh_testing/wazuh_testing/tools/system.py b/deps/wazuh_testing/wazuh_testing/tools/system.py index 40a5634037..8066c04a91 100644 --- a/deps/wazuh_testing/wazuh_testing/tools/system.py +++ b/deps/wazuh_testing/wazuh_testing/tools/system.py @@ -550,7 +550,7 @@ def install_pkg_package(host, url): installer_func = installer_map.get(extension, None) if not installer_func: - raise ValueError(f"Unsupported extension: {extension} for Windows systems") + raise ValueError(f"Unsupported extension: {extension} for {system}") result = installer_func(host, url)