import sos-4.2-2.el8

This commit is contained in:
CentOS Sources 2021-11-04 16:22:20 +00:00 committed by Stepan Oksanichenko
parent 6b2dbf3bec
commit fae7e7e456
35 changed files with 1101 additions and 4604 deletions

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
SOURCES/sos-4.1.tar.gz
SOURCES/sos-4.2.tar.gz
SOURCES/sos-audit-0.3.tgz

View File

@ -1,2 +1,2 @@
7d4d03af232e2357e3359ad564a59f4c3654eac0 SOURCES/sos-4.1.tar.gz
fe82967b0577076aac104412a9fe35cdb444bde4 SOURCES/sos-4.2.tar.gz
9d478b9f0085da9178af103078bbf2fd77b0175a SOURCES/sos-audit-0.3.tgz

View File

@ -1,387 +0,0 @@
From 94b9b90c818eb18f0ca8d78fe063dc5b0677c885 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Tue, 22 Jun 2021 12:58:03 +0200
Subject: [PATCH] [rhui] add plugin to RHUI
Add a new/revoked plugin for RHUI (newly based on python3 and pulp-3).
Edditionally, collect /etc/pki/pulp certificates except for RSA keys.
Resolves: #2590
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/plugins/pulpcore.py | 7 ++++-
sos/report/plugins/rhui.py | 49 ++++++++++++++++++++++++++++++++++
2 files changed, 55 insertions(+), 1 deletion(-)
create mode 100644 sos/report/plugins/rhui.py
diff --git a/sos/report/plugins/pulpcore.py b/sos/report/plugins/pulpcore.py
index ccaac3185..77ceacb92 100644
--- a/sos/report/plugins/pulpcore.py
+++ b/sos/report/plugins/pulpcore.py
@@ -77,7 +77,12 @@ def separate_value(line, sep=':'):
def setup(self):
self.parse_settings_config()
- self.add_copy_spec("/etc/pulp/settings.py")
+ self.add_copy_spec([
+ "/etc/pulp/settings.py",
+ "/etc/pki/pulp/*"
+ ])
+ # skip collecting certificate keys
+ self.add_forbidden_path("/etc/pki/pulp/*.key")
self.add_cmd_output("rq info -u redis://localhost:6379/8",
env={"LC_ALL": "en_US.UTF-8"},
diff --git a/sos/report/plugins/rhui.py b/sos/report/plugins/rhui.py
new file mode 100644
index 000000000..7acd3f49e
--- /dev/null
+++ b/sos/report/plugins/rhui.py
@@ -0,0 +1,49 @@
+# Copyright (C) 2021 Red Hat, Inc., Pavel Moravec <pmoravec@redhat.com>
+
+# This file is part of the sos project: https://github.com/sosreport/sos
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# version 2 of the GNU General Public License.
+#
+# See the LICENSE file in the source distribution for further information.
+
+from sos.report.plugins import Plugin, RedHatPlugin
+
+
+class Rhui(Plugin, RedHatPlugin):
+
+ short_desc = 'Red Hat Update Infrastructure'
+
+ plugin_name = "rhui"
+ commands = ("rhui-manager",)
+ files = ("/etc/ansible/facts.d/rhui_auth.fact", "/usr/lib/rhui/cds.py")
+
+ def setup(self):
+ self.add_copy_spec([
+ "/etc/rhui/rhui-tools.conf",
+ "/etc/rhui/registered_subscriptions.conf",
+ "/etc/pki/rhui/*",
+ "/var/log/rhui-subscription-sync.log",
+ "/var/cache/rhui/*",
+ "/root/.rhui/*",
+ ])
+ # skip collecting certificate keys
+ self.add_forbidden_path("/etc/pki/rhui/*.key")
+
+ self.add_cmd_output([
+ "rhui-manager status",
+ "rhui-manager cert info",
+ "ls -lR /var/lib/rhui/remote_share",
+ ])
+
+ def postproc(self):
+ # obfuscate admin_pw and secret_key values
+ for prop in ["admin_pw", "secret_key"]:
+ self.do_path_regex_sub(
+ "/etc/ansible/facts.d/rhui_auth.fact",
+ r"(%s\s*=\s*)(.*)" % prop,
+ r"\1********")
+
+
+# vim: set et ts=4 sw=4 :
From bd15dc764c9d4554d8e8f08163228d65ca099985 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Thu, 24 Jun 2021 17:53:27 +0200
Subject: [PATCH 1/4] [plugins] Allow add_forbidden_path to apply glob
recursively
Add option to apply glob.glob to forbidden path recursively.
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/plugins/__init__.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/sos/report/plugins/__init__.py b/sos/report/plugins/__init__.py
index 06923300..6fd1a3b2 100644
--- a/sos/report/plugins/__init__.py
+++ b/sos/report/plugins/__init__.py
@@ -1187,12 +1187,14 @@ class Plugin(object):
'symlink': "no"
})
- def add_forbidden_path(self, forbidden):
+ def add_forbidden_path(self, forbidden, recursive=False):
"""Specify a path, or list of paths, to not copy, even if it's part of
an ``add_copy_spec()`` call
:param forbidden: A filepath to forbid collection from
:type forbidden: ``str`` or a ``list`` of strings
+
+ :param recursive: Should forbidden glob be applied recursively
"""
if isinstance(forbidden, str):
forbidden = [forbidden]
@@ -1202,7 +1204,7 @@ class Plugin(object):
for forbid in forbidden:
self._log_info("adding forbidden path '%s'" % forbid)
- for path in glob.glob(forbid):
+ for path in glob.glob(forbid, recursive=recursive):
self.forbidden_paths.append(path)
def get_all_options(self):
--
2.31.1
From b695201baeb629a6543445d98dbb04f357670621 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Thu, 24 Jun 2021 17:57:48 +0200
Subject: [PATCH 2/4] [pulpcore] improve settings.py parsing
- deal with /etc/pulp/settings.py as a one-line string
- parse dbname from it as well
- dont collect any *.key file from whole /etc/pki/pulp dir
Related: #2593
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/plugins/pulpcore.py | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/sos/report/plugins/pulpcore.py b/sos/report/plugins/pulpcore.py
index 77ceacb9..be526035 100644
--- a/sos/report/plugins/pulpcore.py
+++ b/sos/report/plugins/pulpcore.py
@@ -28,9 +28,10 @@ class PulpCore(Plugin, IndependentPlugin):
databases_scope = False
self.dbhost = "localhost"
self.dbport = 5432
+ self.dbname = "pulpcore"
self.dbpasswd = ""
# TODO: read also redis config (we dont expect much customisations)
- # TODO: read also db user (pulp) and database name (pulpcore)
+ # TODO: read also db user (pulp)
self.staticroot = "/var/lib/pulp/assets"
self.uploaddir = "/var/lib/pulp/media/upload"
@@ -44,7 +45,10 @@ class PulpCore(Plugin, IndependentPlugin):
return val
try:
- for line in open("/etc/pulp/settings.py").read().splitlines():
+ # split the lines to "one option per line" format
+ for line in open("/etc/pulp/settings.py").read() \
+ .replace(',', ',\n').replace('{', '{\n') \
+ .replace('}', '\n}').splitlines():
# skip empty lines and lines with comments
if not line or line[0] == '#':
continue
@@ -53,11 +57,14 @@ class PulpCore(Plugin, IndependentPlugin):
continue
# example HOST line to parse:
# 'HOST': 'localhost',
- if databases_scope and match(r"\s+'HOST'\s*:\s+\S+", line):
+ pattern = r"\s*['|\"]%s['|\"]\s*:\s*\S+"
+ if databases_scope and match(pattern % 'HOST', line):
self.dbhost = separate_value(line)
- if databases_scope and match(r"\s+'PORT'\s*:\s+\S+", line):
+ if databases_scope and match(pattern % 'PORT', line):
self.dbport = separate_value(line)
- if databases_scope and match(r"\s+'PASSWORD'\s*:\s+\S+", line):
+ if databases_scope and match(pattern % 'NAME', line):
+ self.dbname = separate_value(line)
+ if databases_scope and match(pattern % 'PASSWORD', line):
self.dbpasswd = separate_value(line)
# if line contains closing '}' database_scope end
if databases_scope and '}' in line:
@@ -82,7 +89,7 @@ class PulpCore(Plugin, IndependentPlugin):
"/etc/pki/pulp/*"
])
# skip collecting certificate keys
- self.add_forbidden_path("/etc/pki/pulp/*.key")
+ self.add_forbidden_path("/etc/pki/pulp/**/*.key", recursive=True)
self.add_cmd_output("rq info -u redis://localhost:6379/8",
env={"LC_ALL": "en_US.UTF-8"},
@@ -104,8 +111,8 @@ class PulpCore(Plugin, IndependentPlugin):
_query = "select * from %s where pulp_last_updated > NOW() - " \
"interval '%s days' order by pulp_last_updated" % \
(table, task_days)
- _cmd = "psql -h %s -p %s -U pulp -d pulpcore -c %s" % \
- (self.dbhost, self.dbport, quote(_query))
+ _cmd = "psql -h %s -p %s -U pulp -d %s -c %s" % \
+ (self.dbhost, self.dbport, self.dbname, quote(_query))
self.add_cmd_output(_cmd, env=self.env, suggest_filename=table)
def postproc(self):
--
2.31.1
From 0286034da44bce43ab368dfc6815da7d74d60719 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Thu, 24 Jun 2021 17:59:36 +0200
Subject: [PATCH 3/4] [rhui] call rhui-* commands with proper env and timeout
rhui-manager commands timeout when not being logged in, which
should be reacted by adding proper cmd timeout.
Adding the env.variable ensures potentially unaswered "RHUI Username:"
is also printed/colected.
Further, prevent collecting any *.key file from the whole /etc/pki/rhui
dir.
Related: #2593
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/plugins/rhui.py | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/sos/report/plugins/rhui.py b/sos/report/plugins/rhui.py
index 7acd3f49..5a152427 100644
--- a/sos/report/plugins/rhui.py
+++ b/sos/report/plugins/rhui.py
@@ -29,13 +29,16 @@ class Rhui(Plugin, RedHatPlugin):
"/root/.rhui/*",
])
# skip collecting certificate keys
- self.add_forbidden_path("/etc/pki/rhui/*.key")
+ self.add_forbidden_path("/etc/pki/rhui/**/*.key", recursive=True)
+ # call rhui-manager commands with 1m timeout and
+ # with an env. variable ensuring that "RHUI Username:"
+ # even unanswered prompt gets collected
self.add_cmd_output([
"rhui-manager status",
"rhui-manager cert info",
"ls -lR /var/lib/rhui/remote_share",
- ])
+ ], timeout=60, env={'PYTHONUNBUFFERED': '1'})
def postproc(self):
# obfuscate admin_pw and secret_key values
--
2.31.1
From a656bd239ab86dfd8973f733ae2c0fbd0c57d416 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Thu, 24 Jun 2021 18:01:14 +0200
Subject: [PATCH 4/4] [rhui] fix broken obfuscation
- /etc/ansible/facts.d/rhui_*.fact must be collected by
rhui plugin to let some file to be obfuscated there
- obfuscate also cookies values that can grant login access
Resolves: #2593
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/plugins/ansible.py | 3 +++
sos/report/plugins/rhui.py | 7 +++++++
2 files changed, 10 insertions(+)
diff --git a/sos/report/plugins/ansible.py b/sos/report/plugins/ansible.py
index 3e5d3d37..5991b786 100644
--- a/sos/report/plugins/ansible.py
+++ b/sos/report/plugins/ansible.py
@@ -29,4 +29,7 @@ class Ansible(Plugin, RedHatPlugin, UbuntuPlugin):
"ansible --version"
])
+ # let rhui plugin collects the RHUI specific files
+ self.add_forbidden_path("/etc/ansible/facts.d/rhui_*.fact")
+
# vim: set et ts=4 sw=4 :
diff --git a/sos/report/plugins/rhui.py b/sos/report/plugins/rhui.py
index 5a152427..1d479f85 100644
--- a/sos/report/plugins/rhui.py
+++ b/sos/report/plugins/rhui.py
@@ -27,6 +27,7 @@ class Rhui(Plugin, RedHatPlugin):
"/var/log/rhui-subscription-sync.log",
"/var/cache/rhui/*",
"/root/.rhui/*",
+ "/etc/ansible/facts.d/rhui_*.fact",
])
# skip collecting certificate keys
self.add_forbidden_path("/etc/pki/rhui/**/*.key", recursive=True)
@@ -47,6 +48,12 @@ class Rhui(Plugin, RedHatPlugin):
"/etc/ansible/facts.d/rhui_auth.fact",
r"(%s\s*=\s*)(.*)" % prop,
r"\1********")
+ # obfuscate twoo cookies for login session
+ for cookie in ["csrftoken", "sessionid"]:
+ self.do_path_regex_sub(
+ r"/root/\.rhui/.*/cookies.txt",
+ r"(%s\s+)(\S+)" % cookie,
+ r"\1********")
# vim: set et ts=4 sw=4 :
--
2.31.1
From 4e5bebffca9936bcdf4d38aad9989970a15dd72b Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Tue, 3 Aug 2021 21:54:33 +0200
Subject: [PATCH] [rhui] Update the plugin on several places
- obfuscate "rhui_manager_password: xxx" in /root/.rhui/answers.yaml*
- no need to collect or obfuscate anything from /etc/ansible/facts.d
- newly detect the plugin via /etc/rhui/rhui-tools.conf file or rhui-manager
command (only)
Resolves: #2637
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/plugins/rhui.py | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/sos/report/plugins/rhui.py b/sos/report/plugins/rhui.py
index 1d479f85..52065fb4 100644
--- a/sos/report/plugins/rhui.py
+++ b/sos/report/plugins/rhui.py
@@ -16,8 +16,8 @@ class Rhui(Plugin, RedHatPlugin):
short_desc = 'Red Hat Update Infrastructure'
plugin_name = "rhui"
- commands = ("rhui-manager",)
- files = ("/etc/ansible/facts.d/rhui_auth.fact", "/usr/lib/rhui/cds.py")
+ commands = ("rhui-manager", )
+ files = ("/etc/rhui/rhui-tools.conf", )
def setup(self):
self.add_copy_spec([
@@ -27,7 +27,6 @@ class Rhui(Plugin, RedHatPlugin):
"/var/log/rhui-subscription-sync.log",
"/var/cache/rhui/*",
"/root/.rhui/*",
- "/etc/ansible/facts.d/rhui_*.fact",
])
# skip collecting certificate keys
self.add_forbidden_path("/etc/pki/rhui/**/*.key", recursive=True)
@@ -42,11 +41,10 @@ class Rhui(Plugin, RedHatPlugin):
], timeout=60, env={'PYTHONUNBUFFERED': '1'})
def postproc(self):
- # obfuscate admin_pw and secret_key values
- for prop in ["admin_pw", "secret_key"]:
- self.do_path_regex_sub(
- "/etc/ansible/facts.d/rhui_auth.fact",
- r"(%s\s*=\s*)(.*)" % prop,
+ # hide rhui_manager_password value in (also rotated) answers file
+ self.do_path_regex_sub(
+ r"/root/\.rhui/answers.yaml.*",
+ r"(\s*rhui_manager_password\s*:)\s*(\S+)",
r"\1********")
# obfuscate twoo cookies for login session
for cookie in ["csrftoken", "sessionid"]:
--
2.31.1

View File

@ -0,0 +1,257 @@
From 5b245b1e449c6a05d09034bcb8290bffded79327 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Wed, 8 Sep 2021 17:04:58 +0200
Subject: [PATCH] [report] Implement --estimate-only
Add report option --estimate-only to estimate disk space requirements
when running a sos report.
Resolves: #2673
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
man/en/sos-report.1 | 13 +++++++-
sos/report/__init__.py | 74 ++++++++++++++++++++++++++++++++++++++++--
2 files changed, 84 insertions(+), 3 deletions(-)
diff --git a/man/en/sos-report.1 b/man/en/sos-report.1
index 36b337df..e8efc8f8 100644
--- a/man/en/sos-report.1
+++ b/man/en/sos-report.1
@@ -14,7 +14,7 @@ sos report \- Collect and package diagnostic and support data
[--preset preset] [--add-preset add_preset]\fR
[--del-preset del_preset] [--desc description]\fR
[--batch] [--build] [--debug] [--dry-run]\fR
- [--label label] [--case-id id]\fR
+ [--estimate-only] [--label label] [--case-id id]\fR
[--threads threads]\fR
[--plugin-timeout TIMEOUT]\fR
[--cmd-timeout TIMEOUT]\fR
@@ -317,6 +317,17 @@ output, or string data from the system. The resulting logs may be used
to understand the actions that sos would have taken without the dry run
option.
.TP
+.B \--estimate-only
+Estimate disk space requirements when running sos report. This can be valuable
+to prevent sosreport working dir to consume all free disk space. No plugin data
+is available at the end.
+
+Plugins will be collected sequentially, size of collected files and commands outputs
+will be calculated and the plugin files will be immediatelly deleted prior execution
+of the next plugin. This still can consume whole free disk space, though. Please note,
+size estimations may not be accurate for highly utilized systems due to changes between
+an estimate and a real execution.
+.TP
.B \--upload
If specified, attempt to upload the resulting archive to a vendor defined location.
diff --git a/sos/report/__init__.py b/sos/report/__init__.py
index 82484f1d..b033f621 100644
--- a/sos/report/__init__.py
+++ b/sos/report/__init__.py
@@ -86,6 +86,7 @@ class SoSReport(SoSComponent):
'desc': '',
'domains': [],
'dry_run': False,
+ 'estimate_only': False,
'experimental': False,
'enable_plugins': [],
'keywords': [],
@@ -137,6 +138,7 @@ class SoSReport(SoSComponent):
self._args = args
self.sysroot = "/"
self.preset = None
+ self.estimated_plugsizes = {}
self.print_header()
self._set_debug()
@@ -223,6 +225,11 @@ class SoSReport(SoSComponent):
help="Description for a new preset",)
report_grp.add_argument("--dry-run", action="store_true",
help="Run plugins but do not collect data")
+ report_grp.add_argument("--estimate-only", action="store_true",
+ help="Approximate disk space requirements for "
+ "a real sos run; disables --clean and "
+ "--collect, sets --threads=1 and "
+ "--no-postproc")
report_grp.add_argument("--experimental", action="store_true",
dest="experimental", default=False,
help="enable experimental plugins")
@@ -700,6 +700,33 @@ class SoSReport(SoSComponent):
self.all_options.append((plugin, plugin_name, optname,
optparm))
+ def _set_estimate_only(self):
+ # set estimate-only mode by enforcing some options settings
+ # and return a corresponding log messages string
+ msg = "\nEstimate-only mode enabled"
+ ext_msg = []
+ if self.opts.threads > 1:
+ ext_msg += ["--threads=%s overriden to 1" % self.opts.threads, ]
+ self.opts.threads = 1
+ if not self.opts.build:
+ ext_msg += ["--build enabled", ]
+ self.opts.build = True
+ if not self.opts.no_postproc:
+ ext_msg += ["--no-postproc enabled", ]
+ self.opts.no_postproc = True
+ if self.opts.clean:
+ ext_msg += ["--clean disabled", ]
+ self.opts.clean = False
+ if self.opts.upload:
+ ext_msg += ["--upload* options disabled", ]
+ self.opts.upload = False
+ if ext_msg:
+ msg += ", which overrides some options:\n " + "\n ".join(ext_msg)
+ else:
+ msg += "."
+ msg += "\n\n"
+ return msg
+
def _report_profiles_and_plugins(self):
self.ui_log.info("")
if len(self.loaded_plugins):
@@ -875,10 +909,12 @@ class SoSReport(SoSComponent):
return True
def batch(self):
+ msg = self.policy.get_msg()
+ if self.opts.estimate_only:
+ msg += self._set_estimate_only()
if self.opts.batch:
- self.ui_log.info(self.policy.get_msg())
+ self.ui_log.info(msg)
else:
- msg = self.policy.get_msg()
msg += _("Press ENTER to continue, or CTRL-C to quit.\n")
try:
input(msg)
@@ -1011,6 +1047,22 @@ class SoSReport(SoSComponent):
self.running_plugs.remove(plugin[1])
self.loaded_plugins[plugin[0]-1][1].set_timeout_hit()
pool._threads.clear()
+ if self.opts.estimate_only:
+ from pathlib import Path
+ tmpdir_path = Path(self.archive.get_tmp_dir())
+ self.estimated_plugsizes[plugin[1]] = sum(
+ [f.stat().st_size for f in tmpdir_path.glob('**/*')
+ if (os.path.isfile(f) and not os.path.islink(f))])
+ # remove whole tmp_dir content - including "sos_commands" and
+ # similar dirs that will be re-created on demand by next plugin
+ # if needed; it is less error-prone approach than skipping
+ # deletion of some dirs but deleting their content
+ for f in os.listdir(self.archive.get_tmp_dir()):
+ f = os.path.join(self.archive.get_tmp_dir(), f)
+ if os.path.isdir(f):
+ rmtree(f)
+ else:
+ os.unlink(f)
return True
def collect_plugin(self, plugin):
@@ -1330,6 +1382,24 @@ class SoSReport(SoSComponent):
self.policy.display_results(archive, directory, checksum,
map_file=map_file)
+ if self.opts.estimate_only:
+ from sos.utilities import get_human_readable
+ _sum = get_human_readable(sum(self.estimated_plugsizes.values()))
+ self.ui_log.info("Estimated disk space requirement for whole "
+ "uncompressed sos report directory: %s" % _sum)
+ bigplugins = sorted(self.estimated_plugsizes.items(),
+ key=lambda x: x[1], reverse=True)[:3]
+ bp_out = ", ".join("%s: %s" %
+ (p, get_human_readable(v, precision=0))
+ for p, v in bigplugins)
+ self.ui_log.info("Three biggest plugins: %s" % bp_out)
+ self.ui_log.info("")
+ self.ui_log.info("Please note the estimation is relevant to the "
+ "current options.")
+ self.ui_log.info("Be aware that the real disk space requirements "
+ "might be different.")
+ self.ui_log.info("")
+
if self.opts.upload or self.opts.upload_url:
if not self.opts.build:
try:
--
2.31.1
From 7ae47e6c0717c0b56c3368008dd99a87f7f436d5 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Wed, 13 Oct 2021 20:21:16 +0200
Subject: [PATCH] [report] Count with sos_logs and sos_reports in
--estimate-only
Currently, we estimate just plugins' disk space and ignore sos_logs
or sos_reports directories - although they can occupy nontrivial disk
space as well.
Resolves: #2723
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/__init__.py | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/sos/report/__init__.py b/sos/report/__init__.py
index e35c7e8d..7feb31ee 100644
--- a/sos/report/__init__.py
+++ b/sos/report/__init__.py
@@ -1380,6 +1380,14 @@ class SoSReport(SoSComponent):
if self.opts.estimate_only:
from sos.utilities import get_human_readable
+ from pathlib import Path
+ # add sos_logs, sos_reports dirs, etc., basically everything
+ # that remained in self.tmpdir after plugins' contents removal
+ # that still will be moved to the sos report final directory path
+ tmpdir_path = Path(self.tmpdir)
+ self.estimated_plugsizes['sos_logs_reports'] = sum(
+ [f.stat().st_size for f in tmpdir_path.glob('**/*')])
+
_sum = get_human_readable(sum(self.estimated_plugsizes.values()))
self.ui_log.info("Estimated disk space requirement for whole "
"uncompressed sos report directory: %s" % _sum)
--
2.31.1
From 4293f3317505661e8f32ba94ad87310996fa1626 Mon Sep 17 00:00:00 2001
From: Eric Desrochers <eric.desrochers@canonical.com>
Date: Tue, 19 Oct 2021 12:18:40 -0400
Subject: [PATCH] [report] check for symlink before rmtree when opt
estimate-only is use
Check if the dir is also symlink before performing rmtree()
method so that unlink() method can be used instead.
Traceback (most recent call last):
File "./bin/sos", line 22, in <module>
sos.execute()
File "/tmp/sos/sos/__init__.py", line 186, in execute
self._component.execute()
OSError: Cannot call rmtree on a symbolic link
Closes: #2727
Signed-off-by: Eric Desrochers <eric.desrochers@canonical.com>
---
sos/report/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sos/report/__init__.py b/sos/report/__init__.py
index 7feb31ee..1b5bc97d 100644
--- a/sos/report/__init__.py
+++ b/sos/report/__init__.py
@@ -1059,7 +1059,7 @@ class SoSReport(SoSComponent):
# deletion of some dirs but deleting their content
for f in os.listdir(self.archive.get_tmp_dir()):
f = os.path.join(self.archive.get_tmp_dir(), f)
- if os.path.isdir(f):
+ if os.path.isdir(f) and not os.path.islink(f):
rmtree(f)
else:
os.unlink(f)
--
2.31.1

