diff --git a/.gitignore b/.gitignore index bc00a98..05c646c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ /sos-4.10.0.tar.gz /sos-4.10.1.tar.gz /sos-4.10.2.tar.gz +/sos-4.11.0.tar.gz diff --git a/0001-python3-walrus-operator-and-rhel8-changes-only.patch b/0001-python3-walrus-operator-and-rhel8-changes-only.patch index 491a3b6..ef7044d 100644 --- a/0001-python3-walrus-operator-and-rhel8-changes-only.patch +++ b/0001-python3-walrus-operator-and-rhel8-changes-only.patch @@ -39,19 +39,6 @@ self.db_folder = "/var/snap/juju-db/current/db" super().setup() ---- a/sos/report/plugins/__init__.py 2025-08-21 12:41:10.418390705 +0200 -+++ b/sos/report/plugins/__init__.py 2025-08-21 12:55:39.546634618 +0200 -@@ -2965,8 +2965,9 @@ - :rtype: ``str`` - """ - if self.container_exists(container, runtime) or \ -- ((_runtime := self._get_container_runtime(runtime)) and -+ ((self._get_container_runtime(runtime)) and - runas is not None): -+ _runtime = self._get_container_runtime(runtime) - return _runtime.fmt_container_cmd(container, cmd, quotecmd) - return '' - --- a/sos/report/plugins/loki.py 2025-11-24 11:20:56.237814760 +0100 +++ b/sos/report/plugins/loki.py 2025-11-24 11:28:37.466603011 +0100 @@ -143,7 +143,8 @@ @@ -100,3 +87,30 @@ futures = executor.map(obfuscate_arc_files, archive_list, [file_list[i::self.opts.jobs] for i in range(self.opts.jobs)]) + +--- a/sos/collector/sosnode.py 2026-04-02 10:15:34.743009569 +0200 ++++ b/sos/collector/sosnode.py 2026-04-02 10:17:42.557250748 +0200 +@@ -163,7 +163,8 @@ + if not self._sudo_binary: + _bin = self.opts.sudo_binary.split('/')[-1] + # verify the provided binary is at least in our PATH +- if ret := self.run_command(f"command -v {_bin}"): ++ ret = self.run_command(f"command -v {_bin}") ++ if ret: + if not ret['status'] == 0: + err = f"Privilege escalation command not in PATH: {_bin}" + self.log_error(err) + +--- a/sos/report/plugins/logs.py 2026-04-02 10:19:59.641196712 +0200 ++++ b/sos/report/plugins/logs.py 2026-04-02 10:20:28.313299348 +0200 +@@ -38,7 +38,8 @@ + # this WILL break on anything other than basic echos + # as shown in the rsyslog documentation + if _ent.startswith('echo '): +- if envc := os.getenv(_ent.split()[1].strip(' $`')): ++ envc = os.getenv(_ent.split()[1].strip(' $`')) ++ if envc: + confs += glob.glob(envc) + else: + confs += glob.glob(_ent) + diff --git a/0003-gcp-Catch-exceptions-when-PRODUCT_PATH-doesnt-exist.patch b/0003-gcp-Catch-exceptions-when-PRODUCT_PATH-doesnt-exist.patch deleted file mode 100644 index 006c44c..0000000 --- a/0003-gcp-Catch-exceptions-when-PRODUCT_PATH-doesnt-exist.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 178d7fb1296dbcb744867d1b8a29678d1a3b0820 Mon Sep 17 00:00:00 2001 -From: Pavel Moravec -Date: Mon, 26 Jan 2026 12:14:19 +0100 -Subject: [PATCH] [gcp] Catch exceptions when PRODUCT_PATH doesnt exist - -Catch exceptions when /sys/devices/virtual/dmi/id/product_name does not -exist on a (rare) system, while user manually enabled gcp plugin. - -Closes: #4215 - -Signed-off-by: Pavel Moravec ---- - sos/report/plugins/gcp.py | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/sos/report/plugins/gcp.py b/sos/report/plugins/gcp.py -index 24b50323..43ceec00 100644 ---- a/sos/report/plugins/gcp.py -+++ b/sos/report/plugins/gcp.py -@@ -38,8 +38,11 @@ class GCP(Plugin, IndependentPlugin): - Checks if this plugin should be executed based on the presence of - GCE entry in sysfs. - """ -- with open(self.PRODUCT_PATH, encoding='utf-8') as sys_file: -- return "Google Compute Engine" in sys_file.read() -+ try: -+ with open(self.PRODUCT_PATH, encoding='utf-8') as sys_file: -+ return "Google Compute Engine" in sys_file.read() -+ except OSError: -+ return False - - def setup(self): - """ --- -2.52.0 - diff --git a/0006-revert-PR4092.patch b/0003-revert-PR4092.patch similarity index 100% rename from 0006-revert-PR4092.patch rename to 0003-revert-PR4092.patch diff --git a/0004-aap_containerized-Carry-forward-postproc-from-other.patch b/0004-aap_containerized-Carry-forward-postproc-from-other.patch deleted file mode 100644 index 8924e7e..0000000 --- a/0004-aap_containerized-Carry-forward-postproc-from-other.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 0c237bcaf476c9b5a28165b9124e08163af707ab Mon Sep 17 00:00:00 2001 -From: Pavel Moravec -Date: Fri, 30 Jan 2026 21:50:52 +0100 -Subject: [PATCH] [aap_containerized] Carry forward postproc from other AAP - plugins - -Secrets obfuscations from 2a46e99 commit must be reflected in -containerized plugin. - -Further, fix a typo in a regexp, to properly obfuscate: - -EMAIL_HOST_PASSWORD = 'FAKESECRET!!!' - -in (both) controller's settings. - -Closes: #4213 - -Signed-off-by: Pavel Moravec ---- - sos/report/plugins/aap_containerized.py | 37 +++++++++++++++++++------ - sos/report/plugins/aap_controller.py | 4 +-- - 2 files changed, 30 insertions(+), 11 deletions(-) - -diff --git a/sos/report/plugins/aap_containerized.py b/sos/report/plugins/aap_containerized.py -index 7baa5fb3..0c85d4b2 100644 ---- a/sos/report/plugins/aap_containerized.py -+++ b/sos/report/plugins/aap_containerized.py -@@ -41,6 +41,7 @@ class AAPContainerized(Plugin, RedHatPlugin): - def setup(self): - # Check if username is passed as argument - username = self.get_option("username") -+ self.aap_directory_name = self.get_option("directory") - if not username: - self._log_warn("AAP username is missing, use '-k " - "aap_containerized.username=' to set it") -@@ -61,16 +62,15 @@ class AAPContainerized(Plugin, RedHatPlugin): - return - - # Grab aap installation directory under user's home -- if not self.get_option("directory"): -+ if not self.aap_directory_name: - user_home_directory = os.path.expanduser(f"~{username}") -- aap_directory_name = self.path_join(user_home_directory, "aap") -- else: -- aap_directory_name = self.get_option("directory") -+ self.aap_directory_name = self.path_join(user_home_directory, -+ "aap") - - # Don't collect cert and key files from the installation directory -- if self.path_exists(aap_directory_name): -+ if self.path_exists(self.aap_directory_name): - forbidden_paths = [ -- self.path_join(aap_directory_name, path) -+ self.path_join(self.aap_directory_name, path) - for path in [ - "containers", - "tls", -@@ -93,10 +93,10 @@ class AAPContainerized(Plugin, RedHatPlugin): - ] - ] - self.add_forbidden_path(forbidden_paths) -- self.add_copy_spec(aap_directory_name) -+ self.add_copy_spec(self.aap_directory_name) - else: -- self._log_error(f"Directory {aap_directory_name} does not exist " -- "or invalid absolute path provided") -+ self._log_error(f"Directory {self.aap_directory_name} does not " -+ "exist or invalid absolute path provided.") - - # Gather output of following podman commands as user - podman_commands = [ -@@ -200,6 +200,24 @@ class AAPContainerized(Plugin, RedHatPlugin): - return False - - def postproc(self): -+ # remove controller email password -+ file_path = f"{self.aap_directory_name}/controller/etc/settings.py" -+ jreg = r"(EMAIL_HOST_PASSWORD\s*=\s*)\'(.+)\'" -+ repl = r"\1********" -+ self.do_path_regex_sub(file_path, jreg, repl) -+ -+ # remove gateway database password -+ file_path = f"{self.aap_directory_name}/gateway/etc/settings.py" -+ jreg = r"(\s*'PASSWORD'\s*:\s*)('.*')" -+ repl = r"\1********" -+ self.do_path_regex_sub(file_path, jreg, repl) -+ -+ # Mask EDA optional secrets -+ file_path = f"{self.aap_directory_name}/eda/etc/settings.yaml" -+ regex = r"(\s*)(PASSWORD|MQ_USER_PASSWORD|SECRET_KEY)(:\s*)(.*$)" -+ replacement = r'\1\2\3********' -+ self.do_path_regex_sub(file_path, regex, replacement) -+ - # Mask PASSWORD from print_settings command - jreg = r'((["\']?PASSWORD["\']?\s*[:=]\s*)[rb]?["\'])(.*?)(["\'])' - self.do_cmd_output_sub( -@@ -214,4 +232,5 @@ class AAPContainerized(Plugin, RedHatPlugin): - jreg, - r'\1**********\5') - -+ - # vim: set et ts=4 sw=4 : -diff --git a/sos/report/plugins/aap_controller.py b/sos/report/plugins/aap_controller.py -index afb2508c..e2b5e39e 100644 ---- a/sos/report/plugins/aap_controller.py -+++ b/sos/report/plugins/aap_controller.py -@@ -83,12 +83,12 @@ class AAPControllerPlugin(Plugin, RedHatPlugin): - self.do_path_regex_sub("/etc/tower/conf.d/postgres.py", jreg, repl) - - # remove email password -- jreg = r"(EMAIL_HOST_PASSWORD\s*=)\'(.+)\'" -+ jreg = r"(EMAIL_HOST_PASSWORD\s*=\s*)\'(.+)\'" - repl = r"\1********" - self.do_path_regex_sub("/etc/tower/settings.py", jreg, repl) - - # remove email password (if customized) -- jreg = r"(EMAIL_HOST_PASSWORD\s*=)\'(.+)\'" -+ jreg = r"(EMAIL_HOST_PASSWORD\s*=\s*)\'(.+)\'" - repl = r"\1********" - self.do_path_regex_sub("/etc/tower/conf.d/custom.py", jreg, repl) - --- -2.52.0 - diff --git a/0005-cleaner-Update-filename-after-converting-pem-to-text.patch b/0005-cleaner-Update-filename-after-converting-pem-to-text.patch deleted file mode 100644 index 1781c61..0000000 --- a/0005-cleaner-Update-filename-after-converting-pem-to-text.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 0c7626683ae2dcbc5f7b0f00e0980895e0e1ce0d Mon Sep 17 00:00:00 2001 -From: Pavel Moravec -Date: Mon, 2 Feb 2026 14:03:26 +0100 -Subject: [PATCH] [cleaner] Update filename after converting pem to text - -When converting PEM certificate to text, we need to update filename and -short_name to the newly created file, to ensure cleaner handles the -right file. - -Also, rename misleading short_name to rel_name as it keeps the rel.path -to the filename. - -Closes: #4219 -Relevant: RHEL-145301 - -Signed-off-by: Pavel Moravec ---- - sos/cleaner/archives/__init__.py | 34 +++++++++++++++++++------------- - 1 file changed, 20 insertions(+), 14 deletions(-) - -diff --git a/sos/cleaner/archives/__init__.py b/sos/cleaner/archives/__init__.py -index e918e2e3..af6ed222 100644 ---- a/sos/cleaner/archives/__init__.py -+++ b/sos/cleaner/archives/__init__.py -@@ -156,18 +156,18 @@ class SoSObfuscationArchive(): - for filename in flist: - self.log_debug(f" pid={os.getpid()}: obfuscating {filename}") - try: -- short_name = filename.split(self.archive_name + '/')[1] -- if self.should_skip_file(short_name): -+ rel_name = os.path.relpath(filename, start=self.extracted_path) -+ if self.should_skip_file(rel_name): - continue - if (not self.keep_binary_files and -- self.should_remove_file(short_name)): -+ self.should_remove_file(rel_name)): - # We reach this case if the option --keep-binary-files - # was not used, and the file is in a list to be removed -- self.remove_file(short_name) -+ self.remove_file(rel_name) - continue - if (self.keep_binary_files and - (file_is_binary(filename) or -- self.should_remove_file(short_name))): -+ self.should_remove_file(rel_name))): - # We reach this case if the option --keep-binary-files - # is used. In this case we want to make sure - # the cleaner doesn't try to clean a binary file -@@ -180,28 +180,32 @@ class SoSObfuscationArchive(): - if is_certificate: - if is_certificate == "certificatekey": - # Always remove certificate Key files -- self.remove_file(short_name) -+ self.remove_file(rel_name) - continue - if self.treat_certificates == "keep": - continue - if self.treat_certificates == "remove": -- self.remove_file(short_name) -+ self.remove_file(rel_name) - continue - if self.treat_certificates == "obfuscate": -- self.certificate_to_text(filename) -+ # since the original filename is deleted, we must -+ # update both "filename" and "rel_name" -+ filename = self.certificate_to_text(filename) -+ rel_name = os.path.relpath(filename, -+ start=self.extracted_path) - _parsers = [ - _p for _p in self.parsers if not - any( -- _skip.match(short_name) for _skip in _p.skip_patterns -+ _skip.match(rel_name) for _skip in _p.skip_patterns - ) - ] - if not _parsers: - self.log_debug( -- f"Skipping obfuscation of {short_name or filename} " -+ f"Skipping obfuscation of {rel_name or filename} " - f"due to matching file skip pattern" - ) - continue -- self.log_debug(f"Obfuscating {short_name or filename}") -+ self.log_debug(f"Obfuscating {rel_name or filename}") - subs = 0 - with tempfile.NamedTemporaryFile(mode='w', dir=self.tmpdir) \ - as tfile: -@@ -214,13 +218,13 @@ class SoSObfuscationArchive(): - tfile.write(line) - except Exception as err: - self.log_debug(f"Unable to obfuscate " -- f"{short_name}: {err}") -+ f"{rel_name}: {err}") - tfile.seek(0) - if subs: - shutil.copyfile(tfile.name, filename) - self.update_sub_count(subs) - -- self.obfuscate_filename(short_name, filename) -+ self.obfuscate_filename(rel_name, filename) - - except Exception as err: - self.log_debug(f" pid={os.getpid()}: caught exception on " -@@ -309,11 +313,13 @@ class SoSObfuscationArchive(): - """Convert a certificate to text. This is used when cleaner encounters - a certificate file and the option 'treat_certificates' is 'obfuscate'. - """ -+ out_fn = f"{fname}.text" - self.log_info(f"Converting certificate file '{fname}' to text") - sos_get_command_output( - f"openssl storeutl -noout -text -certs {str(fname)}", -- to_file=f"{fname}.text") -+ to_file=out_fn) - os.remove(fname) -+ return out_fn - - def remove_file(self, fname): - """Remove a file from the archive. This is used when cleaner encounters --- -2.52.0 - diff --git a/sos.spec b/sos.spec index ad1c2fd..31740b2 100644 --- a/sos.spec +++ b/sos.spec @@ -4,8 +4,8 @@ Summary: A set of tools to gather troubleshooting information from a system Name: sos -Version: 4.10.2 -Release: 2%{?dist} +Version: 4.11.0 +Release: 1%{?dist} Group: Applications/System Source0: https://github.com/sosreport/sos/archive/%{version}/sos-%{version}.tar.gz Source1: sos-audit-%{auditversion}.tgz @@ -24,10 +24,7 @@ Conflicts: vdsm < 4.40 Obsoletes: sos-collector Patch1: 0001-python3-walrus-operator-and-rhel8-changes-only.patch Patch2: 0002-sosreport-binary.patch -Patch3: 0003-gcp-Catch-exceptions-when-PRODUCT_PATH-doesnt-exist.patch -Patch4: 0004-aap_containerized-Carry-forward-postproc-from-other.patch -Patch5: 0005-cleaner-Update-filename-after-converting-pem-to-text.patch -Patch6: 0006-revert-PR4092.patch +Patch3: 0003-revert-PR4092.patch %description Sos is a set of tools that gathers information about system @@ -41,9 +38,6 @@ support technicians and developers. %patch -P 1 -p1 %patch -P 2 -p1 %patch -P 3 -p1 -%patch -P 4 -p1 -%patch -P 5 -p1 -%patch -P 6 -p1 %build %py3_build @@ -116,6 +110,10 @@ of the system. Currently storage and filesystem commands are audited. %license LICENSE %changelog +* Thu Apr 02 2026 Jan Jansky = 4.11.0-1 +- Update to 4.11.0-1 + Resolves: RHEL-157813 + * Thu Feb 26 2026 Jan Jansky = 4.10.2-2 - Update to 4.10.2-2 Resolves: RHEL-142630 diff --git a/sources b/sources index e304d30..8ec0cef 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (sos-4.10.2.tar.gz) = b79021d462f8f192bac8bd5651227cb1bbd7dfefae27bfc934194b29157512828b8fa8d7296283c8f555176f4d2662e08b74f54901d84db8833a0ac82b3d6fac +SHA512 (sos-4.11.0.tar.gz) = ba35fdd460a28cc43cf5f693764aa577f643899a050a9e345e02e1c47e6199ae247133edf328ea71edd3f9ae71bb8b4d5c5ba8d73cc7ba8595f3b7679e4fedc6 SHA512 (sos-audit-0.3-1.tgz) = 24c7bfec7e47a082ca1f2a96c5ad455c692d81dcc4339877de5bd324719609d91bc0ef6ddb95485fb75b81f90f8a7cc58370ada6f626c275bab36e9e2a409330