import CS git sos-4.11.2-4.el8_10
This commit is contained in:
parent
2dd39933dd
commit
215aaca98b
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,2 @@
|
||||
SOURCES/sos-4.11.0.tar.gz
|
||||
SOURCES/sos-4.11.2.tar.gz
|
||||
SOURCES/sos-audit-0.3-1.tgz
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
b95a041f0826234fcdc7ee452d31609972d5d556 SOURCES/sos-4.11.0.tar.gz
|
||||
d8d5e3e1eb124345417341ef9e9aa84f5cae609f SOURCES/sos-4.11.2.tar.gz
|
||||
00752b68ec5e1141192a9dab7d44377b8d637bf7 SOURCES/sos-audit-0.3-1.tgz
|
||||
|
||||
@ -23,22 +23,25 @@
|
||||
res.append(ls[0])
|
||||
except Exception as err:
|
||||
self.log_debug(f"Error parsing sos help: {err}")
|
||||
--- a/sos/report/plugins/mongodb.py
|
||||
+++ b/sos/report/plugins/mongodb.py
|
||||
@@ -87,9 +87,11 @@
|
||||
--- a/sos/report/plugins/mongodb.py 2026-07-02 09:06:03.860609746 +0200
|
||||
+++ b/sos/report/plugins/mongodb.py 2026-07-02 09:08:00.003595562 +0200
|
||||
@@ -87,10 +87,13 @@
|
||||
)
|
||||
|
||||
def setup(self):
|
||||
- if get_juju_info := self.path_exists('/var/lib/juju/db'):
|
||||
+ if self.path_exists('/var/lib/juju/db'):
|
||||
+ get_juju_info = self.path_exists('/var/lib/juju/db')
|
||||
+ get_juju_info = self.path_exists('/var/lib/juju/db')
|
||||
+ if get_juju_info:
|
||||
self.db_folder = "/var/lib/juju/db"
|
||||
- elif get_juju_info := self.path_exists('/var/snap/juju-db/curent/db'):
|
||||
+ elif self.path_exists('/var/snap/juju-db/curent/db'):
|
||||
+ get_juju_info = self.path_exists('/var/snap/juju-db/curent/db')
|
||||
self.db_folder = "/var/snap/juju-db/current/db"
|
||||
- self.db_folder = "/var/snap/juju-db/current/db"
|
||||
+ else:
|
||||
+ get_juju_info = self.path_exists('/var/snap/juju-db/current/db')
|
||||
+ if get_juju_info:
|
||||
+ self.db_folder = "/var/snap/juju-db/current/db"
|
||||
|
||||
super().setup()
|
||||
|
||||
--- 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 @@
|
||||
@ -51,43 +54,29 @@
|
||||
if isinstance(labels_option, str) and labels_option:
|
||||
self.labels.extend(labels_option.split(":"))
|
||||
|
||||
--- a/sos/cleaner/archives/__init__.py 2025-09-22 19:44:51.272619200 +0200
|
||||
+++ b/sos/cleaner/archives/__init__.py 2025-09-22 23:28:15.116001268 +0200
|
||||
@@ -118,6 +118,8 @@ class SoSObfuscationArchive():
|
||||
self.parsers = parsers # TODO: include this in __init__?
|
||||
|
||||
def load_parser_entries(self):
|
||||
+ self.soslog = logging.getLogger('sos')
|
||||
+ self.ui_log = logging.getLogger('sos_ui')
|
||||
for parser in self.parsers:
|
||||
parser.load_map_entries()
|
||||
|
||||
@@ -150,6 +152,7 @@ class SoSObfuscationArchive():
|
||||
return line, count
|
||||
|
||||
def obfuscate_arc_files(self, flist):
|
||||
+ self.load_parser_entries()
|
||||
for filename in flist:
|
||||
self.log_debug(f" pid={os.getpid()}: obfuscating {filename}")
|
||||
try:
|
||||
--- a/sos/cleaner/__init__.py 2025-09-22 19:44:51.272619200 +0200
|
||||
+++ b/sos/cleaner/__init__.py 2025-09-22 23:32:17.606745778 +0200
|
||||
@@ -720,10 +720,11 @@ third party.
|
||||
# based on files' sizes.
|
||||
|
||||
--- a/sos/cleaner/__init__.py
|
||||
+++ b/sos/cleaner/__init__.py
|
||||
@@ -40,6 +40,8 @@ from sos.utilities import (get_human_rea
|
||||
|
||||
# an auxiliary method to kick off child processes over its instances
|
||||
def _obfuscate_arc_files(arc, input_queue, output_queue):
|
||||
+ arc.soslog = logging.getLogger('sos')
|
||||
+ arc.ui_log = logging.getLogger('sos_ui')
|
||||
while True:
|
||||
try:
|
||||
file = input_queue.get()
|
||||
--- a/sos/cleaner/__init__.py 2026-07-01 13:45:34.298955340 +0200
|
||||
+++ b/sos/cleaner/__init__.py 2026-07-01 13:47:15.978445308 +0200
|
||||
@@ -795,6 +795,9 @@
|
||||
# sentinel mark. That triggers the child processes to report back
|
||||
# to output_queue some stats, and finish.
|
||||
files_obfuscated_count = total_sub_count = removed_file_count = 0
|
||||
+ # two nullification required before processes cloning
|
||||
+ archive.soslog = None
|
||||
+ archive.ui_log = None
|
||||
archive_list = [archive for i in range(self.opts.jobs)]
|
||||
- with ProcessPoolExecutor(
|
||||
- max_workers=self.opts.jobs,
|
||||
- initializer=archive.load_parser_entries) as executor:
|
||||
+ with ProcessPoolExecutor(max_workers=self.opts.jobs) as executor:
|
||||
futures = executor.map(obfuscate_arc_files, archive_list,
|
||||
[file_list[i::self.opts.jobs] for i in
|
||||
range(self.opts.jobs)])
|
||||
|
||||
input_queue = multiprocessing.Queue()
|
||||
output_queue = multiprocessing.Queue()
|
||||
|
||||
--- 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 @@
|
||||
@ -114,3 +103,65 @@
|
||||
else:
|
||||
confs += glob.glob(_ent)
|
||||
|
||||
--- a/sos/report/plugins/charmed_cruise_control.py 2026-07-16 13:00:22.269714807 +0200
|
||||
+++ b/sos/report/plugins/charmed_cruise_control.py 2026-07-16 13:01:56.710522628 +0200
|
||||
@@ -35,7 +35,8 @@
|
||||
) as f:
|
||||
content = f.read().strip()
|
||||
|
||||
- if match := re.match(r"balancer: (?P<pwd>\w+),ADMIN", content):
|
||||
+ match = re.match(r"balancer: (?P<pwd>\w+),ADMIN", content)
|
||||
+ if match:
|
||||
pwd = match.group("pwd")
|
||||
return f"-u balancer:{pwd}"
|
||||
|
||||
--- a/sos/report/plugins/__init__.py
|
||||
+++ b/sos/report/plugins/__init__.py
|
||||
@@ -3262,7 +3262,10 @@
|
||||
# skip forbidden paths; since we might recursivelly copied
|
||||
# whole directory, we must find the forbidden files in dest
|
||||
# path and delete the unwanted
|
||||
- base_dir = dest.removesuffix(f"{path.lstrip('/')}")
|
||||
+ _suffix = path.lstrip('/')
|
||||
+ base_dir = (dest[:-len(_suffix)]
|
||||
+ if dest.endswith(_suffix) and _suffix
|
||||
+ else dest)
|
||||
for relname in [file.relative_to(base_dir).as_posix()
|
||||
for file in Path(dest).rglob('*')]:
|
||||
absname = f"/{relname}"
|
||||
|
||||
--- a/sos/cleaner/__init__.py
|
||||
+++ b/sos/cleaner/__init__.py
|
||||
@@ -846,6 +846,8 @@
|
||||
# *all* mapping.all(item) methods - so replaying this will
|
||||
# generate the right datasets!
|
||||
archive.load_parser_entries()
|
||||
+ archive.soslog = logging.getLogger('sos')
|
||||
+ archive.ui_log = logging.getLogger('sos_ui')
|
||||
|
||||
try:
|
||||
self.obfuscate_directory_names(archive)
|
||||
|
||||
--- a/sos/report/plugins/charmed_mongodb.py 2026-07-16 14:48:09.639484635 +0200
|
||||
+++ b/sos/report/plugins/charmed_mongodb.py 2026-07-16 14:49:02.337015148 +0200
|
||||
@@ -122,8 +122,8 @@
|
||||
encoding="utf-8",
|
||||
) as f:
|
||||
data = yaml.safe_load(f)
|
||||
-
|
||||
- if sharding_conf := data.get("sharding", {}):
|
||||
+ sharding_conf = data.get("sharding", {})
|
||||
+ if sharding_conf:
|
||||
role = sharding_conf.get("clusterRole", "")
|
||||
|
||||
return self._match_role(role)
|
||||
@@ -144,7 +144,8 @@
|
||||
return None
|
||||
|
||||
data = yaml.safe_load(result.get("output", ""))
|
||||
- if sharding_conf := data.get("sharding", {}):
|
||||
+ sharding_conf = data.get("sharding", {})
|
||||
+ if sharding_conf:
|
||||
role = sharding_conf.get("clusterRole", "")
|
||||
return self._match_role(role)
|
||||
|
||||
|
||||
1436
SOURCES/0002-remove-unsupported-python36-plugins.patch
Normal file
1436
SOURCES/0002-remove-unsupported-python36-plugins.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,49 +0,0 @@
|
||||
--- a/sos/upload/targets/__init__.py 2025-09-16 19:57:27.294642506 +0200
|
||||
+++ b/sos/upload/targets/__init__.py 2025-09-16 19:59:44.498573843 +0200
|
||||
@@ -465,7 +465,7 @@
|
||||
self.upload_password or
|
||||
self._upload_password)
|
||||
|
||||
- def upload_sftp(self, user=None, password=None, user_dir=None):
|
||||
+ def upload_sftp(self, user=None, password=None):
|
||||
"""Attempts to upload the archive to an SFTP location.
|
||||
|
||||
Due to the lack of well maintained, secure, and generally widespread
|
||||
@@ -540,13 +540,10 @@
|
||||
raise Exception("Unable to connect via SFTP to "
|
||||
f"{self.get_upload_url_string()}")
|
||||
|
||||
- # certain implementations require file to be put in the user dir
|
||||
- put_cmd = (
|
||||
- f"put {self.upload_archive_name} "
|
||||
- f"{f'{user_dir}/' if user_dir else ''}"
|
||||
- f"{self._get_sftp_upload_name()}"
|
||||
- )
|
||||
+ put_cmd = (f'put {self.upload_archive_name} '
|
||||
+ f'{self._get_sftp_upload_name()}')
|
||||
ret.sendline(put_cmd)
|
||||
+
|
||||
put_expects = [
|
||||
'100%',
|
||||
pexpect.TIMEOUT,
|
||||
--- a/sos/upload/targets/redhat.py 2025-09-16 19:57:36.804628207 +0200
|
||||
+++ b/sos/upload/targets/redhat.py 2025-09-16 20:00:52.578728154 +0200
|
||||
@@ -145,7 +145,7 @@
|
||||
return fname
|
||||
|
||||
# pylint: disable=too-many-branches
|
||||
- def upload_sftp(self, user=None, password=None, user_dir=None):
|
||||
+ def upload_sftp(self, user=None, password=None):
|
||||
"""Override the base upload_sftp to allow for setting an on-demand
|
||||
generated anonymous login for the RH SFTP server if a username and
|
||||
password are not given
|
||||
@@ -217,8 +217,7 @@
|
||||
f"{anon.status_code}): {anon.json()}"
|
||||
)
|
||||
if _user and _token:
|
||||
- return super().upload_sftp(user=_user, password=_token,
|
||||
- user_dir=_user)
|
||||
+ return super().upload_sftp(user=_user, password=_token)
|
||||
raise Exception("Could not retrieve valid or anonymous credentials")
|
||||
|
||||
def check_file_too_big(self, archive):
|
||||
121
SOURCES/0004-revert-PR4092-and-PR4275.patch
Normal file
121
SOURCES/0004-revert-PR4092-and-PR4275.patch
Normal file
@ -0,0 +1,121 @@
|
||||
diff --git a/sos/upload/targets/__init__.py b/sos/upload/targets/__init__.py
|
||||
index 9e905e1063..6f72d963ea 100644
|
||||
--- a/sos/upload/targets/__init__.py
|
||||
+++ b/sos/upload/targets/__init__.py
|
||||
@@ -540,36 +540,7 @@ def upload_sftp(self, user=None, password=None, user_dir=None):
|
||||
raise Exception("Unable to connect via SFTP to "
|
||||
f"{self.get_upload_url_string()}")
|
||||
|
||||
- # user_dir indicates that we need to switch into a specific user
|
||||
- # directory. If ChRootDirectory is set, this happens automatically
|
||||
- # so check if the PWD contains the user. If it does, we are
|
||||
- # already in the user directory so set user_dir to None
|
||||
- if user_dir:
|
||||
- user_match = False
|
||||
- ret.sendline('pwd')
|
||||
- pwd_expects = [
|
||||
- 'sftp>',
|
||||
- 'Invalid command.',
|
||||
- pexpect.TIMEOUT,
|
||||
- pexpect.EOF
|
||||
- ]
|
||||
- pwd_cmd = ret.expect(pwd_expects, timeout=10) == 0
|
||||
- if pwd_cmd:
|
||||
- # Extract the path from child.before
|
||||
- raw_output = ret.before
|
||||
- user_match = re.search(user, raw_output)
|
||||
- else:
|
||||
- self.ui_log.warning("This server does not support the PWD "
|
||||
- "command - unable to verify user "
|
||||
- "directory. Attempting upload without "
|
||||
- "changing to user directory.")
|
||||
- user_dir = None
|
||||
-
|
||||
- if user_match:
|
||||
- user_dir = None
|
||||
-
|
||||
# certain implementations require file to be put in the user dir
|
||||
- # so we prepend the user directory to the file path
|
||||
put_cmd = (
|
||||
f"put {self.upload_archive_name} "
|
||||
f"{f'{user_dir}/' if user_dir else ''}"
|
||||
diff --git a/sos/upload/targets/redhat.py b/sos/upload/targets/redhat.py
|
||||
index 636a645fe6..0cfb80eecd 100644
|
||||
--- a/sos/upload/targets/redhat.py
|
||||
+++ b/sos/upload/targets/redhat.py
|
||||
@@ -158,7 +158,6 @@ def upload_sftp(self, user=None, password=None, user_dir=None):
|
||||
" for obtaining SFTP auth token.")
|
||||
_token = None
|
||||
_user = None
|
||||
- _user_dir = None
|
||||
|
||||
# We may have a device token already if we attempted
|
||||
# to upload via http but the upload failed. So
|
||||
@@ -192,7 +191,6 @@ def upload_sftp(self, user=None, password=None, user_dir=None):
|
||||
# credentials are valid
|
||||
_user = json.loads(ret.text)['username']
|
||||
_token = json.loads(ret.text)['token']
|
||||
- _user_dir = f"/users/{_user}"
|
||||
else:
|
||||
self.ui_log.debug(
|
||||
f"DEBUG: auth attempt failed (status: {ret.status_code}): "
|
||||
@@ -220,7 +218,7 @@ def upload_sftp(self, user=None, password=None, user_dir=None):
|
||||
)
|
||||
if _user and _token:
|
||||
return super().upload_sftp(user=_user, password=_token,
|
||||
- user_dir=_user_dir)
|
||||
+ user_dir=_user)
|
||||
raise Exception("Could not retrieve valid or anonymous credentials")
|
||||
|
||||
def check_file_too_big(self, archive):
|
||||
--
|
||||
2.47.0
|
||||
--- a/sos/upload/targets/__init__.py 2025-09-16 19:57:27.294642506 +0200
|
||||
+++ b/sos/upload/targets/__init__.py 2025-09-16 19:59:44.498573843 +0200
|
||||
@@ -465,7 +465,7 @@
|
||||
self.upload_password or
|
||||
self._upload_password)
|
||||
|
||||
- def upload_sftp(self, user=None, password=None, user_dir=None):
|
||||
+ def upload_sftp(self, user=None, password=None):
|
||||
"""Attempts to upload the archive to an SFTP location.
|
||||
|
||||
Due to the lack of well maintained, secure, and generally widespread
|
||||
@@ -540,13 +540,10 @@
|
||||
raise Exception("Unable to connect via SFTP to "
|
||||
f"{self.get_upload_url_string()}")
|
||||
|
||||
- # certain implementations require file to be put in the user dir
|
||||
- put_cmd = (
|
||||
- f"put {self.upload_archive_name} "
|
||||
- f"{f'{user_dir}/' if user_dir else ''}"
|
||||
- f"{self._get_sftp_upload_name()}"
|
||||
- )
|
||||
+ put_cmd = (f'put {self.upload_archive_name} '
|
||||
+ f'{self._get_sftp_upload_name()}')
|
||||
ret.sendline(put_cmd)
|
||||
+
|
||||
put_expects = [
|
||||
'100%',
|
||||
pexpect.TIMEOUT,
|
||||
--- a/sos/upload/targets/redhat.py 2025-09-16 19:57:36.804628207 +0200
|
||||
+++ b/sos/upload/targets/redhat.py 2025-09-16 20:00:52.578728154 +0200
|
||||
@@ -145,7 +145,7 @@
|
||||
return fname
|
||||
|
||||
# pylint: disable=too-many-branches
|
||||
- def upload_sftp(self, user=None, password=None, user_dir=None):
|
||||
+ def upload_sftp(self, user=None, password=None):
|
||||
"""Override the base upload_sftp to allow for setting an on-demand
|
||||
generated anonymous login for the RH SFTP server if a username and
|
||||
password are not given
|
||||
@@ -217,8 +217,7 @@
|
||||
f"{anon.status_code}): {anon.json()}"
|
||||
)
|
||||
if _user and _token:
|
||||
- return super().upload_sftp(user=_user, password=_token,
|
||||
- user_dir=_user)
|
||||
+ return super().upload_sftp(user=_user, password=_token)
|
||||
raise Exception("Could not retrieve valid or anonymous credentials")
|
||||
|
||||
def check_file_too_big(self, archive):
|
||||
@ -0,0 +1,37 @@
|
||||
From 2fab657e3909f76e31bc6c56a5ad26f86a9925e5 Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Moravec <pmoravec@redhat.com>
|
||||
Date: Tue, 23 Jun 2026 17:17:01 +0200
|
||||
Subject: [PATCH] [foreman-installer] Scrub secrets in CLI arg dumps
|
||||
|
||||
Installer logs dump CLI args we need to scrub.
|
||||
|
||||
Closes: #4367
|
||||
|
||||
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
|
||||
---
|
||||
sos/report/plugins/foreman_installer.py | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/sos/report/plugins/foreman_installer.py b/sos/report/plugins/foreman_installer.py
|
||||
index f55cde23..89eef2e4 100644
|
||||
--- a/sos/report/plugins/foreman_installer.py
|
||||
+++ b/sos/report/plugins/foreman_installer.py
|
||||
@@ -54,11 +54,12 @@ class ForemanInstaller(Plugin, DebianPlugin, UbuntuPlugin):
|
||||
r"::(.*(token|secret|key|passw).*)\") value:) "
|
||||
r"(.*)")
|
||||
self.do_path_regex_sub(install_logs, logs_debug_reg, r"\1 \2 ********")
|
||||
- # also hide passwords in yet different formats
|
||||
+ # also hide passwords in yet different formats, including CLI arg dumps
|
||||
self.do_path_regex_sub(
|
||||
install_logs,
|
||||
- r"password(\", \"|=|\" value: \"|\": \")(.*?)(\", \".*|\"]]|\"|$)",
|
||||
- r"password\1********\3")
|
||||
+ r"((?:password|consumer-key|consumer-secret|key-secret|secret-key|"
|
||||
+ r"oauth-key|oauth-secret)(?:\", \"|\": \"|=))([^\"\n]*)(\"|$)",
|
||||
+ r"\1********\3")
|
||||
self.do_path_regex_sub(
|
||||
"/var/log/foreman-installer/foreman-proxy*",
|
||||
r"(\s*proxy_password\s=) (.*)",
|
||||
--
|
||||
2.54.0
|
||||
|
||||
97
SOURCES/0006-foremanctl-valkey-PR4376.patch
Normal file
97
SOURCES/0006-foremanctl-valkey-PR4376.patch
Normal file
@ -0,0 +1,97 @@
|
||||
From 5e7a01d9df2bc4e1f2659ace959ea52228ee1eee Mon Sep 17 00:00:00 2001
|
||||
From: akumari <akumari@redhat.com>
|
||||
Date: Wed, 1 Jul 2026 09:26:52 +0530
|
||||
Subject: [PATCH 1/2] [foremanctl] Enable plugin for containerized deployments
|
||||
|
||||
The plugin required foremanctl package which doesn't exist in
|
||||
containerized mode. Add container detection to enable the plugin
|
||||
and collect foremanctl health diagnostics for support cases.
|
||||
|
||||
Signed-off-by: akumari <akumari@redhat.com>
|
||||
---
|
||||
sos/report/plugins/foremanctl.py | 29 +++++++++++++++++++++++++----
|
||||
1 file changed, 25 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/sos/report/plugins/foremanctl.py b/sos/report/plugins/foremanctl.py
|
||||
index 1b6ba4a4..0425cc05 100644
|
||||
--- a/sos/report/plugins/foremanctl.py
|
||||
+++ b/sos/report/plugins/foremanctl.py
|
||||
@@ -19,6 +19,7 @@ class Foremanctl(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin):
|
||||
plugin_name = 'foremanctl'
|
||||
profiles = ('sysmgmt',)
|
||||
packages = ('foremanctl', )
|
||||
+ containers = ('foreman', 'foreman-proxy',)
|
||||
|
||||
def setup(self):
|
||||
self.add_copy_spec([
|
||||
@@ -29,14 +30,34 @@ class Foremanctl(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin):
|
||||
|
||||
self.add_cmd_output([
|
||||
"foremanctl features",
|
||||
+ "foremanctl health",
|
||||
])
|
||||
|
||||
self.add_dir_listing(["/var/lib/foremanctl/"], recursive=True)
|
||||
|
||||
def postproc(self):
|
||||
- self.do_path_regex_sub("/var/lib/foremanctl/parameters.yaml",
|
||||
- r"(foreman_initial_admin_password:\s*)(.*)",
|
||||
- r"\1********")
|
||||
-
|
||||
+ # Scrub passwords, credentials, tokens, secrets, and keys
|
||||
+ self.do_path_regex_sub(
|
||||
+ "/var/lib/foremanctl/parameters.yaml",
|
||||
+ r"((.*)?(passw|cred|token|secret|key).*(\:\s|=))(.*)",
|
||||
+ r"\1********")
|
||||
+
|
||||
+ # Scrub passwords from foremanctl logs - Pattern 1: key=value format
|
||||
+ self.do_path_regex_sub(
|
||||
+ "/var/log/foremanctl/foremanctl.*log*",
|
||||
+ r"((passw|cred|token|secret|key)\w*\s*=\s*)(.*?)(\s|,|\"|'|$)",
|
||||
+ r"\1********\4")
|
||||
+
|
||||
+ # Scrub passwords from foremanctl logs - Pattern 2: "password something" format
|
||||
+ self.do_path_regex_sub(
|
||||
+ "/var/log/foremanctl/foremanctl.*log*",
|
||||
+ r"(password\s+)(.*?)(\s|,|\"|$)",
|
||||
+ r"\1********\3")
|
||||
+
|
||||
+ # Scrub admin credentials in username:password format
|
||||
+ self.do_path_regex_sub(
|
||||
+ "/var/log/foremanctl/foremanctl.*log*",
|
||||
+ r"(Admin credentials:\s+\w+:)(.*?)(\"|,|$)",
|
||||
+ r"\1********\3")
|
||||
|
||||
# vim: set et ts=4 sw=4 :
|
||||
--
|
||||
2.54.0
|
||||
|
||||
From 3b6bbcb819e05aecf0fec4767588ea0376c9f218 Mon Sep 17 00:00:00 2001
|
||||
From: akumari <akumari@redhat.com>
|
||||
Date: Tue, 7 Jul 2026 14:06:40 +0530
|
||||
Subject: [PATCH 2/2] [valkey] Add container support for containerized
|
||||
deployments
|
||||
|
||||
Adds container support to the valkey plugin to enable it
|
||||
for containerized deployments using foremanctl/quadlet.
|
||||
|
||||
Signed-off-by: akumari <akumari@redhat.com>
|
||||
---
|
||||
sos/report/plugins/valkey.py | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/sos/report/plugins/valkey.py b/sos/report/plugins/valkey.py
|
||||
index 26a74a56..f7b49253 100644
|
||||
--- a/sos/report/plugins/valkey.py
|
||||
+++ b/sos/report/plugins/valkey.py
|
||||
@@ -19,6 +19,7 @@ class Valkey(Plugin, IndependentPlugin):
|
||||
profiles = ('services',)
|
||||
|
||||
packages = ('valkey',)
|
||||
+ containers = ('valkey',)
|
||||
|
||||
var_puppet_gen = "/var/lib/config-data/puppet-generated/valkey"
|
||||
|
||||
--
|
||||
2.54.0
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
From 6085b2580173a7a43de8b541584c82481c617aa2 Mon Sep 17 00:00:00 2001
|
||||
From: asadawar <asadawar@users.noreply.github.com>
|
||||
Date: Mon, 27 Jul 2026 17:50:42 +0530
|
||||
Subject: [PATCH] [policies] Prefer most specific policy when multiple match
|
||||
|
||||
When multiple policies within the same module return True from
|
||||
check(), the policy loader now selects the most specific one
|
||||
(deepest in the class hierarchy) instead of whichever happens
|
||||
to sort first alphabetically.
|
||||
|
||||
Previously, import_policy() returned classes sorted by name via
|
||||
inspect.getmembers(), and load() picked the first match. This
|
||||
caused RHELPolicy to always win over RedHatCoreOSPolicy inside
|
||||
a toolbox container on RHCOS, because uppercase 'H' sorts before
|
||||
lowercase 'e' in ASCII. Both policies return True in that context
|
||||
(RHEL for the container's /etc/redhat-release, RHCOS for the
|
||||
host's /host/etc/os-release), but the more specific RHCOS policy
|
||||
was never reached.
|
||||
|
||||
This has existed since RedHatCoreOSPolicy was introduced in 2019
|
||||
(commit fa06bc09c95c) but was never visible because RHCOS had no
|
||||
behavioral differences from RHEL until the archive naming change
|
||||
in commit 0e919b6.
|
||||
|
||||
The fix collects all matching policies from a module and sorts by
|
||||
MRO depth (descending), so a subclass is always preferred over
|
||||
its parent. This is safe because a subclass that returns True from
|
||||
check() is by definition a more precise match than its parent.
|
||||
|
||||
Assisted-by: Claude Code <https://claude.ai/code>
|
||||
Signed-off-by: asadawar <asadawar@users.noreply.github.com>
|
||||
---
|
||||
sos/policies/__init__.py | 18 +++++++++++-------
|
||||
1 file changed, 11 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/sos/policies/__init__.py b/sos/policies/__init__.py
|
||||
index 35b3a532..b4920e82 100644
|
||||
--- a/sos/policies/__init__.py
|
||||
+++ b/sos/policies/__init__.py
|
||||
@@ -29,20 +29,24 @@ def import_policy(name):
|
||||
return None
|
||||
|
||||
|
||||
-def load(cache={}, sysroot=None, init=None, probe_runtime=True,
|
||||
+def load(cache=None, sysroot=None, init=None, probe_runtime=True,
|
||||
remote_exec=None, remote_check=''):
|
||||
+ if cache is None:
|
||||
+ cache = {}
|
||||
if 'policy' in cache:
|
||||
return cache.get('policy')
|
||||
|
||||
import sos.policies.distros
|
||||
helper = ImporterHelper(sos.policies.distros)
|
||||
+ matches = []
|
||||
for module in helper.get_modules():
|
||||
- for policy in import_policy(module):
|
||||
- if policy.check(remote=remote_check):
|
||||
- cache['policy'] = policy(sysroot=sysroot, init=init,
|
||||
- probe_runtime=probe_runtime,
|
||||
- remote_exec=remote_exec)
|
||||
- break
|
||||
+ matches.extend([policy for policy in (import_policy(module) or [])
|
||||
+ if policy.check(remote=remote_check)])
|
||||
+ if matches:
|
||||
+ matches.sort(key=lambda p: len(p.__mro__), reverse=True)
|
||||
+ cache['policy'] = matches[0](sysroot=sysroot, init=init,
|
||||
+ probe_runtime=probe_runtime,
|
||||
+ remote_exec=remote_exec)
|
||||
|
||||
if sys.platform != 'linux':
|
||||
raise Exception("SoS is not supported on this platform")
|
||||
--
|
||||
2.55.0
|
||||
|
||||
@ -0,0 +1,90 @@
|
||||
From d94095e55d69d5e4135df0193c9726c2789526ab Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Moravec <pmoravec@redhat.com>
|
||||
Date: Wed, 29 Jul 2026 10:46:25 +0200
|
||||
Subject: [PATCH] [processor] Limit /sys/devices/system/cpu/cpu* subdirs
|
||||
collected
|
||||
|
||||
For systems with >500 CPUs, collecting all such directories means
|
||||
millions of files to be collected, what excessivelly slows down the
|
||||
plugin until its timeout.
|
||||
|
||||
Limit the default number of such directories to 64, configurable via a
|
||||
plugin option.
|
||||
|
||||
Resolves: #4399
|
||||
|
||||
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
|
||||
---
|
||||
sos/report/plugins/processor.py | 41 ++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 40 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/sos/report/plugins/processor.py b/sos/report/plugins/processor.py
|
||||
index 9375b5a1..593bd36b 100644
|
||||
--- a/sos/report/plugins/processor.py
|
||||
+++ b/sos/report/plugins/processor.py
|
||||
@@ -6,7 +6,9 @@
|
||||
#
|
||||
# See the LICENSE file in the source distribution for further information.
|
||||
|
||||
-from sos.report.plugins import Plugin, IndependentPlugin, SoSPredicate
|
||||
+import re
|
||||
+from sos.report.plugins import (Plugin, IndependentPlugin, SoSPredicate,
|
||||
+ PluginOpt)
|
||||
from sos.policies.distros.ubuntu import UbuntuPolicy
|
||||
|
||||
|
||||
@@ -18,6 +20,11 @@ class Processor(Plugin, IndependentPlugin):
|
||||
profiles = ('system', 'hardware', 'memory')
|
||||
files = ('/proc/cpuinfo',)
|
||||
packages = ('cpufreq-utils', 'cpuid')
|
||||
+ option_list = [
|
||||
+ PluginOpt('max_cpu_dirs', default=64, val_type=int,
|
||||
+ desc='Maximum number of cpu[0-9]+ directories '
|
||||
+ 'to collect from /sys/devices/system/cpu'),
|
||||
+ ]
|
||||
|
||||
cpu_kmods = []
|
||||
|
||||
@@ -43,7 +50,39 @@ class Processor(Plugin, IndependentPlugin):
|
||||
# copy /sys/devices/system/cpu/cpuX with separately applied sizelimit
|
||||
# this is required for systems with tens/hundreds of CPUs where the
|
||||
# cumulative directory size exceeds 25MB or even 100MB.
|
||||
+ # Limit cpu[0-9]* directories to avoid excessive collection.
|
||||
+ # All non-cpu* directories are always collected.
|
||||
+ max_cpu_dirs = self.get_option('max_cpu_dirs')
|
||||
+ if max_cpu_dirs < 0:
|
||||
+ self._log_info(f"Invalid max_cpu_dirs={max_cpu_dirs} value "
|
||||
+ f"provided, replacing by 0."
|
||||
+ )
|
||||
+ max_cpu_dirs = 0
|
||||
cdirs = self.listdir('/sys/devices/system/cpu')
|
||||
+
|
||||
+ if len(cdirs) > max_cpu_dirs:
|
||||
+ # separate cpu from non-cpu, then limit cpu dirs
|
||||
+ cpu_pattern = re.compile(r'cpu(\d+)')
|
||||
+ cpu_dirs = []
|
||||
+ other_dirs = []
|
||||
+
|
||||
+ for cdir in cdirs:
|
||||
+ if cpu_pattern.fullmatch(cdir):
|
||||
+ cpu_dirs.append(cdir)
|
||||
+ else:
|
||||
+ other_dirs.append(cdir)
|
||||
+
|
||||
+ # Only limit if cpu_dirs specifically exceeds max
|
||||
+ if len(cpu_dirs) > max_cpu_dirs:
|
||||
+ self._log_info(
|
||||
+ f"Limiting cpu directories from {len(cpu_dirs)} to "
|
||||
+ f"{max_cpu_dirs} (use '-k processor.max_cpu_dirs=N' "
|
||||
+ f"to change)."
|
||||
+ )
|
||||
+ cpu_dirs = sorted(cpu_dirs)[:max_cpu_dirs]
|
||||
+
|
||||
+ cdirs = other_dirs + cpu_dirs
|
||||
+
|
||||
self.add_copy_spec([
|
||||
self.path_join('/sys/devices/system/cpu', cdir) for cdir in cdirs
|
||||
])
|
||||
--
|
||||
2.55.0
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
|
||||
Summary: A set of tools to gather troubleshooting information from a system
|
||||
Name: sos
|
||||
Version: 4.11.0
|
||||
Release: 1%{?dist}
|
||||
Version: 4.11.2
|
||||
Release: 4%{?dist}
|
||||
Group: Applications/System
|
||||
Source0: https://github.com/sosreport/sos/archive/%{version}/sos-%{version}.tar.gz
|
||||
Source1: sos-audit-%{auditversion}.tgz
|
||||
@ -23,8 +23,13 @@ Recommends: python3-pyyaml
|
||||
Conflicts: vdsm < 4.40
|
||||
Obsoletes: sos-collector
|
||||
Patch1: 0001-python3-walrus-operator-and-rhel8-changes-only.patch
|
||||
Patch2: 0002-sosreport-binary.patch
|
||||
Patch3: 0003-revert-PR4092.patch
|
||||
Patch2: 0002-remove-unsupported-python36-plugins.patch
|
||||
Patch3: 0003-sosreport-binary.patch
|
||||
Patch4: 0004-revert-PR4092-and-PR4275.patch
|
||||
Patch5: 0005-foreman-installer-Scrub-secrets-in-CLI-arg-dumps.patch
|
||||
Patch6: 0006-foremanctl-valkey-PR4376.patch
|
||||
Patch7: 0007-policies-Prefer-most-specific-policy-when-multiple-m.patch
|
||||
Patch8: 0008-processor-Limit-sys-devices-system-cpu-cpu-subdirs-c.patch
|
||||
|
||||
%description
|
||||
Sos is a set of tools that gathers information about system
|
||||
@ -38,6 +43,11 @@ 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
|
||||
%patch -P 7 -p1
|
||||
%patch -P 8 -p1
|
||||
|
||||
%build
|
||||
%py3_build
|
||||
@ -110,6 +120,15 @@ of the system. Currently storage and filesystem commands are audited.
|
||||
%license LICENSE
|
||||
|
||||
%changelog
|
||||
* Wed Aug 05 2026 Jan Jansky <jjansky@redhat.com> = 4.11.2-4
|
||||
- Update to 4.11.2-4
|
||||
|
||||
* Fri Jul 17 2026 Jan Jansky <jjansky@redhat.com> = 4.11.2-2
|
||||
- Update to 4.11.2-2
|
||||
|
||||
* Wed Jul 15 2026 Jan Jansky <jjansky@redhat.com> = 4.11.2-1
|
||||
- Update to 4.11.2-1
|
||||
|
||||
* Thu Apr 02 2026 Jan Jansky <jjansky@redhat.com> = 4.11.0-1
|
||||
- Update to 4.11.0-1
|
||||
Resolves: RHEL-157813
|
||||
|
||||
Loading…
Reference in New Issue
Block a user