View File

@ -1,32 +0,0 @@
From bbb7f8bf522960a8ca7625f539e9e5d109abb704 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Wed, 19 May 2021 08:31:45 +0200
Subject: [PATCH] [networking] collect also tc filter show ingress
Both "tc -s filter show dev %eth [|ingress]" commands required as
they provide different output.
Resolves: #2550
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/plugins/networking.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sos/report/plugins/networking.py b/sos/report/plugins/networking.py
index acfa027f..35646268 100644
--- a/sos/report/plugins/networking.py
+++ b/sos/report/plugins/networking.py
@@ -156,7 +156,8 @@ class Networking(Plugin):
"ethtool --phy-statistics " + eth,
"ethtool --show-priv-flags " + eth,
"ethtool --show-eee " + eth,
- "tc -s filter show dev " + eth
+ "tc -s filter show dev " + eth,
+ "tc -s filter show dev " + eth + " ingress",
], tags=eth)
# skip EEPROM collection by default, as it might hang or
--
2.26.3

View File

@ -1,284 +0,0 @@
From 00d12ad3cf24dcc6c73e9bcf63db1d3f17e58bb1 Mon Sep 17 00:00:00 2001
From: Jake Hunsaker <jhunsake@redhat.com>
Date: Thu, 1 Jul 2021 10:50:54 -0400
Subject: [PATCH] [sosnode] Properly format skip-commands and skip-files on
nodes
Fixes an issue where options provided for `skip-commands` and
`skip-files` were not properly formatted, thus causing an exception
during the finalization of the node's sos command.
Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
---
sos/collector/sosnode.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/sos/collector/sosnode.py b/sos/collector/sosnode.py
index 6597d236..426edcba 100644
--- a/sos/collector/sosnode.py
+++ b/sos/collector/sosnode.py
@@ -734,11 +734,12 @@ class SosNode():
if self.check_sos_version('4.1'):
if self.opts.skip_commands:
sos_opts.append(
- '--skip-commands=%s' % (quote(self.opts.skip_commands))
+ '--skip-commands=%s' % (
+ quote(','.join(self.opts.skip_commands)))
)
if self.opts.skip_files:
sos_opts.append(
- '--skip-files=%s' % (quote(self.opts.skip_files))
+ '--skip-files=%s' % (quote(','.join(self.opts.skip_files)))
)
if self.check_sos_version('4.2'):
--
2.31.1
From de7edce3f92ed50abcb28dd0dbcbeb104dc7c679 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Fri, 2 Jul 2021 09:52:11 +0200
Subject: [PATCH] [collector] fix a typo in --plugin-option
Sos report uses --plugin-option or --plugopts.
Relevant: #2606
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/collector/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sos/collector/__init__.py b/sos/collector/__init__.py
index 6d96d692..f072287e 100644
--- a/sos/collector/__init__.py
+++ b/sos/collector/__init__.py
@@ -272,7 +272,7 @@ class SoSCollector(SoSComponent):
help="chroot executed commands to SYSROOT")
sos_grp.add_argument('-e', '--enable-plugins', action="extend",
help='Enable specific plugins for sosreport')
- sos_grp.add_argument('-k', '--plugin-options', action="extend",
+ sos_grp.add_argument('-k', '--plugin-option', action="extend",
help='Plugin option as plugname.option=value')
sos_grp.add_argument('--log-size', default=0, type=int,
help='Limit the size of individual logs (in MiB)')
--
2.31.1
From 24a79ae8df8f29276f6139c68d4ba9b05114f951 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Fri, 2 Jul 2021 09:53:47 +0200
Subject: [PATCH] [options] allow variant option names in config file
While cmdline allows --plugin-option as well as --plugopts,
it stores the value under `plugopts` key. Therefore parsing
config file ignores --plugin-option.
Similarly for --name/--label and --profile/--profiles.
When processing config file, we must unify those potentially duplicit
keys.
Resolves: #2606
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/options.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/sos/options.py b/sos/options.py
index 1eda55d6..a014a022 100644
--- a/sos/options.py
+++ b/sos/options.py
@@ -186,9 +186,18 @@ class SoSOptions():
if 'verbose' in odict.keys():
odict['verbosity'] = int(odict.pop('verbose'))
# convert options names
+ # unify some of them if multiple variants of the
+ # cmdoption exist
+ rename_opts = {
+ 'name': 'label',
+ 'plugin_option': 'plugopts',
+ 'profile': 'profiles'
+ }
for key in list(odict):
if '-' in key:
odict[key.replace('-', '_')] = odict.pop(key)
+ if key in rename_opts:
+ odict[rename_opts[key]] = odict.pop(key)
# set the values according to the config file
for key, val in odict.items():
if isinstance(val, str):
--
2.31.1
From c7d3644c0c64e9e5439806250592a55c8e2de26f Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Thu, 1 Jul 2021 08:11:15 +0200
Subject: [PATCH] [report,collect] unify --map-file arguments
Unify --map[-file] argument among report/collect/clean.
Resolves: #2602
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/cleaner/__init__.py | 2 +-
sos/collector/__init__.py | 2 +-
sos/report/__init__.py | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/sos/cleaner/__init__.py b/sos/cleaner/__init__.py
index 7414b55e0..4c9837826 100644
--- a/sos/cleaner/__init__.py
+++ b/sos/cleaner/__init__.py
@@ -192,7 +192,7 @@ def add_parser_options(cls, parser):
'file for obfuscation'))
clean_grp.add_argument('--no-update', dest='no_update', default=False,
action='store_true',
- help='Do not update the --map file with new '
+ help='Do not update the --map-file with new '
'mappings from this run')
clean_grp.add_argument('--keep-binary-files', default=False,
action='store_true',
diff --git a/sos/collector/__init__.py b/sos/collector/__init__.py
index 7b8cfcf72..6d96d6923 100644
--- a/sos/collector/__init__.py
+++ b/sos/collector/__init__.py
@@ -427,7 +427,7 @@ def add_parser_options(cls, parser):
cleaner_grp.add_argument('--no-update', action='store_true',
default=False, dest='no_update',
help='Do not update the default cleaner map')
- cleaner_grp.add_argument('--map', dest='map_file',
+ cleaner_grp.add_argument('--map-file', dest='map_file',
default='/etc/sos/cleaner/default_mapping',
help=('Provide a previously generated mapping'
' file for obfuscation'))
diff --git a/sos/report/__init__.py b/sos/report/__init__.py
index 7ad2d24a4..411c4eb03 100644
--- a/sos/report/__init__.py
+++ b/sos/report/__init__.py
@@ -341,7 +341,7 @@ def add_parser_options(cls, parser):
cleaner_grp.add_argument('--no-update', action='store_true',
default=False, dest='no_update',
help='Do not update the default cleaner map')
- cleaner_grp.add_argument('--map', dest='map_file',
+ cleaner_grp.add_argument('--map-file', dest='map_file',
default='/etc/sos/cleaner/default_mapping',
help=('Provide a previously generated mapping'
' file for obfuscation'))
From fd75745e7a5a6c5def8e6d23190227872b9912c3 Mon Sep 17 00:00:00 2001
From: Jake Hunsaker <jhunsake@redhat.com>
Date: Wed, 11 Aug 2021 10:48:41 -0400
Subject: [PATCH] [sosnode] Fix passing of plugin options when using
`--only-plugins`
Fixes the handling of plugin options passed by `sos collect` to each
node by first aligning the SoSOption name to those of `report`
(`plugopts`), and second re-arranges the handling of plugin options and
preset options passed by the user when also using `--only-plugins` so
that the former are preserved and passed only with the `--only-plugins`
option value.
Resolves: #2641
Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
---
sos/collector/__init__.py | 5 +++--
sos/collector/sosnode.py | 34 +++++++++++++++++-----------------
2 files changed, 20 insertions(+), 19 deletions(-)
diff --git a/sos/collector/__init__.py b/sos/collector/__init__.py
index 57ef074e..70b7a69e 100644
--- a/sos/collector/__init__.py
+++ b/sos/collector/__init__.py
@@ -84,7 +84,7 @@ class SoSCollector(SoSComponent):
'only_plugins': [],
'password': False,
'password_per_node': False,
- 'plugin_options': [],
+ 'plugopts': [],
'plugin_timeout': None,
'cmd_timeout': None,
'preset': '',
@@ -273,7 +273,8 @@ class SoSCollector(SoSComponent):
help="chroot executed commands to SYSROOT")
sos_grp.add_argument('-e', '--enable-plugins', action="extend",
help='Enable specific plugins for sosreport')
- sos_grp.add_argument('-k', '--plugin-option', action="extend",
+ sos_grp.add_argument('-k', '--plugin-option', '--plugopts',
+ action="extend", dest='plugopts',
help='Plugin option as plugname.option=value')
sos_grp.add_argument('--log-size', default=0, type=int,
help='Limit the size of individual logs (in MiB)')
diff --git a/sos/collector/sosnode.py b/sos/collector/sosnode.py
index 426edcba..5d05c297 100644
--- a/sos/collector/sosnode.py
+++ b/sos/collector/sosnode.py
@@ -667,10 +667,10 @@ class SosNode():
if self.cluster.sos_plugin_options:
for opt in self.cluster.sos_plugin_options:
- if not any(opt in o for o in self.plugin_options):
+ if not any(opt in o for o in self.plugopts):
option = '%s=%s' % (opt,
self.cluster.sos_plugin_options[opt])
- self.plugin_options.append(option)
+ self.plugopts.append(option)
# set master-only options
if self.cluster.check_node_is_master(self):
@@ -688,7 +688,7 @@ class SosNode():
self.only_plugins = list(self.opts.only_plugins)
self.skip_plugins = list(self.opts.skip_plugins)
self.enable_plugins = list(self.opts.enable_plugins)
- self.plugin_options = list(self.opts.plugin_options)
+ self.plugopts = list(self.opts.plugopts)
self.preset = list(self.opts.preset)
def finalize_sos_cmd(self):
@@ -754,6 +754,20 @@ class SosNode():
os.path.join(self.host.sos_bin_path, self.sos_bin)
)
+ if self.plugopts:
+ opts = [o for o in self.plugopts
+ if self._plugin_exists(o.split('.')[0])
+ and self._plugin_option_exists(o.split('=')[0])]
+ if opts:
+ sos_opts.append('-k %s' % quote(','.join(o for o in opts)))
+
+ if self.preset:
+ if self._preset_exists(self.preset):
+ sos_opts.append('--preset=%s' % quote(self.preset))
+ else:
+ self.log_debug('Requested to enable preset %s but preset does '
+ 'not exist on node' % self.preset)
+
if self.only_plugins:
plugs = [o for o in self.only_plugins if self._plugin_exists(o)]
if len(plugs) != len(self.only_plugins):
@@ -792,20 +806,6 @@ class SosNode():
if enable:
sos_opts.append('--enable-plugins=%s' % quote(enable))
- if self.plugin_options:
- opts = [o for o in self.plugin_options
- if self._plugin_exists(o.split('.')[0])
- and self._plugin_option_exists(o.split('=')[0])]
- if opts:
- sos_opts.append('-k %s' % quote(','.join(o for o in opts)))
-
- if self.preset:
- if self._preset_exists(self.preset):
- sos_opts.append('--preset=%s' % quote(self.preset))
- else:
- self.log_debug('Requested to enable preset %s but preset does '
- 'not exist on node' % self.preset)
-
self.sos_cmd = "%s %s" % (sos_cmd, ' '.join(sos_opts))
self.log_info('Final sos command set to %s' % self.sos_cmd)
self.manifest.add_field('final_sos_command', self.sos_cmd)
--
2.31.1

View File

@ -1,39 +0,0 @@
From 4fb834ec862228afb276ccbd45aa86c66044ea66 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Mon, 15 Mar 2021 09:09:51 +0100
Subject: [PATCH] [gluster] collect public keys from the right dir
Collection of glusterfind dir is achieved by /var/lib/gluster
so it doesn't be collected explicitly.
/var/lib/glusterd/glusterfind/.keys/ subdir is required to be
explicitly collected, as add_copy_spec uses glob.glob() that skips
hidden files.
Resolves: #2451
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
---
sos/report/plugins/gluster.py | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/sos/report/plugins/gluster.py b/sos/report/plugins/gluster.py
index e1a89df2..952cab63 100644
--- a/sos/report/plugins/gluster.py
+++ b/sos/report/plugins/gluster.py
@@ -76,9 +76,8 @@ class Gluster(Plugin, RedHatPlugin):
"/var/lib/glusterd/",
# collect nfs-ganesha related configuration
"/run/gluster/shared_storage/nfs-ganesha/",
- # collect status files and public ssh keys
- "/var/lib/glusterd/.keys/",
- "/var/lib/glusterd/glusterfind/"
+ # collect public ssh keys (a_s_c skips implicit hidden files)
+ "/var/lib/glusterd/glusterfind/.keys/",
] + glob.glob('/run/gluster/*tier-dht/*'))
if not self.get_option("all_logs"):
--
2.26.3

View File

@ -1,243 +0,0 @@
From fc0218638f3e865c4315823e72aef2f46d012d07 Mon Sep 17 00:00:00 2001
From: Jake Hunsaker <jhunsake@redhat.com>
Date: Wed, 14 Apr 2021 11:55:03 -0400
Subject: [PATCH 1/2] [clean] Load maps from all archives before obfuscation
loop
Previously, maps were being prepped via archives after extraction. This
reduced the amount of file IO being done, but made it so that necessary
obfuscations from later archives in a series would not be obfuscated in
the archives obfuscated before those later archives were extracted.
Fix this by extracting the map prep files into memory for each archive
to prep the maps before we enter the obfuscation loop entirely.
Closes: #2490
Related: RHBZ#1930181
Resolves: #2492
Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
---
sos/cleaner/__init__.py | 69 +++++++++++++++-----------
sos/cleaner/parsers/username_parser.py | 13 +++--
2 files changed, 45 insertions(+), 37 deletions(-)
diff --git a/sos/cleaner/__init__.py b/sos/cleaner/__init__.py
index b9eb61ef..d10cdc55 100644
--- a/sos/cleaner/__init__.py
+++ b/sos/cleaner/__init__.py
@@ -292,6 +292,7 @@ third party.
# we have at least one valid target to obfuscate
self.completed_reports = []
+ self.preload_all_archives_into_maps()
self.obfuscate_report_paths()
if not self.completed_reports:
@@ -473,6 +474,44 @@ third party.
self.ui_log.info("Exiting on user cancel")
os._exit(130)
+ def preload_all_archives_into_maps(self):
+ """Before doing the actual obfuscation, if we have multiple archives
+ to obfuscate then we need to preload each of them into the mappings
+ to ensure that node1 is obfuscated in node2 as well as node2 being
+ obfuscated in node1's archive.
+ """
+ self.log_info("Pre-loading multiple archives into obfuscation maps")
+ for _arc in self.report_paths:
+ is_dir = os.path.isdir(_arc)
+ if is_dir:
+ _arc_name = _arc
+ else:
+ archive = tarfile.open(_arc)
+ _arc_name = _arc.split('/')[-1].split('.tar')[0]
+ # for each parser, load the map_prep_file into memory, and then
+ # send that for obfuscation. We don't actually obfuscate the file
+ # here, do that in the normal archive loop
+ for _parser in self.parsers:
+ if not _parser.prep_map_file:
+ continue
+ _arc_path = os.path.join(_arc_name, _parser.prep_map_file)
+ try:
+ if is_dir:
+ _pfile = open(_arc_path, 'r')
+ content = _pfile.read()
+ else:
+ _pfile = archive.extractfile(_arc_path)
+ content = _pfile.read().decode('utf-8')
+ _pfile.close()
+ if isinstance(_parser, SoSUsernameParser):
+ _parser.load_usernames_into_map(content)
+ for line in content.splitlines():
+ if isinstance(_parser, SoSHostnameParser):
+ _parser.load_hostname_into_map(line)
+ self.obfuscate_line(line, _parser.prep_map_file)
+ except Exception as err:
+ self.log_debug("Could not prep %s: %s" % (_arc_path, err))
+
def obfuscate_report(self, report):
"""Individually handle each archive or directory we've discovered by
running through each file therein.
@@ -493,7 +532,6 @@ third party.
start_time = datetime.now()
arc_md.add_field('start_time', start_time)
archive.extract()
- self.prep_maps_from_archive(archive)
archive.report_msg("Beginning obfuscation...")
file_list = archive.get_file_list()
@@ -542,35 +580,6 @@ third party.
self.ui_log.info("Exception while processing %s: %s"
% (report, err))
- def prep_maps_from_archive(self, archive):
- """Open specific files from an archive and try to load those values
- into our mappings before iterating through the entire archive.
-
- Positional arguments:
-
- :param archive SoSObfuscationArchive: An open archive object
- """
- for parser in self.parsers:
- if not parser.prep_map_file:
- continue
- prep_file = archive.get_file_path(parser.prep_map_file)
- if not prep_file:
- self.log_debug("Could not prepare %s: %s does not exist"
- % (parser.name, parser.prep_map_file),
- caller=archive.archive_name)
- continue
- # this is a bit clunky, but we need to load this particular
- # parser in a different way due to how hostnames are validated for
- # obfuscation
- if isinstance(parser, SoSHostnameParser):
- with open(prep_file, 'r') as host_file:
- hostname = host_file.readline().strip()
- parser.load_hostname_into_map(hostname)
- if isinstance(parser, SoSUsernameParser):
- parser.load_usernames_into_map(prep_file)
- self.obfuscate_file(prep_file, parser.prep_map_file,
- archive.archive_name)
-
def obfuscate_file(self, filename, short_name=None, arc_name=None):
"""Obfuscate and individual file, line by line.
diff --git a/sos/cleaner/parsers/username_parser.py b/sos/cleaner/parsers/username_parser.py
index 5223c018..2bb6c7f3 100644
--- a/sos/cleaner/parsers/username_parser.py
+++ b/sos/cleaner/parsers/username_parser.py
@@ -39,16 +39,15 @@ class SoSUsernameParser(SoSCleanerParser):
super(SoSUsernameParser, self).__init__(conf_file)
self.mapping.load_names_from_options(opt_names)
- def load_usernames_into_map(self, fname):
+ def load_usernames_into_map(self, content):
"""Since we don't get the list of usernames from a straight regex for
this parser, we need to override the initial parser prepping here.
"""
- with open(fname, 'r') as lastfile:
- for line in lastfile.read().splitlines()[1:]:
- user = line.split()[0]
- if user in self.skip_list:
- continue
- self.mapping.get(user)
+ for line in content.splitlines()[1:]:
+ user = line.split()[0]
+ if user in self.skip_list:
+ continue
+ self.mapping.get(user)
def parse_line(self, line):
count = 0
--
2.26.3
From b713f458bfa92427147de754ea36054bfde53d71 Mon Sep 17 00:00:00 2001
From: Jake Hunsaker <jhunsake@redhat.com>
Date: Wed, 14 Apr 2021 12:22:28 -0400
Subject: [PATCH 2/2] [clean] Remove duplicate file skipping within
obfuscate_line()
A redundant file skipping check was being executed within
`obfuscate_line()` that would cause subsequent archives being obfuscated
to skip line obfuscation within a file, despite iterating through the
entire file.
Remove this redundant check, thus allowing proper obfuscation.
Closes: #2490
Related: RHBZ#1930181
Resolves: #2492
Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
---
sos/cleaner/__init__.py | 11 +++--------
sos/cleaner/obfuscation_archive.py | 2 --
2 files changed, 3 insertions(+), 10 deletions(-)
diff --git a/sos/cleaner/__init__.py b/sos/cleaner/__init__.py
index d10cdc55..bdd24f95 100644
--- a/sos/cleaner/__init__.py
+++ b/sos/cleaner/__init__.py
@@ -508,7 +508,7 @@ third party.
for line in content.splitlines():
if isinstance(_parser, SoSHostnameParser):
_parser.load_hostname_into_map(line)
- self.obfuscate_line(line, _parser.prep_map_file)
+ self.obfuscate_line(line)
except Exception as err:
self.log_debug("Could not prep %s: %s" % (_arc_path, err))
@@ -606,7 +606,7 @@ third party.
if not line.strip():
continue
try:
- line, count = self.obfuscate_line(line, short_name)
+ line, count = self.obfuscate_line(line)
subs += count
tfile.write(line)
except Exception as err:
@@ -631,7 +631,7 @@ third party.
pass
return string_data
- def obfuscate_line(self, line, filename):
+ def obfuscate_line(self, line):
"""Run a line through each of the obfuscation parsers, keeping a
cumulative total of substitutions done on that particular line.
@@ -639,16 +639,11 @@ third party.
:param line str: The raw line as read from the file being
processed
- :param filename str: Filename the line was read from
Returns the fully obfuscated line and the number of substitutions made
"""
count = 0
for parser in self.parsers:
- if filename and any([
- re.match(_s, filename) for _s in parser.skip_files
- ]):
- continue
try:
line, _count = parser.parse_line(line)
count += _count
diff --git a/sos/cleaner/obfuscation_archive.py b/sos/cleaner/obfuscation_archive.py
index 84ca30cd..c64ab13b 100644
--- a/sos/cleaner/obfuscation_archive.py
+++ b/sos/cleaner/obfuscation_archive.py
@@ -219,8 +219,6 @@ class SoSObfuscationArchive():
:param filename str: Filename relative to the extracted
archive root
"""
- if filename in self.file_sub_list:
- return True
if not os.path.isfile(self.get_file_path(filename)):
return True
--
2.26.3

View File

@ -1,99 +0,0 @@
From 3b439fb64d8d65b0c09aa8452bf0181ec20f8bcf Mon Sep 17 00:00:00 2001
From: Jose Castillo <jcastillo@redhat.com>
Date: Wed, 3 Mar 2021 13:03:16 +0100
Subject: [PATCH] [man] Multiple fixes in man pages
This patch fixes references to sosreport, to the
preferred 'sos report'. Also adds "SEE ALSO" consistently
for all man pages, and fixes a MAINTAINER line.
Resolves: #2432
Signed-off-by: Jose Castillo <jcastillo@redhat.com>
Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
---
man/en/sos-clean.1 | 5 +++++
man/en/sos-collect.1 | 1 +
man/en/sos-report.1 | 22 ++++++++++++++--------
3 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/man/en/sos-clean.1 b/man/en/sos-clean.1
index 0c62ed07..d64a0ec7 100644
--- a/man/en/sos-clean.1
+++ b/man/en/sos-clean.1
@@ -77,6 +77,11 @@ Default: 4
.TP
.B \-\-no-update
Do not write the mapping file contents to /etc/sos/cleaner/default_mapping
+.SH SEE ALSO
+.BR sos (1)
+.BR sos-report (1)
+.BR sos-collect (1)
+
.SH MAINTAINER
.nf
Jake Hunsaker <jhunsake@redhat.com>
diff --git a/man/en/sos-collect.1 b/man/en/sos-collect.1
index d4e5e648..da36542d 100644
--- a/man/en/sos-collect.1
+++ b/man/en/sos-collect.1
@@ -330,6 +330,7 @@ Sosreport option. Override the default compression type.
.SH SEE ALSO
.BR sos (1)
.BR sos-report (1)
+.BR sos-clean (1)
.SH MAINTAINER
Jake Hunsaker <jhunsake@redhat.com>
diff --git a/man/en/sos-report.1 b/man/en/sos-report.1
index e7fae97b..81005959 100644
--- a/man/en/sos-report.1
+++ b/man/en/sos-report.1
@@ -38,11 +38,12 @@ sosreport \- Collect and package diagnostic and support data
[-h|--help]\fR
.SH DESCRIPTION
-\fBsosreport\fR generates an archive of configuration and diagnostic
-information from the running system. The archive may be stored locally
-or centrally for recording or tracking purposes or may be sent to
-technical support representatives, developers or system administrators
-to assist with technical fault-finding and debugging.
+\fBreport\fR is an sos subcommand that generates an archive of
+configuration and diagnostic information from the running system.
+The archive may be stored locally or centrally for recording or
+tracking purposes or may be sent to technical support representatives,
+developers or system administrators to assist with technical
+fault-finding and debugging.
.LP
Sos is modular in design and is able to collect data from a wide
range of subsystems and packages that may be installed. An
@@ -110,8 +111,8 @@ User defined presets are saved under /var/lib/sos/presets as JSON-formatted file
.B \--add-preset ADD_PRESET [options]
Add a preset with name ADD_PRESET that enables [options] when called.
-For example, 'sosreport --add-preset mypreset --log-size=50 -n logs' will enable
-a user to run 'sosreport --preset mypreset' that sets the maximum log size to
+For example, 'sos report --add-preset mypreset --log-size=50 -n logs' will enable
+a user to run 'sos report --preset mypreset' that sets the maximum log size to
50 and disables the logs plugin.
Note: to set a description for the preset that is displayed with \fB--list-presets\fR,
@@ -343,9 +344,14 @@ been tested for this port or may still be under active development.
.TP
.B \--help
Display usage message.
+.SH SEE ALSO
+.BR sos (1)
+.BR sos-clean (1)
+.BR sos-collect (1)
+
.SH MAINTAINER
.nf
-Bryn M. Reeves <bmr@redhat.com>
+Jake Hunsaker <jhunsake@redhat.com>
.fi
.SH AUTHORS & CONTRIBUTORS
See \fBAUTHORS\fR file in the package documentation.
--
2.26.3

View File

@ -1,50 +0,0 @@
From 153c0154050a111fd7e5bcf4a685f906a1dea737 Mon Sep 17 00:00:00 2001
From: Jose Castillo <jcastillo@redhat.com>
Date: Wed, 10 Mar 2021 15:33:50 +0100
Subject: [PATCH] [ds] Mask password and encription keys in ldif files
Both /etc/dirsrv/slapd*/dse.ldif{,.startOK} files contain
sensitive information :
- all the nsSymmetricKey entries : symmetric encryption key
- nsslapd-rootpw : the admin password's hash
This patch masks these entries in the files we collect.
Resolves: #2442
Signed-off-by: Jose Castillo <jcastillo@redhat.com>
Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
---
sos/report/plugins/ds.py | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/sos/report/plugins/ds.py b/sos/report/plugins/ds.py
index f4d68d6e..d467dc89 100644
--- a/sos/report/plugins/ds.py
+++ b/sos/report/plugins/ds.py
@@ -74,4 +74,22 @@ class DirectoryServer(Plugin, RedHatPlugin):
self.add_cmd_output("ls -l /var/lib/dirsrv/slapd-*/db/*")
+ def postproc(self):
+ # Example for scrubbing rootpw hash
+ #
+ # nsslapd-rootpw: AAAAB3NzaC1yc2EAAAADAQABAAABAQDeXYA3juyPqaUuyfWV2HuIM
+ # v3gebb/5cvx9ehEAFF2yIKvsQN2EJGTV+hBM1DEOB4eyy/H11NqcNwm/2QsagDB3PVwYp
+ # 9VKN3BdhQjlhuoYKhLwgtYUMiGL8AX5g1qxjirIkTRJwjbXkSNuQaXig7wVjmvXnB2o7B
+ # zLtu99DiL1AizfVeZTYA+OVowYKYaXYljVmVKS+g3t29Obaom54ZLpfuoGMmyO64AJrWs
+ #
+ # to
+ #
+ # nsslapd-rootpw:********
+
+ regexppass = r"(nsslapd-rootpw(\s)*:(\s)*)(\S+)([\r\n]\s.*)*\n"
+ regexpkey = r"(nsSymmetricKey(\s)*::(\s)*)(\S+)([\r\n]\s.*)*\n"
+ repl = r"\1********\n"
+ self.do_path_regex_sub('/etc/dirsrv/*', regexppass, repl)
+ self.do_path_regex_sub('/etc/dirsrv/*', regexpkey, repl)
+
# vim: set et ts=4 sw=4 :
--
2.26.3

View File

@ -1,315 +0,0 @@
From 90b6b709e9f4002376b656b155d00d85382f1828 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Mon, 29 Mar 2021 16:23:01 +0200
Subject: [PATCH] [report] add --cmd-timeout option
Add --cmd-timeout option to configure command timeout. Plugin-specific
option of the same name (i.e. -k logs.cmd-timeout=60) can control the
timeout per plugin.
Option defaults and global/plugin-specific option preference follows the
--plugin-timeout rules.
Resolves: #2466
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
---
man/en/sos-report.1 | 18 +++++++++-
sos/collector/__init__.py | 3 ++
sos/collector/sosnode.py | 5 +++
sos/options.py | 3 +-
sos/report/__init__.py | 5 ++-
sos/report/plugins/__init__.py | 63 ++++++++++++++++++++++++----------
6 files changed, 76 insertions(+), 21 deletions(-)
diff --git a/man/en/sos-report.1 b/man/en/sos-report.1
index 81005959..51cf3436 100644
--- a/man/en/sos-report.1
+++ b/man/en/sos-report.1
@@ -17,6 +17,7 @@ sosreport \- Collect and package diagnostic and support data
[--label label] [--case-id id]\fR
[--threads threads]\fR
[--plugin-timeout TIMEOUT]\fR
+ [--cmd-timeout TIMEOUT]\fR
[-s|--sysroot SYSROOT]\fR
[-c|--chroot {auto|always|never}\fR
[--tmp-dir directory]\fR
@@ -247,7 +248,7 @@ Specify a timeout in seconds to allow each plugin to run for. A value of 0
means no timeout will be set. A value of -1 is used to indicate the default
timeout of 300 seconds.
-Note that this options sets the timeout for all plugins. If you want to set
+Note that this option sets the timeout for all plugins. If you want to set
a timeout for a specific plugin, use the 'timeout' plugin option available to
all plugins - e.g. '-k logs.timeout=600'.
@@ -255,6 +256,21 @@ The plugin-specific timeout option will override this option. For example, using
\'--plugin-timeout=60 -k logs.timeout=600\' will set a timeout of 600 seconds for
the logs plugin and 60 seconds for all other enabled plugins.
.TP
+.B \--cmd-timeout TIMEOUT
+Specify a timeout limit in seconds for a command execution. Same defaults logic
+from --plugin-timeout applies here.
+
+This option sets the command timeout for all plugins. If you want to set a cmd
+timeout for a specific plugin, use the 'cmd-timeout' plugin option available to
+all plugins - e.g. '-k logs.cmd-timeout=600'.
+
+Again, the same plugin/global precedence logic as for --plugin-timeout applies
+here.
+
+Note that setting --cmd-timeout (or -k logs.cmd-timeout) high should be followed
+by increasing the --plugin-timeout equivalent, otherwise the plugin can easily
+timeout on slow commands execution.
+.TP
.B \--case-id NUMBER
Specify a case identifier to associate with the archive.
Identifiers may include alphanumeric characters, commas and periods ('.').
diff --git a/sos/collector/__init__.py b/sos/collector/__init__.py
index 406c8f35..1ae73508 100644
--- a/sos/collector/__init__.py
+++ b/sos/collector/__init__.py
@@ -82,6 +82,7 @@ class SoSCollector(SoSComponent):
'password_per_node': False,
'plugin_options': [],
'plugin_timeout': None,
+ 'cmd_timeout': None,
'preset': '',
'save_group': '',
'since': '',
@@ -276,6 +277,8 @@ class SoSCollector(SoSComponent):
help='Do not collect env vars in sosreports')
sos_grp.add_argument('--plugin-timeout', type=int, default=None,
help='Set the global plugin timeout value')
+ sos_grp.add_argument('--cmd-timeout', type=int, default=None,
+ help='Set the global command timeout value')
sos_grp.add_argument('--since', default=None,
help=('Escapes archived files older than date. '
'This will also affect --all-logs. '
diff --git a/sos/collector/sosnode.py b/sos/collector/sosnode.py
index a1679655..dbbee12e 100644
--- a/sos/collector/sosnode.py
+++ b/sos/collector/sosnode.py
@@ -664,6 +664,11 @@ class SosNode():
'--skip-files=%s' % (quote(self.opts.skip_files))
)
+ if self.check_sos_version('4.2'):
+ if self.opts.cmd_timeout:
+ sos_opts.append('--cmd-timeout=%s'
+ % quote(str(self.opts.cmd_timeout)))
+
sos_cmd = sos_cmd.replace(
'sosreport',
os.path.join(self.host.sos_bin_path, self.sos_bin)
diff --git a/sos/options.py b/sos/options.py
index b82a7d36..1eda55d6 100644
--- a/sos/options.py
+++ b/sos/options.py
@@ -283,7 +283,8 @@ class SoSOptions():
if name in ("add_preset", "del_preset", "desc", "note"):
return False
# Exception list for options that still need to be reported when 0
- if name in ['log_size', 'plugin_timeout'] and value == 0:
+ if name in ['log_size', 'plugin_timeout', 'cmd_timeout'] \
+ and value == 0:
return True
return has_value(name, value)
diff --git a/sos/report/__init__.py b/sos/report/__init__.py
index 25478ba7..945d0fc1 100644
--- a/sos/report/__init__.py
+++ b/sos/report/__init__.py
@@ -107,6 +107,7 @@ class SoSReport(SoSComponent):
'only_plugins': [],
'preset': 'auto',
'plugin_timeout': 300,
+ 'cmd_timeout': 300,
'profiles': [],
'since': None,
'verify': False,
@@ -266,6 +267,8 @@ class SoSReport(SoSComponent):
help="A preset identifier", default="auto")
report_grp.add_argument("--plugin-timeout", default=None,
help="set a timeout for all plugins")
+ report_grp.add_argument("--cmd-timeout", default=None,
+ help="set a command timeout for all plugins")
report_grp.add_argument("-p", "--profile", "--profiles",
action="extend", dest="profiles", type=str,
default=[],
@@ -709,7 +712,7 @@ class SoSReport(SoSComponent):
self.ui_log.info(_("The following plugin options are available:"))
for (plug, plugname, optname, optparm) in self.all_options:
- if optname in ('timeout', 'postproc'):
+ if optname in ('timeout', 'postproc', 'cmd-timeout'):
continue
# format option value based on its type (int or bool)
if type(optparm["enabled"]) == bool:
diff --git a/sos/report/plugins/__init__.py b/sos/report/plugins/__init__.py
index 02625eb1..779119af 100644
--- a/sos/report/plugins/__init__.py
+++ b/sos/report/plugins/__init__.py
@@ -472,6 +472,9 @@ class Plugin(object):
_default_plug_opts = [
('timeout', 'Timeout in seconds for plugin. The default value (-1) ' +
'defers to the general plugin timeout, 300 seconds', 'fast', -1),
+ ('cmd-timeout', 'Timeout in seconds for a command execution. The ' +
+ 'default value (-1) defers to the general cmd timeout, 300 ' +
+ 'seconds', 'fast', -1),
('postproc', 'Enable post-processing collected plugin data', 'fast',
True)
]
@@ -532,16 +535,15 @@ class Plugin(object):
self.manifest.add_list('commands', [])
self.manifest.add_list('files', [])
- @property
- def timeout(self):
- """Returns either the default plugin timeout value, the value as
- provided on the commandline via -k plugin.timeout=value, or the value
- of the global --plugin-timeout option.
+ def timeout_from_options(self, optname, plugoptname, default_timeout):
+ """Returns either the default [plugin|cmd] timeout value, the value as
+ provided on the commandline via -k plugin.[|cmd-]timeout=value, or the
+ value of the global --[plugin|cmd]-timeout option.
"""
_timeout = None
try:
- opt_timeout = self.get_option('plugin_timeout')
- own_timeout = int(self.get_option('timeout'))
+ opt_timeout = self.get_option(optname)
+ own_timeout = int(self.get_option(plugoptname))
if opt_timeout is None:
_timeout = own_timeout
elif opt_timeout is not None and own_timeout == -1:
@@ -551,10 +553,30 @@ class Plugin(object):
else:
return None
except ValueError:
- return self.plugin_timeout # Default to known safe value
+ return default_timeout # Default to known safe value
if _timeout is not None and _timeout > -1:
return _timeout
- return self.plugin_timeout
+ return default_timeout
+
+ @property
+ def timeout(self):
+ """Returns either the default plugin timeout value, the value as
+ provided on the commandline via -k plugin.timeout=value, or the value
+ of the global --plugin-timeout option.
+ """
+ _timeout = self.timeout_from_options('plugin_timeout', 'timeout',
+ self.plugin_timeout)
+ return _timeout
+
+ @property
+ def cmdtimeout(self):
+ """Returns either the default command timeout value, the value as
+ provided on the commandline via -k plugin.cmd-timeout=value, or the
+ value of the global --cmd-timeout option.
+ """
+ _cmdtimeout = self.timeout_from_options('cmd_timeout', 'cmd-timeout',
+ self.cmd_timeout)
+ return _cmdtimeout
def set_timeout_hit(self):
self._timeout_hit = True
@@ -1235,8 +1257,8 @@ class Plugin(object):
"""
global_options = (
- 'all_logs', 'allow_system_changes', 'log_size', 'plugin_timeout',
- 'since', 'verify'
+ 'all_logs', 'allow_system_changes', 'cmd_timeout', 'log_size',
+ 'plugin_timeout', 'since', 'verify'
)
if optionname in global_options:
@@ -1505,7 +1527,7 @@ class Plugin(object):
'tags': _spec_tags
})
- def add_blockdev_cmd(self, cmds, devices='block', timeout=300,
+ def add_blockdev_cmd(self, cmds, devices='block', timeout=None,
sizelimit=None, chroot=True, runat=None, env=None,
binary=False, prepend_path=None, whitelist=[],
blacklist=[], tags=[]):
@@ -1569,7 +1591,7 @@ class Plugin(object):
whitelist=whitelist, blacklist=blacklist,
tags=_dev_tags)
- def _add_device_cmd(self, cmds, devices, timeout=300, sizelimit=None,
+ def _add_device_cmd(self, cmds, devices, timeout=None, sizelimit=None,
chroot=True, runat=None, env=None, binary=False,
prepend_path=None, whitelist=[], blacklist=[],
tags=[]):
@@ -1627,7 +1649,7 @@ class Plugin(object):
changes=soscmd.changes)
def add_cmd_output(self, cmds, suggest_filename=None,
- root_symlink=None, timeout=cmd_timeout, stderr=True,
+ root_symlink=None, timeout=None, stderr=True,
chroot=True, runat=None, env=None, binary=False,
sizelimit=None, pred=None, subdir=None,
changes=False, foreground=False, tags=[]):
@@ -1849,7 +1871,7 @@ class Plugin(object):
self._log_debug("added string ...'%s' as '%s'" % (summary, filename))
def _collect_cmd_output(self, cmd, suggest_filename=None,
- root_symlink=False, timeout=cmd_timeout,
+ root_symlink=False, timeout=None,
stderr=True, chroot=True, runat=None, env=None,
binary=False, sizelimit=None, subdir=None,
changes=False, foreground=False, tags=[]):
@@ -1883,6 +1905,8 @@ class Plugin(object):
if self._timeout_hit:
return
+ if timeout is None:
+ timeout = self.cmdtimeout
_tags = []
if isinstance(tags, str):
@@ -1975,7 +1999,7 @@ class Plugin(object):
return result
def collect_cmd_output(self, cmd, suggest_filename=None,
- root_symlink=False, timeout=cmd_timeout,
+ root_symlink=False, timeout=None,
stderr=True, chroot=True, runat=None, env=None,
binary=False, sizelimit=None, pred=None,
subdir=None, tags=[]):
@@ -2044,7 +2068,7 @@ class Plugin(object):
tags=tags
)
- def exec_cmd(self, cmd, timeout=cmd_timeout, stderr=True, chroot=True,
+ def exec_cmd(self, cmd, timeout=None, stderr=True, chroot=True,
runat=None, env=None, binary=False, pred=None,
foreground=False, container=False, quotecmd=False):
"""Execute a command right now and return the output and status, but
@@ -2095,6 +2119,9 @@ class Plugin(object):
if not self.test_predicate(cmd=True, pred=pred):
return _default
+ if timeout is None:
+ timeout = self.cmdtimeout
+
if chroot or self.commons['cmdlineopts'].chroot == 'always':
root = self.sysroot
else:
@@ -2331,7 +2358,7 @@ class Plugin(object):
def add_journal(self, units=None, boot=None, since=None, until=None,
lines=None, allfields=False, output=None,
- timeout=cmd_timeout, identifier=None, catalog=None,
+ timeout=None, identifier=None, catalog=None,
sizelimit=None, pred=None, tags=[]):
"""Collect journald logs from one of more units.
--
2.26.3

View File

@ -1,30 +0,0 @@
From 0d56e43299009ffa91f665d85b5a08ba76da9c1f Mon Sep 17 00:00:00 2001
From: Jose Castillo <jcastillo@redhat.com>
Date: Wed, 17 Mar 2021 13:10:36 +0100
Subject: [PATCH] [cups] Add gathering cups-browsed logs
Gather logs from the service cups-browsed sent
to the journal.
Resolves: #2452
Signed-off-by: Jose Castillo <jcastillo@redhat.com>
Signed-off-by: Bryan Quigley <code@bryanquigley.com>
---
sos/report/plugins/cups.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/sos/report/plugins/cups.py b/sos/report/plugins/cups.py
index 29a903e8..ab7b6b70 100644
--- a/sos/report/plugins/cups.py
+++ b/sos/report/plugins/cups.py
@@ -40,5 +40,6 @@ class Cups(Plugin, IndependentPlugin):
])
self.add_journal(units="cups")
+ self.add_journal(units="cups-browsed")
# vim: set et ts=4 sw=4 :
--
2.26.3

View File

@ -1,62 +0,0 @@
From d03c2fa4439c87783293c922b2825cf86e8818bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Po=C5=82awski?= <ppolawsk@redhat.com>
Date: Fri, 12 Mar 2021 12:42:30 +0100
Subject: [PATCH] [sssd] Enable collecting SSSD memory cache
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
SSSD plugin by default collects only logs and configuration.
This patch enables collecting memory cache maintained
by SSSD daemon. Cache does not contain any client sensible
data so can be safely included in the sos-report.
Resolves: #2444
Signed-off-by: Paweł Poławski <ppolawsk@redhat.com>
Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
---
sos/report/plugins/sssd.py | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/sos/report/plugins/sssd.py b/sos/report/plugins/sssd.py
index 9469c41c..aeb68c4f 100644
--- a/sos/report/plugins/sssd.py
+++ b/sos/report/plugins/sssd.py
@@ -10,6 +10,7 @@
from sos.report.plugins import (Plugin, RedHatPlugin, DebianPlugin,
UbuntuPlugin, SoSPredicate)
+from glob import glob
class Sssd(Plugin):
@@ -22,11 +23,22 @@ class Sssd(Plugin):
def setup(self):
self.add_copy_spec([
+ # main config file
"/etc/sssd/sssd.conf",
- "/var/log/sssd/*",
- "/var/lib/sss/pubconf/krb5.include.d/*",
# SSSD 1.14
- "/etc/sssd/conf.d/*.conf"
+ "/etc/sssd/conf.d/*.conf",
+ # dynamic Kerberos configuration
+ "/var/lib/sss/pubconf/krb5.include.d/*"
+ ])
+
+ # add individual log files
+ self.add_copy_spec(glob("/var/log/sssd/*log*"))
+
+ # add memory cache
+ self.add_copy_spec([
+ "/var/lib/sss/mc/passwd",
+ "/var/lib/sss/mc/group",
+ "/var/lib/sss/mc/initgroups"
])
# call sssctl commands only when sssd service is running,
--
2.26.3

View File

@ -1,29 +0,0 @@
From dddabb07a88d398ed7b8a878e95acfd968af6698 Mon Sep 17 00:00:00 2001
From: Mamatha Inamdar <mamatha4@linux.vnet.ibm.com>
Date: Tue, 23 Mar 2021 17:58:30 +0530
Subject: [PATCH] This patch is to update kernel plugin to collect
dynamic_debug log files for ibmvNIC
Resolves: #2458
Signed-off-by: Mamatha Inamdar <mamatha4@linux.vnet.ibm.com>
Signed-off-by: Bryan Quigley <code@bryanquigley.com>
---
sos/report/plugins/kernel.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/sos/report/plugins/kernel.py b/sos/report/plugins/kernel.py
index febe2ad0..dd7b6939 100644
--- a/sos/report/plugins/kernel.py
+++ b/sos/report/plugins/kernel.py
@@ -106,6 +106,7 @@ class Kernel(Plugin, IndependentPlugin):
"/proc/misc",
"/var/log/dmesg",
"/sys/fs/pstore",
+ "/sys/kernel/debug/dynamic_debug/control",
clocksource_path + "available_clocksource",
clocksource_path + "current_clocksource"
])
--
2.26.3

View File

@ -1,147 +0,0 @@
From 808d9f35ac504a58c337ffed14b39119a591808f Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Tue, 27 Apr 2021 22:16:08 +0200
Subject: [PATCH] [pulpcore] add plugin for pulp-3
Pulp-3 / pulpcore as a revolution from pulp-2 needs a separate
plugin, since both plugins have nothing in common and there might
be deployments where is active both pulp-2 and pulp-3.
Resolves: #2278
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
---
sos/report/plugins/pulpcore.py | 120 +++++++++++++++++++++++++++++++++
1 file changed, 120 insertions(+)
create mode 100644 sos/report/plugins/pulpcore.py
diff --git a/sos/report/plugins/pulpcore.py b/sos/report/plugins/pulpcore.py
new file mode 100644
index 00000000..20403814
--- /dev/null
+++ b/sos/report/plugins/pulpcore.py
@@ -0,0 +1,120 @@
+# Copyright (C) 2021 Red Hat, Inc., Pavel Moravec <pmoravec@redhat.com>
+
+# This file is part of the sos project: https://github.com/sosreport/sos
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# version 2 of the GNU General Public License.
+#
+# See the LICENSE file in the source distribution for further information.
+
+from sos.report.plugins import Plugin, IndependentPlugin
+from pipes import quote
+from re import match
+
+
+class PulpCore(Plugin, IndependentPlugin):
+
+ short_desc = 'Pulp-3 aka pulpcore'
+
+ plugin_name = "pulpcore"
+ commands = ("pulpcore-manager",)
+ files = ("/etc/pulp/settings.py",)
+ option_list = [
+ ('task-days', 'days of tasks history', 'fast', 7)
+ ]
+
+ def parse_settings_config(self):
+ databases_scope = False
+ self.dbhost = "localhost"
+ self.dbport = 5432
+ self.dbpasswd = ""
+ # TODO: read also redis config (we dont expect much customisations)
+ # TODO: read also db user (pulp) and database name (pulpcore)
+ self.staticroot = "/var/lib/pulp/assets"
+ self.uploaddir = "/var/lib/pulp/media/upload"
+
+ def separate_value(line, sep=':'):
+ # an auxiliary method to parse values from lines like:
+ # 'HOST': 'localhost',
+ val = line.split(sep)[1].lstrip().rstrip(',')
+ if (val.startswith('"') and val.endswith('"')) or \
+ (val.startswith('\'') and val.endswith('\'')):
+ val = val[1:-1]
+ return val
+
+ try:
+ for line in open("/etc/pulp/settings.py").read().splitlines():
+ # skip empty lines and lines with comments
+ if not line or line[0] == '#':
+ continue
+ if line.startswith("DATABASES"):
+ databases_scope = True
+ continue
+ # example HOST line to parse:
+ # 'HOST': 'localhost',
+ if databases_scope and match(r"\s+'HOST'\s*:\s+\S+", line):
+ self.dbhost = separate_value(line)
+ if databases_scope and match(r"\s+'PORT'\s*:\s+\S+", line):
+ self.dbport = separate_value(line)
+ if databases_scope and match(r"\s+'PASSWORD'\s*:\s+\S+", line):
+ self.dbpasswd = separate_value(line)
+ # if line contains closing '}' database_scope end
+ if databases_scope and '}' in line:
+ databases_scope = False
+ if line.startswith("STATIC_ROOT = "):
+ self.staticroot = separate_value(line, sep='=')
+ if line.startswith("CHUNKED_UPLOAD_DIR = "):
+ self.uploaddir = separate_value(line, sep='=')
+ except IOError:
+ # fallback when the cfg file is not accessible
+ pass
+ # set the password to os.environ when calling psql commands to prevent
+ # printing it in sos logs
+ # we can't set os.environ directly now: other plugins can overwrite it
+ self.env = {"PGPASSWORD": self.dbpasswd}
+
+ def setup(self):
+ self.parse_settings_config()
+
+ self.add_copy_spec("/etc/pulp/settings.py")
+
+ self.add_cmd_output("rq info -u redis://localhost:6379/8",
+ env={"LC_ALL": "en_US.UTF-8"},
+ suggest_filename="rq_info")
+ self.add_cmd_output("curl -ks https://localhost/pulp/api/v3/status/",
+ suggest_filename="pulp_status")
+ dynaconf_env = {"LC_ALL": "en_US.UTF-8",
+ "PULP_SETTINGS": "/etc/pulp/settings.py",
+ "DJANGO_SETTINGS_MODULE": "pulpcore.app.settings"}
+ self.add_cmd_output("dynaconf list", env=dynaconf_env)
+ for _dir in [self.staticroot, self.uploaddir]:
+ self.add_cmd_output("ls -l %s" % _dir)
+
+ task_days = self.get_option('task-days')
+ for table in ['core_task', 'core_taskgroup',
+ 'core_reservedresourcerecord',
+ 'core_taskreservedresourcerecord',
+ 'core_groupprogressreport', 'core_progressreport']:
+ _query = "select * from %s where pulp_last_updated > NOW() - " \
+ "interval '%s days' order by pulp_last_updated" % \
+ (table, task_days)
+ _cmd = "psql -h %s -p %s -U pulp -d pulpcore -c %s" % \
+ (self.dbhost, self.dbport, quote(_query))
+ self.add_cmd_output(_cmd, env=self.env, suggest_filename=table)
+
+ def postproc(self):
+ # TODO obfuscate from /etc/pulp/settings.py :
+ # SECRET_KEY = "eKfeDkTnvss7p5WFqYdGPWxXfHnsbDBx"
+ # 'PASSWORD': 'tGrag2DmtLqKLTWTQ6U68f6MAhbqZVQj',
+ self.do_path_regex_sub(
+ "/etc/pulp/settings.py",
+ r"(SECRET_KEY\s*=\s*)(.*)",
+ r"\1********")
+ self.do_path_regex_sub(
+ "/etc/pulp/settings.py",
+ r"(PASSWORD\S*\s*:\s*)(.*)",
+ r"\1********")
+
+
+# vim: set et ts=4 sw=4 :
--
2.26.3

View File

@ -1,30 +0,0 @@
From c998ea8c1c950586f91fc9728ee66590740968a5 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Tue, 11 May 2021 15:59:40 +0200
Subject: [PATCH] [saphana] remove redundant unused argument of get_inst_info
get_inst_info does not use and isnt called with 'prefix' argument
Resolves: #2535
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/plugins/saphana.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sos/report/plugins/saphana.py b/sos/report/plugins/saphana.py
index 82c497b4..00e84b59 100644
--- a/sos/report/plugins/saphana.py
+++ b/sos/report/plugins/saphana.py
@@ -51,7 +51,7 @@ class saphana(Plugin, RedHatPlugin):
inst = inst.strip()[-2:]
self.get_inst_info(sid, sidadm, inst)
- def get_inst_info(self, prefix, sid, sidadm, inst):
+ def get_inst_info(self, sid, sidadm, inst):
proc_cmd = 'su - %s -c "sapcontrol -nr %s -function GetProcessList"'
status_fname = "%s_%s_status" % (sid, inst)
self.add_cmd_output(
--
2.26.3

View File

@ -1,50 +0,0 @@
From ee5d9d017b0a1bfeaebee9c21c17e89ef1f909a8 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Mon, 26 Jul 2021 13:30:09 +0200
Subject: [PATCH] [MigrationResults] collect info about conversions and
upgrades
A new tiny plugin independent on leapp and convert2rhel is proposed.
It should collect /etc/migration-results with info about RHEL
conversions and upgrades, whenever the file is present.
Resolves: #2627
Relevant to: rhbz#1959598
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/plugins/migration_results.py | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 sos/report/plugins/migration_results.py
diff --git a/sos/report/plugins/migration_results.py b/sos/report/plugins/migration_results.py
new file mode 100644
index 00000000..b67480ba
--- /dev/null
+++ b/sos/report/plugins/migration_results.py
@@ -0,0 +1,21 @@
+# This file is part of the sos project: https://github.com/sosreport/sos
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# version 2 of the GNU General Public License.
+#
+# See the LICENSE file in the source distribution for further information.
+
+from sos.report.plugins import Plugin, RedHatPlugin
+
+
+class MigrationResults(Plugin, RedHatPlugin):
+
+ short_desc = 'Information about conversions and upgrades'
+
+ plugin_name = 'migration_results'
+ profiles = ('system',)
+
+ files = ('/etc/migration-results',)
+
+# vim: et ts=4 sw=4
--
2.31.1

View File

@ -1,121 +0,0 @@
From 60105e0705f3483b9a3e8e98dafd6f0e1e277ab7 Mon Sep 17 00:00:00 2001
From: Mamatha Inamdar <mamatha4@linux.vnet.ibm.com>
Date: Mon, 19 Apr 2021 16:55:52 +0530
Subject: [PATCH 1/3] [block]:Patch to update block pluging to collect disk
info
This patch is to update block plugin to collect
state of sda
Resolves: #2504
Signed-off-by: Mamatha Inamdar <mamatha4@linux.vnet.ibm.com>
---
sos/report/plugins/block.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/sos/report/plugins/block.py b/sos/report/plugins/block.py
index f93b3231..c959d667 100644
--- a/sos/report/plugins/block.py
+++ b/sos/report/plugins/block.py
@@ -38,7 +38,8 @@ class Block(Plugin, IndependentPlugin):
"/run/blkid/blkid.tab",
"/proc/partitions",
"/proc/diskstats",
- "/sys/block/*/queue/"
+ "/sys/block/*/queue/",
+ "/sys/block/sd*/device/state",
])
cmds = [
--
2.26.3
From c6e0fe5cebd0d9581950db75fa2d234713b7e15a Mon Sep 17 00:00:00 2001
From: Mamatha Inamdar <mamatha4@linux.vnet.ibm.com>
Date: Mon, 26 Apr 2021 23:09:19 +0530
Subject: [PATCH 2/3] [snapper]:Ptach to update snapper plugin to collect
snapper info
This patch is to Introduce snapper plugin to collect
/usr/lib/snapper/ information to check executable
permission for installation-helper command
Resolves: #2504
Signed-off-by: Mamatha Inamdar <mamatha4@linux.vnet.ibm.com>
---
sos/report/plugins/snapper.py | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
create mode 100644 sos/report/plugins/snapper.py
diff --git a/sos/report/plugins/snapper.py b/sos/report/plugins/snapper.py
new file mode 100644
index 00000000..9ef5fec2
--- /dev/null
+++ b/sos/report/plugins/snapper.py
@@ -0,0 +1,27 @@
+# This file is part of the sos project: https://github.com/sosreport/sos
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# version 2 of the GNU General Public License.
+#
+# See the LICENSE file in the source distribution for further information.
+
+from sos.report.plugins import Plugin, IndependentPlugin
+
+
+class Snapper(Plugin, IndependentPlugin):
+
+ short_desc = 'System snapper'
+
+ plugin_name = 'snapper'
+ commands = ("snapper",)
+
+ def setup(self):
+
+ self.add_cmd_output([
+ "ls -la /usr/lib/snapper/",
+ "snapper --version",
+ "snapper list"
+ ])
+
+# vim: set et ts=4 sw=4 :
--
2.26.3
From 61ff5ce165e654a02fe80b9de5ec8e49ed808ec9 Mon Sep 17 00:00:00 2001
From: Mamatha Inamdar <mamatha4@linux.vnet.ibm.com>
Date: Mon, 19 Apr 2021 17:49:08 +0530
Subject: [PATCH 3/3] [kernel]:Patch to update kernel plugin to collect debug
info
This patch is to update kernel plugin to collect
page allocation failure info
Resolves: #2504
Signed-off-by: Mamatha Inamdar <mamatha4@linux.vnet.ibm.com>
---
sos/report/plugins/kernel.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/sos/report/plugins/kernel.py b/sos/report/plugins/kernel.py
index dd7b6939..9d53ca03 100644
--- a/sos/report/plugins/kernel.py
+++ b/sos/report/plugins/kernel.py
@@ -107,6 +107,8 @@ class Kernel(Plugin, IndependentPlugin):
"/var/log/dmesg",
"/sys/fs/pstore",
"/sys/kernel/debug/dynamic_debug/control",
+ "/sys/kernel/debug/extfrag/unusable_index",
+ "/sys/kernel/debug/extfrag/extfrag_index",
clocksource_path + "available_clocksource",
clocksource_path + "current_clocksource"
])
--
2.26.3

View File

@ -1,36 +0,0 @@
From 575ddeddf2f6e1d6a639922f9ccc51c7e46fbe12 Mon Sep 17 00:00:00 2001
From: Seiichi Ikarashi <s.ikarashi@jp.fujitsu.com>
Date: Fri, 14 May 2021 09:49:33 +0900
Subject: [PATCH] [networking] Add nstat command support
As netstat command is being deprecated,
we need nstat as an alternative to "netstat -s".
Signed-off-by: Seiichi Ikarashi <s.ikarashi@fujitsu.com>
---
sos/report/plugins/networking.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/sos/report/plugins/networking.py b/sos/report/plugins/networking.py
index 8b4614bb..acfa027f 100644
--- a/sos/report/plugins/networking.py
+++ b/sos/report/plugins/networking.py
@@ -87,6 +87,7 @@ class Networking(Plugin):
root_symlink="netstat")
self.add_cmd_output([
+ "nstat -zas",
"netstat -s",
"netstat %s -agn" % self.ns_wide,
"ip route show table all",
@@ -198,6 +199,7 @@ class Networking(Plugin):
ns_cmd_prefix + "netstat %s -neopa" % self.ns_wide,
ns_cmd_prefix + "netstat -s",
ns_cmd_prefix + "netstat %s -agn" % self.ns_wide,
+ ns_cmd_prefix + "nstat -zas",
])
ss_cmd = ns_cmd_prefix + "ss -peaonmi"
--
2.26.3

View File

@ -1,78 +0,0 @@
From b27140a9126ea82efb517d60bf1b8455aaf4f5a6 Mon Sep 17 00:00:00 2001
From: Jake Hunsaker <jhunsake@redhat.com>
Date: Fri, 26 Mar 2021 11:12:33 -0400
Subject: [PATCH] [cleaner] Only skip packaging-based files for the IP parser
Files primarily containing package information, e.g. `installed-rpms` or
`installed-debs`, were previously being skipped by all parsers. In
reality, we only need to skip these for the IP parser due to the fact
that version numbers often generate a match for IP address regexes.
This will also fix a problem where if a system was the build host for
certain packages, the hostname would remain in these files as the
hostname parser was previously not checking these files.
Closes: #2400
Resolves: #2464
Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
---
sos/cleaner/obfuscation_archive.py | 10 ----------
sos/cleaner/parsers/ip_parser.py | 16 ++++++++++++++++
2 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/sos/cleaner/obfuscation_archive.py b/sos/cleaner/obfuscation_archive.py
index 981cc05f..84ca30cd 100644
--- a/sos/cleaner/obfuscation_archive.py
+++ b/sos/cleaner/obfuscation_archive.py
@@ -59,20 +59,10 @@ class SoSObfuscationArchive():
Returns: list of files and file regexes
"""
return [
- 'installed-debs',
- 'installed-rpms',
- 'sos_commands/dpkg',
- 'sos_commands/python/pip_list',
- 'sos_commands/rpm',
- 'sos_commands/yum/.*list.*',
- 'sos_commands/snappy/snap_list_--all',
- 'sos_commands/snappy/snap_--version',
- 'sos_commands/vulkan/vulkaninfo',
'sys/firmware',
'sys/fs',
'sys/kernel/debug',
'sys/module',
- 'var/log/.*dnf.*',
r'.*\.tar$', # TODO: support archive unpacking
# Be explicit with these tar matches to avoid matching commands
r'.*\.tar\.xz',
diff --git a/sos/cleaner/parsers/ip_parser.py b/sos/cleaner/parsers/ip_parser.py
index 3ea7f865..08d1cd05 100644
--- a/sos/cleaner/parsers/ip_parser.py
+++ b/sos/cleaner/parsers/ip_parser.py
@@ -24,6 +24,22 @@ class SoSIPParser(SoSCleanerParser):
# don't match package versions recorded in journals
r'.*dnf\[.*\]:'
]
+
+ skip_files = [
+ # skip these as version numbers will frequently look like IP addresses
+ # when using regex matching
+ 'installed-debs',
+ 'installed-rpms',
+ 'sos_commands/dpkg',
+ 'sos_commands/python/pip_list',
+ 'sos_commands/rpm',
+ 'sos_commands/yum/.*list.*',
+ 'sos_commands/snappy/snap_list_--all',
+ 'sos_commands/snappy/snap_--version',
+ 'sos_commands/vulkan/vulkaninfo',
+ 'var/log/.*dnf.*'
+ ]
+
map_file_key = 'ip_map'
prep_map_file = 'sos_commands/networking/ip_-o_addr'
--
2.26.3

View File

@ -1,135 +0,0 @@
From 206d65618f20995b168dcc63090d1e6871450e90 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Wed, 26 May 2021 15:45:26 +0200
Subject: [PATCH] [archive] skip copying SELinux context for /proc and /sys
everytime
A supplement of #1399 fix, now also for adding strings or special
device files.
Also adding a (vendor) test case for it.
Resolves: #2560
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/archive.py | 35 +++++++++++----------
tests/vendor_tests/redhat/rhbz1965001.py | 39 ++++++++++++++++++++++++
2 files changed, 56 insertions(+), 18 deletions(-)
create mode 100644 tests/vendor_tests/redhat/rhbz1965001.py
diff --git a/sos/archive.py b/sos/archive.py
index 4dd31d75..b02b2475 100644
--- a/sos/archive.py
+++ b/sos/archive.py
@@ -326,6 +326,20 @@ class FileCacheArchive(Archive):
return None
return dest
+ def _copy_attributes(self, src, dest):
+ # copy file attributes, skip SELinux xattrs for /sys and /proc
+ try:
+ stat = os.stat(src)
+ if src.startswith("/sys/") or src.startswith("/proc/"):
+ shutil.copymode(src, dest)
+ os.utime(dest, ns=(stat.st_atime_ns, stat.st_mtime_ns))
+ else:
+ shutil.copystat(src, dest)
+ os.chown(dest, stat.st_uid, stat.st_gid)
+ except Exception as e:
+ self.log_debug("caught '%s' setting attributes of '%s'"
+ % (e, dest))
+
def add_file(self, src, dest=None):
with self._path_lock:
if not dest:
@@ -348,18 +362,7 @@ class FileCacheArchive(Archive):
else:
self.log_info("File %s not collected: '%s'" % (src, e))
- # copy file attributes, skip SELinux xattrs for /sys and /proc
- try:
- stat = os.stat(src)
- if src.startswith("/sys/") or src.startswith("/proc/"):
- shutil.copymode(src, dest)
- os.utime(dest, ns=(stat.st_atime_ns, stat.st_mtime_ns))
- else:
- shutil.copystat(src, dest)
- os.chown(dest, stat.st_uid, stat.st_gid)
- except Exception as e:
- self.log_debug("caught '%s' setting attributes of '%s'"
- % (e, dest))
+ self._copy_attributes(src, dest)
file_name = "'%s'" % src
else:
# Open file case: first rewind the file to obtain
@@ -388,11 +391,7 @@ class FileCacheArchive(Archive):
content = content.decode('utf8', 'ignore')
f.write(content)
if os.path.exists(src):
- try:
- shutil.copystat(src, dest)
- except OSError as e:
- self.log_error("Unable to add '%s' to archive: %s" %
- (dest, e))
+ self._copy_attributes(src, dest)
self.log_debug("added string at '%s' to FileCacheArchive '%s'"
% (src, self._archive_root))
@@ -501,7 +500,7 @@ class FileCacheArchive(Archive):
self.log_info("add_node: %s - mknod '%s'" % (msg, dest))
return
raise e
- shutil.copystat(path, dest)
+ self._copy_attributes(path, dest)
def name_max(self):
if 'PC_NAME_MAX' in os.pathconf_names:
diff --git a/tests/vendor_tests/redhat/rhbz1965001.py b/tests/vendor_tests/redhat/rhbz1965001.py
new file mode 100644
index 00000000..aa16ba81
--- /dev/null
+++ b/tests/vendor_tests/redhat/rhbz1965001.py
@@ -0,0 +1,39 @@
+# This file is part of the sos project: https://github.com/sosreport/sos
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# version 2 of the GNU General Public License.
+#
+# See the LICENSE file in the source distribution for further information.
+
+
+import tempfile
+import shutil
+from sos_tests import StageOneReportTest
+
+
+class rhbz1965001(StageOneReportTest):
+ """
+ Copying /proc/sys/vm/{compact_memory,drop_caches} must ignore SELinux
+ context, otherwise an attempt to set the context to files under some
+ directories like /tmp raises an AVC denial, and an ERROR
+ "Unable to add '...' to archive: [Errno 13] Permission denied: '...'
+ is raise.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=1965001
+
+ :avocado: enable
+ :avocado: tags=stageone
+ """
+
+ sos_cmd = '-o system'
+ # it is crucial to run the test case with --tmp-dir=/tmp/... as that is
+ # (an example of) directory exhibiting the relabel permission deny.
+ # /var/tmp directory allows those relabels.
+ #
+ # the directory shouldn't exist at this moment, otherwise
+ # "check to prevent multiple setUp() runs" in sos_tests.py would fail
+ _tmpdir = '/tmp/rhbz1965001_avocado_test'
+
+ def test_no_permission_denied(self):
+ self.assertSosLogNotContains("Permission denied")
--
2.26.3

View File

@ -1,36 +0,0 @@
From 630dfbee936050698d33b59abd1e243c44e50af8 Mon Sep 17 00:00:00 2001
From: Jan Jansky <jjansky@redhat.com>
Date: Thu, 3 Jun 2021 15:04:57 +0200
Subject: [PATCH] [sssd] sssd plugin when sssd-common
We have reports that sssd logs are not
collected, when we investigated
we found associate wants to collect
sssd related logs also when only
sssd-common package is installed.
We got this confirmed by sbr-idm.
Resolves: #2571
Signed-off-by: Jan Jansky <jjansky@redhat.com>
---
sos/report/plugins/sssd.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sos/report/plugins/sssd.py b/sos/report/plugins/sssd.py
index 17933935..6f98e90c 100644
--- a/sos/report/plugins/sssd.py
+++ b/sos/report/plugins/sssd.py
@@ -19,7 +19,7 @@ class Sssd(Plugin):
plugin_name = "sssd"
profiles = ('services', 'security', 'identity')
- packages = ('sssd',)
+ packages = ('sssd', 'sssd-common')
def setup(self):
self.add_copy_spec([
--
2.26.3

File diff suppressed because it is too large Load Diff

View File

@ -1,142 +0,0 @@
From 7e471676fe41dab155a939c60446cc7b7dab773b Mon Sep 17 00:00:00 2001
From: Jake Hunsaker <jhunsake@redhat.com>
Date: Tue, 20 Jul 2021 11:09:29 -0400
Subject: [PATCH] [username parser] Load usernames from `last` for LDAP users
AD/LDAP users are not reported into `lastlog` generally, however they
are reported in `last`. Conversely, `last` does not report local users
who have not logged in but still exist.
In order to obfuscate both kinds of users, we need to look at both
sources.
For this, first allow parsers to specify multiple prep files. Second,
update the username parser to search through all `lastlog` collections
as well as the `last` collection.
Also includes a small update to the username parser's prep loading logic
to ensure we are iterating over each username discovered only once.
Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
---
sos/cleaner/__init__.py | 38 ++++++++++++++------------
sos/cleaner/parsers/__init__.py | 2 +-
sos/cleaner/parsers/username_parser.py | 24 +++++++++++++---
3 files changed, 42 insertions(+), 22 deletions(-)
diff --git a/sos/cleaner/__init__.py b/sos/cleaner/__init__.py
index ca5f93e5..6aadfe79 100644
--- a/sos/cleaner/__init__.py
+++ b/sos/cleaner/__init__.py
@@ -518,23 +518,27 @@ third party.
for _parser in self.parsers:
if not _parser.prep_map_file:
continue
- _arc_path = os.path.join(_arc_name, _parser.prep_map_file)
- try:
- if is_dir:
- _pfile = open(_arc_path, 'r')
- content = _pfile.read()
- else:
- _pfile = archive.extractfile(_arc_path)
- content = _pfile.read().decode('utf-8')
- _pfile.close()
- if isinstance(_parser, SoSUsernameParser):
- _parser.load_usernames_into_map(content)
- for line in content.splitlines():
- if isinstance(_parser, SoSHostnameParser):
- _parser.load_hostname_into_map(line)
- self.obfuscate_line(line)
- except Exception as err:
- self.log_debug("Could not prep %s: %s" % (_arc_path, err))
+ if isinstance(_parser.prep_map_file, str):
+ _parser.prep_map_file = [_parser.prep_map_file]
+ for parse_file in _parser.prep_map_file:
+ _arc_path = os.path.join(_arc_name, parse_file)
+ try:
+ if is_dir:
+ _pfile = open(_arc_path, 'r')
+ content = _pfile.read()
+ else:
+ _pfile = archive.extractfile(_arc_path)
+ content = _pfile.read().decode('utf-8')
+ _pfile.close()
+ if isinstance(_parser, SoSUsernameParser):
+ _parser.load_usernames_into_map(content)
+ for line in content.splitlines():
+ if isinstance(_parser, SoSHostnameParser):
+ _parser.load_hostname_into_map(line)
+ self.obfuscate_line(line)
+ except Exception as err:
+ self.log_debug("Could not prep %s: %s"
+ % (_arc_path, err))
def obfuscate_report(self, report):
"""Individually handle each archive or directory we've discovered by
diff --git a/sos/cleaner/parsers/__init__.py b/sos/cleaner/parsers/__init__.py
index 3076db39..af6e375e 100644
--- a/sos/cleaner/parsers/__init__.py
+++ b/sos/cleaner/parsers/__init__.py
@@ -50,7 +50,7 @@ class SoSCleanerParser():
skip_line_patterns = []
skip_files = []
map_file_key = 'unset'
- prep_map_file = 'unset'
+ prep_map_file = []
def __init__(self, conf_file=None):
# attempt to load previous run data into the mapping for the parser
diff --git a/sos/cleaner/parsers/username_parser.py b/sos/cleaner/parsers/username_parser.py
index 96ce5f0c..b142e371 100644
--- a/sos/cleaner/parsers/username_parser.py
+++ b/sos/cleaner/parsers/username_parser.py
@@ -25,13 +25,24 @@ class SoSUsernameParser(SoSCleanerParser
name = 'Username Parser'
map_file_key = 'username_map'
- prep_map_file = 'sos_commands/login/lastlog_-u_1000-60000'
+ prep_map_file = [
+ 'sos_commands/login/lastlog_-u_1000-60000',
+ 'sos_commands/login/lastlog_-u_60001-65536',
+ 'sos_commands/login/lastlog_-u_65537-4294967295',
+ # AD users will be reported here, but favor the lastlog files since
+ # those will include local users who have not logged in
+ 'sos_commands/login/last'
+ ]
regex_patterns = []
skip_list = [
'core',
'nobody',
'nfsnobody',
- 'root'
+ 'shutdown',
+ 'reboot',
+ 'root',
+ 'ubuntu',
+ 'wtmp'
]
def __init__(self, conf_file=None, opt_names=None):
@@ -44,11 +54,17 @@ class SoSUsernameParser(SoSCleanerParser):
"""Since we don't get the list of usernames from a straight regex for
this parser, we need to override the initial parser prepping here.
"""
+ users = set()
for line in content.splitlines()[1:]:
- user = line.split()[0]
+ try:
+ user = line.split()[0]
+ except Exception:
+ continue
if user in self.skip_list:
continue
- self.mapping.get(user)
+ users.add(user)
+ for each in users:
+ self.mapping.get(each)
def parse_line(self, line):
count = 0
--
2.31.1

View File

@ -1,65 +0,0 @@
From 6d5cbe90e17534d53d7fe42dff4d8ca734acf594 Mon Sep 17 00:00:00 2001
From: Jake Hunsaker <jhunsake@redhat.com>
Date: Tue, 29 Jun 2021 15:49:00 -0400
Subject: [PATCH] [yum] Fix potential traceback when yum history is empty
Like we did in #969 for `dnf`, fix a potential issue where we would
generate a traceback in the plugin when `yum history` is empty.
Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
---
sos/report/plugins/yum.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sos/report/plugins/yum.py b/sos/report/plugins/yum.py
index 54e222df..aec805e6 100644
--- a/sos/report/plugins/yum.py
+++ b/sos/report/plugins/yum.py
@@ -91,7 +91,7 @@ class Yum(Plugin, RedHatPlugin):
# packages installed/erased/updated per transaction
if self.get_option("yum-history-info"):
history = self.exec_cmd("yum history")
- transactions = None
+ transactions = -1
if history['status'] == 0:
for line in history['output'].splitlines():
try:
--
2.31.1
From a7a4ef73faee6cddba36bf670d4a20ab0521c36f Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Wed, 30 Jun 2021 13:10:56 +0200
Subject: [PATCH] [plugins] Set default predicate instead of None for
robustness
Just making the code more robustness, it could be dangerous to
set pred = None and then potentially call log_skipped_cmd that
expects "pred" of SoSPredicate type.
Currently such a call flow can not happen, but it is worth to
make the code more robust for potential future changes.
Resolves: #2601
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/plugins/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sos/report/plugins/__init__.py b/sos/report/plugins/__init__.py
index 6fd1a3b2..b9cd28ed 100644
--- a/sos/report/plugins/__init__.py
+++ b/sos/report/plugins/__init__.py
@@ -1629,7 +1629,7 @@ class Plugin(object):
def _add_cmd_output(self, **kwargs):
"""Internal helper to add a single command to the collection list."""
- pred = kwargs.pop('pred') if 'pred' in kwargs else None
+ pred = kwargs.pop('pred') if 'pred' in kwargs else SoSPredicate(self)
soscmd = SoSCommand(**kwargs)
self._log_debug("packed command: " + soscmd.__str__())
for _skip_cmd in self.skip_commands:
--
2.31.1

View File

@ -0,0 +1,49 @@
From 66ebb8256b1326573cbcb2d134545635dfead3bc Mon Sep 17 00:00:00 2001
From: Jose Castillo <jcastillo@redhat.com>
Date: Sun, 29 Aug 2021 15:35:09 +0200
Subject: [PATCH] [omnipath_client] Ensure opacapture runs only with
allow-system-changes
While omnipath_client plugin is collecting "opacapture",
`depmod -a` command is executed to regenerates some files
under /usr/lib/modules/$kernel.
modules.dep
modules.dep.bin
modules.devname
modules.softdep
modules.symbols
modules.symbols.bin
This patch ensures that the command is only run when
the option --allow-system-changes is used.
Fixes: RHBZ#1998433
Signed-off-by: Jose Castillo <jcastillo@redhat.com>
---
sos/report/plugins/omnipath_client.py | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/sos/report/plugins/omnipath_client.py b/sos/report/plugins/omnipath_client.py
index 1ec01384..4e988c5c 100644
--- a/sos/report/plugins/omnipath_client.py
+++ b/sos/report/plugins/omnipath_client.py
@@ -45,7 +45,12 @@ class OmnipathClient(Plugin, RedHatPlugin):
# rather than storing it somewhere under /var/tmp and copying it via
# add_copy_spec, add it directly to sos_commands/<plugin> dir by
# building a path argument using self.get_cmd_output_path().
- self.add_cmd_output("opacapture %s" % join(self.get_cmd_output_path(),
- "opacapture.tgz"))
+ # This command calls 'depmod -a', so lets make sure we
+ # specified the 'allow-system-changes' option before running it.
+ if self.get_option('allow_system_changes'):
+ self.add_cmd_output("opacapture %s" %
+ join(self.get_cmd_output_path(),
+ "opacapture.tgz"),
+ changes=True)
# vim: set et ts=4 sw=4 :
--
2.31.1

View File

@ -0,0 +1,42 @@
From e2ca3d02f36c0db4efaacfb2c1b7d502f38e371c Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Mon, 30 Aug 2021 10:18:29 +0200
Subject: [PATCH] [unpackaged] deal with recursive loop of symlinks properly
When the plugin processes a recursive loop of symlinks, it currently
hangs in an infinite loop trying to follow the symlinks. Use
pathlib.Path.resolve() method to return the target directly.
Resolves: #2664
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/plugins/unpackaged.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/sos/report/plugins/unpackaged.py b/sos/report/plugins/unpackaged.py
index e5cc6191..9d68077c 100644
--- a/sos/report/plugins/unpackaged.py
+++ b/sos/report/plugins/unpackaged.py
@@ -10,6 +10,7 @@ from sos.report.plugins import Plugin, RedHatPlugin
import os
import stat
+from pathlib import Path
class Unpackaged(Plugin, RedHatPlugin):
@@ -41,8 +42,8 @@ class Unpackaged(Plugin, RedHatPlugin):
for name in files:
path = os.path.join(root, name)
try:
- while stat.S_ISLNK(os.lstat(path).st_mode):
- path = os.path.abspath(os.readlink(path))
+ if stat.S_ISLNK(os.lstat(path).st_mode):
+ path = Path(path).resolve()
except Exception:
continue
file_list.append(os.path.realpath(path))
--
2.31.1

View File

@ -0,0 +1,73 @@
From 7d5157aa5071e3620246e2d4aa80acb2d3ed30f0 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Tue, 28 Sep 2021 22:44:52 +0200
Subject: [PATCH] [networking] prevent iptables-save commands to load nf_tables
kmod
If iptables has built-in nf_tables kmod, then
'ip netns <foo> iptables-save' command requires the kmod which must
be guarded by predicate.
Analogously for ip6tables.
Resolves: #2703
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/plugins/networking.py | 29 ++++++++++++++++++++++++-----
1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/sos/report/plugins/networking.py b/sos/report/plugins/networking.py
index c80ae719..1237f629 100644
--- a/sos/report/plugins/networking.py
+++ b/sos/report/plugins/networking.py
@@ -182,22 +182,41 @@ class Networking(Plugin):
# per-namespace.
self.add_cmd_output("ip netns")
cmd_prefix = "ip netns exec "
- for namespace in self.get_network_namespaces(
- self.get_option("namespace_pattern"),
- self.get_option("namespaces")):
+ namespaces = self.get_network_namespaces(
+ self.get_option("namespace_pattern"),
+ self.get_option("namespaces"))
+ if (namespaces):
+ # 'ip netns exec <foo> iptables-save' must be guarded by nf_tables
+ # kmod, if 'iptables -V' output contains 'nf_tables'
+ # analogously for ip6tables
+ co = {'cmd': 'iptables -V', 'output': 'nf_tables'}
+ co6 = {'cmd': 'ip6tables -V', 'output': 'nf_tables'}
+ iptables_with_nft = (SoSPredicate(self, kmods=['nf_tables'])
+ if self.test_predicate(self,
+ pred=SoSPredicate(self, cmd_outputs=co))
+ else None)
+ ip6tables_with_nft = (SoSPredicate(self, kmods=['nf_tables'])
+ if self.test_predicate(self,
+ pred=SoSPredicate(self, cmd_outputs=co6))
+ else None)
+ for namespace in namespaces:
ns_cmd_prefix = cmd_prefix + namespace + " "
self.add_cmd_output([
ns_cmd_prefix + "ip address show",
ns_cmd_prefix + "ip route show table all",
ns_cmd_prefix + "ip -s -s neigh show",
ns_cmd_prefix + "ip rule list",
- ns_cmd_prefix + "iptables-save",
- ns_cmd_prefix + "ip6tables-save",
ns_cmd_prefix + "netstat %s -neopa" % self.ns_wide,
ns_cmd_prefix + "netstat -s",
ns_cmd_prefix + "netstat %s -agn" % self.ns_wide,
ns_cmd_prefix + "nstat -zas",
], priority=50)
+ self.add_cmd_output([ns_cmd_prefix + "iptables-save"],
+ pred=iptables_with_nft,
+ priority=50)
+ self.add_cmd_output([ns_cmd_prefix + "ip6tables-save"],
+ pred=ip6tables_with_nft,
+ priority=50)
ss_cmd = ns_cmd_prefix + "ss -peaonmi"
# --allow-system-changes is handled directly in predicate
--
2.31.1

View File

@ -0,0 +1,33 @@
From 23e523b6b9784390c7ce2c5af654ab497fb10aaf Mon Sep 17 00:00:00 2001
From: Jose Castillo <jcastillo@redhat.com>
Date: Wed, 8 Sep 2021 09:25:24 +0200
Subject: [PATCH] [kernel] Capture Pressure Stall Information
Kernel 4.20 includes PSI metrics for CPU, memeory and IO.
The feature is enabled after adding "psi=1" as
kernel boot parameter.
The information is captured in files
in the directory /proc/pressure.
Signed-off-by: Jose Castillo <jcastillo@redhat.com>
---
sos/report/plugins/kernel.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sos/report/plugins/kernel.py b/sos/report/plugins/kernel.py
index 8c5e5e11..803f5e30 100644
--- a/sos/report/plugins/kernel.py
+++ b/sos/report/plugins/kernel.py
@@ -112,7 +112,8 @@ class Kernel(Plugin, IndependentPlugin):
"/sys/kernel/debug/extfrag/unusable_index",
"/sys/kernel/debug/extfrag/extfrag_index",
clocksource_path + "available_clocksource",
- clocksource_path + "current_clocksource"
+ clocksource_path + "current_clocksource",
+ "/proc/pressure/"
])
if self.get_option("with-timer"):
--
2.31.1

View File

@ -0,0 +1,151 @@
From 3f0ec3e55e7dcec89dd7fad10084ea7f16178608 Mon Sep 17 00:00:00 2001
From: Salvatore Daniele <sdaniele@redhat.com>
Date: Tue, 7 Sep 2021 13:48:22 -0400
Subject: [PATCH 1/2] [openvswitch] add ovs default OpenFlow protocols
ovs-vsctl list bridge can return an empty 'protocol' column even when
there are OpenFlow protocols in place by default.
ovs-ofctl --version will return the range of supported ofp and should
also be used to ensure flow information for relevant protocol versions
is collected.
OpenFlow default versions:
https://docs.openvswitch.org/en/latest/faq/openflow/
Signed-off-by: Salvatore Daniele <sdaniele@redhat.com>
---
sos/report/plugins/openvswitch.py | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/sos/report/plugins/openvswitch.py b/sos/report/plugins/openvswitch.py
index cd897db2..92cc7259 100644
--- a/sos/report/plugins/openvswitch.py
+++ b/sos/report/plugins/openvswitch.py
@@ -206,6 +206,7 @@ class OpenVSwitch(Plugin):
# Gather additional output for each OVS bridge on the host.
br_list_result = self.collect_cmd_output("ovs-vsctl -t 5 list-br")
+ ofp_ver_result = self.collect_cmd_output("ovs-ofctl -t 5 --version")
if br_list_result['status'] == 0:
for br in br_list_result['output'].splitlines():
self.add_cmd_output([
@@ -232,6 +233,16 @@ class OpenVSwitch(Plugin):
"OpenFlow15"
]
+ # Flow protocol hex identifiers
+ ofp_versions = {
+ 0x01: "OpenFlow10",
+ 0x02: "OpenFlow11",
+ 0x03: "OpenFlow12",
+ 0x04: "OpenFlow13",
+ 0x05: "OpenFlow14",
+ 0x06: "OpenFlow15",
+ }
+
# List protocols currently in use, if any
ovs_list_bridge_cmd = "ovs-vsctl -t 5 list bridge %s" % br
br_info = self.collect_cmd_output(ovs_list_bridge_cmd)
@@ -242,6 +253,21 @@ class OpenVSwitch(Plugin):
br_protos_ln = line[line.find("[")+1:line.find("]")]
br_protos = br_protos_ln.replace('"', '').split(", ")
+ # If 'list bridge' yeilded no protocols, use the range of
+ # protocols enabled by default on this version of ovs.
+ if br_protos == [''] and ofp_ver_result['output']:
+ ofp_version_range = ofp_ver_result['output'].splitlines()
+ ver_range = []
+
+ for line in ofp_version_range:
+ if "OpenFlow versions" in line:
+ v = line.split("OpenFlow versions ")[1].split(":")
+ ver_range = range(int(v[0], 16), int(v[1], 16)+1)
+
+ for protocol in ver_range:
+ if protocol in ofp_versions:
+ br_protos.append(ofp_versions[protocol])
+
# Collect flow information for relevant protocol versions only
for flow in flow_versions:
if flow in br_protos:
--
2.31.1
From 5a006024f730213a726c70e82c5ecd2daf685b2b Mon Sep 17 00:00:00 2001
From: Salvatore Daniele <sdaniele@redhat.com>
Date: Tue, 7 Sep 2021 14:17:19 -0400
Subject: [PATCH 2/2] [openvswitch] add commands for offline analysis
Replicas of ovs-vswitchd and ovsdb-server can be recreated offline
using flow, group, and tlv dumps, and ovs conf.db. This allows for
offline anaylsis and the use of tools such as ovs-appctl
ofproto/trace and ovs-ofctl for debugging.
This patch ensures this information is available in the sos report.
The db is copied rather than collected using ovsdb-client list dump
for two reasons:
ovsdb-client requires interacting with the ovsdb-server which could
take it 'down' for some time, and impact large, busy clusters.
The list-dump is not in a format that can be used to restore the db
offline. All of the information in the list dump is available and more
by copying the db.
Signed-off-by: Salvatore Daniele <sdaniele@redhat.com>
---
sos/report/plugins/openvswitch.py | 12 ++++++++++--
sos/report/plugins/ovn_central.py | 1 +
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/sos/report/plugins/openvswitch.py b/sos/report/plugins/openvswitch.py
index 92cc7259..003596c6 100644
--- a/sos/report/plugins/openvswitch.py
+++ b/sos/report/plugins/openvswitch.py
@@ -75,12 +75,19 @@ class OpenVSwitch(Plugin):
"/run/openvswitch/ovs-monitor-ipsec.pid"
])
+ self.add_copy_spec([
+ path_join('/usr/local/etc/openvswitch', 'conf.db'),
+ path_join('/etc/openvswitch', 'conf.db'),
+ path_join('/var/lib/openvswitch', 'conf.db'),
+ ])
+ ovs_dbdir = environ.get('OVS_DBDIR')
+ if ovs_dbdir:
+ self.add_copy_spec(path_join(ovs_dbdir, 'conf.db'))
+
self.add_cmd_output([
# The '-t 5' adds an upper bound on how long to wait to connect
# to the Open vSwitch server, avoiding hangs when running sos.
"ovs-vsctl -t 5 show",
- # Gather the database.
- "ovsdb-client -f list dump",
# List the contents of important runtime directories
"ls -laZ /run/openvswitch",
"ls -laZ /dev/hugepages/",
@@ -276,6 +283,7 @@ class OpenVSwitch(Plugin):
"ovs-ofctl -O %s dump-groups %s" % (flow, br),
"ovs-ofctl -O %s dump-group-stats %s" % (flow, br),
"ovs-ofctl -O %s dump-flows %s" % (flow, br),
+ "ovs-ofctl -O %s dump-tlv-map %s" % (flow, br),
"ovs-ofctl -O %s dump-ports-desc %s" % (flow, br)
])
diff --git a/sos/report/plugins/ovn_central.py b/sos/report/plugins/ovn_central.py
index a4c483a9..d6647aad 100644
--- a/sos/report/plugins/ovn_central.py
+++ b/sos/report/plugins/ovn_central.py
@@ -138,6 +138,7 @@ class OVNCentral(Plugin):
os.path.join('/usr/local/etc/openvswitch', dbfile),
os.path.join('/etc/openvswitch', dbfile),
os.path.join('/var/lib/openvswitch', dbfile),
+ os.path.join('/var/lib/ovn/etc', dbfile),
])
if ovs_dbdir:
self.add_copy_spec(os.path.join(ovs_dbdir, dbfile))
--
2.31.1

View File

@ -0,0 +1,303 @@
From 2ab8ba3ecbd52e452cc554d515e0782801dcb4b6 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Wed, 8 Sep 2021 15:31:48 +0200
Subject: [PATCH] [firewalld] collect nft rules in firewall_tables only
We collect 'nft list ruleset' in both plugins, while:
- nft is not shipped by firewalld package, so we should not collect
it in firewalld plugin
- running the command requires both nf_tables and nfnetlink kmods, so
we should use both kmods in the predicate
Resolves: #2679
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/plugins/firewall_tables.py | 9 +++++----
sos/report/plugins/firewalld.py | 8 +-------
2 files changed, 6 insertions(+), 11 deletions(-)
diff --git a/sos/report/plugins/firewall_tables.py b/sos/report/plugins/firewall_tables.py
index 56058d3bf9..63a7dddeb5 100644
--- a/sos/report/plugins/firewall_tables.py
+++ b/sos/report/plugins/firewall_tables.py
@@ -40,10 +40,11 @@ def collect_nftables(self):
""" Collects nftables rulesets with 'nft' commands if the modules
are present """
- self.add_cmd_output(
- "nft list ruleset",
- pred=SoSPredicate(self, kmods=['nf_tables'])
- )
+ # collect nftables ruleset
+ nft_pred = SoSPredicate(self,
+ kmods=['nf_tables', 'nfnetlink'],
+ required={'kmods': 'all'})
+ self.add_cmd_output("nft list ruleset", pred=nft_pred, changes=True)
def setup(self):
# collect iptables -t for any existing table, if we can't read the
diff --git a/sos/report/plugins/firewalld.py b/sos/report/plugins/firewalld.py
index ec83527ed7..9401bfd239 100644
--- a/sos/report/plugins/firewalld.py
+++ b/sos/report/plugins/firewalld.py
@@ -9,7 +9,7 @@
#
# See the LICENSE file in the source distribution for further information.
-from sos.report.plugins import Plugin, RedHatPlugin, SoSPredicate
+from sos.report.plugins import Plugin, RedHatPlugin
class FirewallD(Plugin, RedHatPlugin):
@@ -35,12 +35,6 @@ def setup(self):
"/var/log/firewalld",
])
- # collect nftables ruleset
- nft_pred = SoSPredicate(self,
- kmods=['nf_tables', 'nfnetlink'],
- required={'kmods': 'all'})
- self.add_cmd_output("nft list ruleset", pred=nft_pred, changes=True)
-
# use a 10s timeout to workaround dbus problems in
# docker containers.
self.add_cmd_output([
--
2.31.1
From 2a7cf53b61943907dc823cf893530b620a87946c Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Fri, 15 Oct 2021 22:31:36 +0200
Subject: [PATCH 1/3] [report] Use log_skipped_cmd method inside
collect_cmd_output
Also, remove obsolete parameters of the log_skipped_cmd method.
Related: #2724
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/plugins/__init__.py | 26 ++++++++------------------
1 file changed, 8 insertions(+), 18 deletions(-)
diff --git a/sos/report/plugins/__init__.py b/sos/report/plugins/__init__.py
index ec138f83..b60ab5f6 100644
--- a/sos/report/plugins/__init__.py
+++ b/sos/report/plugins/__init__.py
@@ -876,8 +876,7 @@ class Plugin():
return bool(pred)
return False
- def log_skipped_cmd(self, pred, cmd, kmods=False, services=False,
- changes=False):
+ def log_skipped_cmd(self, cmd, pred, changes=False):
"""Log that a command was skipped due to predicate evaluation.
Emit a warning message indicating that a command was skipped due
@@ -887,21 +886,17 @@ class Plugin():
message indicating that the missing data can be collected by using
the "--allow-system-changes" command line option will be included.
- :param pred: The predicate that caused the command to be skipped
- :type pred: ``SoSPredicate``
-
:param cmd: The command that was skipped
:type cmd: ``str``
- :param kmods: Did kernel modules cause the command to be skipped
- :type kmods: ``bool``
-
- :param services: Did services cause the command to be skipped
- :type services: ``bool``
+ :param pred: The predicate that caused the command to be skipped
+ :type pred: ``SoSPredicate``
:param changes: Is the `--allow-system-changes` enabled
:type changes: ``bool``
"""
+ if pred is None:
+ pred = SoSPredicate(self)
msg = "skipped command '%s': %s" % (cmd, pred.report_failure())
if changes:
@@ -1700,9 +1693,7 @@ class Plugin():
self.collect_cmds.append(soscmd)
self._log_info("added cmd output '%s'" % soscmd.cmd)
else:
- self.log_skipped_cmd(pred, soscmd.cmd, kmods=bool(pred.kmods),
- services=bool(pred.services),
- changes=soscmd.changes)
+ self.log_skipped_cmd(soscmd.cmd, pred, changes=soscmd.changes)
def add_cmd_output(self, cmds, suggest_filename=None,
root_symlink=None, timeout=None, stderr=True,
@@ -2112,7 +2103,7 @@ class Plugin():
root_symlink=False, timeout=None,
stderr=True, chroot=True, runat=None, env=None,
binary=False, sizelimit=None, pred=None,
- subdir=None, tags=[]):
+ changes=False, subdir=None, tags=[]):
"""Execute a command and save the output to a file for inclusion in the
report, then return the results for further use by the plugin
@@ -2163,8 +2154,7 @@ class Plugin():
:rtype: ``dict``
"""
if not self.test_predicate(cmd=True, pred=pred):
- self._log_info("skipped cmd output '%s' due to predicate (%s)" %
- (cmd, self.get_predicate(cmd=True, pred=pred)))
+ self.log_skipped_cmd(cmd, pred, changes=changes)
return {
'status': None, # don't match on if result['status'] checks
'output': '',
--
2.31.1
From 6b1bea0ffb1df7f8e5001b06cf25f0741b007ddd Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Fri, 15 Oct 2021 22:34:01 +0200
Subject: [PATCH 2/3] [firewall_tables] call iptables -t <table> based on nft
list
If iptables are not realy in use, calling iptables -t <table>
would load corresponding nft table.
Therefore, call iptables -t only for the tables from "nft list ruleset"
output.
Example: nft list ruleset contains
table ip mangle {
..
}
so we can collect iptable -t mangle -nvL .
The same applies to ip6tables as well.
Resolves: #2724
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/plugins/firewall_tables.py | 29 ++++++++++++++++++++-------
1 file changed, 22 insertions(+), 7 deletions(-)
diff --git a/sos/report/plugins/firewall_tables.py b/sos/report/plugins/firewall_tables.py
index 63a7ddde..ef04d939 100644
--- a/sos/report/plugins/firewall_tables.py
+++ b/sos/report/plugins/firewall_tables.py
@@ -44,26 +44,41 @@ class firewall_tables(Plugin, IndependentPlugin):
nft_pred = SoSPredicate(self,
kmods=['nf_tables', 'nfnetlink'],
required={'kmods': 'all'})
- self.add_cmd_output("nft list ruleset", pred=nft_pred, changes=True)
+ return self.collect_cmd_output("nft list ruleset", pred=nft_pred,
+ changes=True)
def setup(self):
+ # first, collect "nft list ruleset" as collecting commands like
+ # ip6tables -t mangle -nvL
+ # depends on its output
+ # store in nft_ip_tables lists of ip[|6] tables from nft list
+ nft_list = self.collect_nftables()
+ nft_ip_tables = {'ip': [], 'ip6': []}
+ nft_lines = nft_list['output'] if nft_list['status'] == 0 else ''
+ for line in nft_lines.splitlines():
+ words = line.split()[0:3]
+ if len(words) == 3 and words[0] == 'table' and \
+ words[1] in nft_ip_tables.keys():
+ nft_ip_tables[words[1]].append(words[2])
# collect iptables -t for any existing table, if we can't read the
# tables, collect 2 default ones (mangle, filter)
+ # do collect them only when relevant nft list ruleset exists
+ default_ip_tables = "mangle\nfilter\n"
try:
ip_tables_names = open("/proc/net/ip_tables_names").read()
except IOError:
- ip_tables_names = "mangle\nfilter\n"
+ ip_tables_names = default_ip_tables
for table in ip_tables_names.splitlines():
- self.collect_iptable(table)
+ if nft_list['status'] == 0 and table in nft_ip_tables['ip']:
+ self.collect_iptable(table)
# collect the same for ip6tables
try:
ip_tables_names = open("/proc/net/ip6_tables_names").read()
except IOError:
- ip_tables_names = "mangle\nfilter\n"
+ ip_tables_names = default_ip_tables
for table in ip_tables_names.splitlines():
- self.collect_ip6table(table)
-
- self.collect_nftables()
+ if nft_list['status'] == 0 and table in nft_ip_tables['ip6']:
+ self.collect_ip6table(table)
# When iptables is called it will load the modules
# iptables_filter (for kernel <= 3) or
--
2.31.1
From 464bd2d2e83f203e369f2ba7671bbb7da53e06f6 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Sun, 24 Oct 2021 16:00:31 +0200
Subject: [PATCH 3/3] [firewall_tables] Call iptables only when nft ip filter
table exists
iptables -vnxL creates nft 'ip filter' table if it does not exist, hence
we must guard iptables execution by presence of the nft table.
An equivalent logic applies to ip6tables.
Resolves: #2724
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/plugins/firewall_tables.py | 26 ++++++++++++++------------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/sos/report/plugins/firewall_tables.py b/sos/report/plugins/firewall_tables.py
index ef04d939..7eafd60f 100644
--- a/sos/report/plugins/firewall_tables.py
+++ b/sos/report/plugins/firewall_tables.py
@@ -80,19 +80,21 @@ class firewall_tables(Plugin, IndependentPlugin):
if nft_list['status'] == 0 and table in nft_ip_tables['ip6']:
self.collect_ip6table(table)
- # When iptables is called it will load the modules
- # iptables_filter (for kernel <= 3) or
- # nf_tables (for kernel >= 4) if they are not loaded.
+ # When iptables is called it will load:
+ # 1) the modules iptables_filter (for kernel <= 3) or
+ # nf_tables (for kernel >= 4) if they are not loaded.
+ # 2) nft 'ip filter' table will be created
# The same goes for ipv6.
- self.add_cmd_output(
- "iptables -vnxL",
- pred=SoSPredicate(self, kmods=['iptable_filter', 'nf_tables'])
- )
-
- self.add_cmd_output(
- "ip6tables -vnxL",
- pred=SoSPredicate(self, kmods=['ip6table_filter', 'nf_tables'])
- )
+ if nft_list['status'] != 0 or 'filter' in nft_ip_tables['ip']:
+ self.add_cmd_output(
+ "iptables -vnxL",
+ pred=SoSPredicate(self, kmods=['iptable_filter', 'nf_tables'])
+ )
+ if nft_list['status'] != 0 or 'filter' in nft_ip_tables['ip6']:
+ self.add_cmd_output(
+ "ip6tables -vnxL",
+ pred=SoSPredicate(self, kmods=['ip6table_filter', 'nf_tables'])
+ )
self.add_copy_spec([
"/etc/nftables",
--
2.31.1

View File

@ -0,0 +1,48 @@
From b09ed75b09075d86c184b0a63cce9260f2cee4ca Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Mon, 30 Aug 2021 11:27:48 +0200
Subject: [PATCH] [processor] Apply sizelimit to /sys/devices/system/cpu/cpuX
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.
Resolves: #2639
Closes: #2665
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/plugins/processor.py | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/sos/report/plugins/processor.py b/sos/report/plugins/processor.py
index 0ddfd126..2df2dc9a 100644
--- a/sos/report/plugins/processor.py
+++ b/sos/report/plugins/processor.py
@@ -7,6 +7,7 @@
# See the LICENSE file in the source distribution for further information.
from sos.report.plugins import Plugin, IndependentPlugin
+import os
class Processor(Plugin, IndependentPlugin):
@@ -34,7 +35,13 @@ class Processor(Plugin, IndependentPlugin):
self.add_copy_spec([
"/proc/cpuinfo",
"/sys/class/cpuid",
- "/sys/devices/system/cpu"
+ ])
+ # 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.
+ cdirs = self.listdir('/sys/devices/system/cpu')
+ self.add_copy_spec([
+ os.path.join('/sys/devices/system/cpu', cdir) for cdir in cdirs
])
self.add_cmd_output([
--
2.31.1

View File

@ -0,0 +1,69 @@
From 5a9458d318302c1caef862a868745fc8bdf5c741 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Mon, 4 Oct 2021 15:52:36 +0200
Subject: [PATCH] [foreman] Collect puma status and stats
Collect foreman-puma-status and 'pumactl [gc-|]stats', optionally using
SCL (if detected).
Resolves: #2712
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/plugins/foreman.py | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/sos/report/plugins/foreman.py b/sos/report/plugins/foreman.py
index 4539f12b..351794f4 100644
--- a/sos/report/plugins/foreman.py
+++ b/sos/report/plugins/foreman.py
@@ -13,6 +13,7 @@ from sos.report.plugins import (Plugin,
UbuntuPlugin)
from pipes import quote
from re import match
+from sos.utilities import is_executable
class Foreman(Plugin):
@@ -26,7 +27,9 @@ class Foreman(Plugin):
option_list = [
('months', 'number of months for dynflow output', 'fast', 1),
('proxyfeatures', 'collect features of smart proxies', 'slow', False),
+ ('puma-gc', 'collect Puma GC stats', 'fast', False),
]
+ pumactl = 'pumactl %s -S /usr/share/foreman/tmp/puma.state'
def setup(self):
# for external DB, search in /etc/foreman/database.yml for:
@@ -134,6 +138,17 @@ class Foreman(Plugin):
suggest_filename='dynflow_sidekiq_status')
self.add_journal(units="dynflow-sidekiq@*")
+ # Puma stats & status, i.e. foreman-puma-stats, then
+ # pumactl stats -S /usr/share/foreman/tmp/puma.state
+ # and optionally also gc-stats
+ # if on RHEL with Software Collections, wrap the commands accordingly
+ if self.get_option('puma-gc'):
+ self.add_cmd_output(self.pumactl % 'gc-stats',
+ suggest_filename='pumactl_gc-stats')
+ self.add_cmd_output(self.pumactl % 'stats',
+ suggest_filename='pumactl_stats')
+ self.add_cmd_output('/usr/sbin/foreman-puma-status')
+
# collect tables sizes, ordered
_cmd = self.build_query_cmd(
"SELECT table_name, pg_size_pretty(total_bytes) AS total, "
@@ -297,6 +312,10 @@ class RedHatForeman(Foreman, RedHatPlugin):
self.add_file_tags({
'/usr/share/foreman/.ssh/ssh_config': 'ssh_foreman_config',
})
+ # if we are on RHEL7 with scl, wrap some Puma commands by
+ # scl enable tfm 'command'
+ if self.policy.dist_version() == 7 and is_executable('scl'):
+ self.pumactl = "scl enable tfm '%s'" % self.pumactl
super(RedHatForeman, self).setup()
--
2.31.1

View File

@ -0,0 +1,33 @@
From e56b3ea999731b831ebba80cf367e43e65c12b62 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Mon, 4 Oct 2021 14:43:08 +0200
Subject: [PATCH] [report] Overwrite pred=None before refering predicate
attributes
During a dry run, add_journal method sets pred=None whilst log_skipped_cmd
refers to predicate attributes. In that case, replace None predicate
by a default / empty predicate.
Resolves: #2711
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/report/plugins/__init__.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/sos/report/plugins/__init__.py b/sos/report/plugins/__init__.py
index 3c2b64d9..c635b8de 100644
--- a/sos/report/plugins/__init__.py
+++ b/sos/report/plugins/__init__.py
@@ -1693,6 +1693,8 @@ class Plugin():
def _add_cmd_output(self, **kwargs):
"""Internal helper to add a single command to the collection list."""
pred = kwargs.pop('pred') if 'pred' in kwargs else SoSPredicate(self)
+ if pred is None:
+ pred = SoSPredicate(self)
if 'priority' not in kwargs:
kwargs['priority'] = 10
if 'changes' not in kwargs:
--
2.31.1

View File

@ -4,8 +4,8 @@
Summary: A set of tools to gather troubleshooting information from a system
Name: sos
Version: 4.1
Release: 5%{?dist}
Version: 4.2
Release: 2%{?dist}
Group: Applications/System
Source0: https://github.com/sosreport/sos/archive/%{version}/sos-%{version}.tar.gz
Source1: sos-audit-%{auditversion}.tgz
@ -20,28 +20,17 @@ Requires: xz
Conflicts: vdsm < 4.40
Obsoletes: sos-collector
Recommends: python3-pexpect
Patch1: sos-bz1930181-collect-cleaning-consistency.patch
Patch2: sos-bz1935603-manpages-see-also.patch
Patch3: sos-bz1937418-add-cmd-timeout.patch
Patch4: sos-bz1937298-ds-mask-password-in-ldif.patch
Patch5: sos-bz1939963-gather-cups-browsed-logs.patch
Patch6: sos-bz1940502-sssd-memcache-and-logs.patch
Patch7: sos-bz1942276-ibmvNIC-dynamic-debugs.patch
Patch8: sos-bz1956673-pulpcore-plugin.patch
Patch9: sos-bz1959413-saphana-traceback.patch
Patch10: sos-bz1961458-collect-nstat.patch
Patch11: sos-bz1961229-snapper-plugin-and-allocation-failures.patch
Patch12: sos-bz1925419-all-gluster-files.patch
Patch13: sos-bz1964499-obfuscate-fqdn-from-dnf-log.patch
Patch14: sos-bz1886711-enhance-tc-hw-offload.patch
Patch15: sos-bz1965001-fix-avc-copystating-proc-sys.patch
Patch16: sos-bz1967613-sssd-common.patch
Patch17: sos-bz1973675-ocp-cluster-cleaner.patch
Patch18: sos-bz1923938-sos-log-effective-options.patch
Patch19: sos-bz1985986-potential-issues-static-analyse.patch
Patch20: sos-bz1959598-conversions-and-upgrades.patch
Patch21: sos-bz1665947-rhui-plugin.patch
Patch22: sos-bz1985037-cleaner-AD-users-obfuscation.patch
Recommends: python3-requests
Patch1: sos-bz2011413-cpuX-individual-sizelimits.patch
Patch2: sos-bz1998521-unpackaged-recursive-symlink.patch
Patch3: sos-bz1998433-opacapture-under-allow-system-changes.patch
Patch4: sos-bz2002145-kernel-psi.patch
Patch5: sos-bz2001096-iptables-save-under-nf_tables-kmod.patch
Patch6: sos-bz1873185-estimate-only-option.patch
Patch7: sos-bz2005195-iptables-based-on-ntf.patch
Patch8: sos-bz2011506-foreman-puma-status.patch
Patch9: sos-bz2012856-dryrun-uncaught-exception.patch
Patch10: sos-bz2004929-openvswitch-offline-analysis.patch
%description
@ -63,18 +52,6 @@ support technicians and developers.
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%build
%py3_build
@ -141,6 +118,34 @@ of the system. Currently storage and filesystem commands are audited.
%ghost /etc/audit/rules.d/40-sos-storage.rules
%changelog
* Wed Nov 03 2021 Pavel Moravec <pmoravec@redhat.com> = 4.2-2
- [firewall_tables] call iptables -t <table> based on nft
Resolves: bz2005195
- [report] Count with sos_logs and sos_reports in
Resolves: bz1873185
- [foreman] Collect puma status and stats
Resolves: bz2011506
- [report] Overwrite pred=None before refering predicate
Resolves: bz2012856
- [openvswitch] add commands for offline analysis
Resolves: bz2004929
* Wed Oct 06 2021 Pavel Moravec <pmoravec@redhat.com> = 4.2-1
- Rebase on upstream 4.2
Resolves: bz1998133
- [report] Implement --estimate-only
Resolves: bz1873185
- [omnipath_client] Opacapture to run only with allow changes
Resolves: bz1998433
- [unpackaged] deal with recursive loop of symlinks properly
Resolves: bz1998521
- [networking] prevent iptables-save commands to load nf_tables
Resolves: bz2001096
- [kernel] Capture Pressure Stall Information
Resolves: bz2002145
- [processor] Apply sizelimit to /sys/devices/system/cpu/cpuX
Resolves: bz2011413
* Wed Aug 11 2021 Pavel Moravec <pmoravec@redhat.com> = 4.1-5
- [report,collect] unify --map-file arguments
Resolves: bz1923938