aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJake Hunsaker <jhunsake@redhat.com>2020-04-16 10:44:48 -0400
committerJake Hunsaker <jhunsake@redhat.com>2020-04-22 10:58:15 -0400
commita885b3cb61dd4d86848978944a85d56cc7cf46de (patch)
tree45c68ed20e2409f5115493d25b0bab11d6a1b8de
parent0a9ee64550acfc3e792d5b6a9529c866fb833ba5 (diff)
downloadsos-a885b3cb61dd4d86848978944a85d56cc7cf46de.tar.gz
[sosnode|collector] Add support for newer report options
Adds support for newer sos report options like `allow_system_changes` and `plugin_timeout` to collector. These options are version dependent, so they are evaluated on a per-node basis during final sos command construction. Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
-rw-r--r--sos/collector/__init__.py42
-rw-r--r--sos/collector/sosnode.py41
2 files changed, 63 insertions, 20 deletions
diff --git a/sos/collector/__init__.py b/sos/collector/__init__.py
index 2c2d4027..05a9a6c1 100644
--- a/sos/collector/__init__.py
+++ b/sos/collector/__init__.py
@@ -48,6 +48,7 @@ class SoSCollector(SoSComponent):
arg_defaults = {
'alloptions': False,
'all_logs': False,
+ 'allow_system_changes': False,
'become_root': False,
'batch': False,
'case_id': False,
@@ -63,15 +64,18 @@ class SoSCollector(SoSComponent):
'ssh_key': '',
'insecure_sudo': False,
'plugin_options': [],
+ 'plugin_timeout': None,
'list_options': False,
'label': '',
'log_size': 0,
'skip_plugins': [],
'nodes': [],
+ 'no_env_vars': False,
'no_pkg_check': False,
'no_local': False,
'master': '',
'only_plugins': [],
+ 'since': '',
'ssh_port': 22,
'password': False,
'password_per_node': False,
@@ -219,6 +223,11 @@ class SoSCollector(SoSComponent):
help='Enable all sos options')
parser.add_argument('--all-logs', action='store_true',
help='Collect logs regardless of size')
+ parser.add_argument('--allow-system-changes', action='store_true',
+ default=False,
+ help=('Allow sosreport to run commands that may '
+ 'alter system state')
+ )
parser.add_argument('-b', '--become', action='store_true',
dest='become_root',
help='Become root on the remote nodes')
@@ -251,6 +260,8 @@ class SoSCollector(SoSComponent):
help='Use when passwordless sudo is configured')
parser.add_argument('-k', '--plugin-options', action="append",
help='Plugin option as plugname.option=value')
+ parser.add_argument('--plugin-timeout', type=int, default=None,
+ help='Set the global plugin timeout value')
parser.add_argument('-l', '--list-options', action="store_true",
help='List options available for profiles')
parser.add_argument('--label', help='Assign a label to the archives')
@@ -261,6 +272,9 @@ class SoSCollector(SoSComponent):
parser.add_argument('--nodes', action="append",
help='Provide a comma delimited list of nodes, or '
'a regex to match against')
+ parser.add_argument('--no-env-vars', action='store_true',
+ default=False,
+ help='Do not collect env vars in sosreports')
parser.add_argument('--no-pkg-check', action='store_true',
help=('Do not run package checks. Use this '
'with --cluster-type if there are rpm '
@@ -281,6 +295,11 @@ class SoSCollector(SoSComponent):
help='Prompt for password for each node')
parser.add_argument('--preset', default='', required=False,
help='Specify a sos preset to use')
+ parser.add_argument('--since', default=None,
+ help=('Escapes archived files older than date. '
+ 'This will also affect --all-logs. '
+ 'Format: YYYYMMDD[HHMMSS]')
+ )
parser.add_argument('--sos-cmd', dest='sos_opt_line',
help=("Manually specify the commandline options "
"for sosreport on remote nodes")
@@ -713,7 +732,7 @@ class SoSCollector(SoSComponent):
def configure_sos_cmd(self):
"""Configures the sosreport command that is run on the nodes"""
- self.sos_cmd = 'sosreport --batch'
+ self.sos_cmd = 'sosreport --batch '
if self.opts.sos_opt_line:
filt = ['&', '|', '>', '<', ';']
if any(f in self.opts.sos_opt_line for f in filt):
@@ -726,23 +745,26 @@ class SoSCollector(SoSComponent):
self.log_debug("User specified manual sosreport command. "
"Command set to %s" % self.sos_cmd)
return True
+
+ sos_opts = []
+
if self.opts.case_id:
- self.sos_cmd += ' --case-id=%s' % (
- quote(self.opts.case_id))
+ sos_opts.append('--case-id=%s' % (quote(self.opts.case_id)))
if self.opts.alloptions:
- self.sos_cmd += ' --alloptions'
+ sos_opts.append('--alloptions')
if self.opts.all_logs:
- self.sos_cmd += ' --all-logs'
+ sos_opts.append('--all-logs')
if self.opts.verify:
- self.sos_cmd += ' --verify'
+ sos_opts.append('--verify')
if self.opts.log_size:
- self.sos_cmd += (' --log-size=%s' % quote(self.opts.log_size))
+ sos_opts.append(('--log-size=%s' % quote(str(self.opts.log_size))))
if self.opts.sysroot:
- self.sos_cmd += ' -s %s' % quote(self.opts.sysroot)
+ sos_opts.append('-s %s' % quote(self.opts.sysroot))
if self.opts.chroot:
- self.sos_cmd += ' -c %s' % quote(self.opts.chroot)
+ sos_opts.append('-c %s' % quote(self.opts.chroot))
if self.opts.compression_type != 'auto':
- self.sos_cmd += ' -z %s' % (quote(self.opts.compression))
+ sos_opts.append('-z %s' % (quote(self.opts.compression)))
+ self.sos_cmd = self.sos_cmd + ' '.join(sos_opts)
self.log_debug("Initial sos cmd set to %s" % self.sos_cmd)
self.commons['sos_cmd'] = self.sos_cmd
diff --git a/sos/collector/sosnode.py b/sos/collector/sosnode.py
index 9a845e2a..398db303 100644
--- a/sos/collector/sosnode.py
+++ b/sos/collector/sosnode.py
@@ -387,7 +387,7 @@ class SosNode():
def sosreport(self):
"""Run a sosreport on the node, then collect it"""
- self.finalize_sos_cmd()
+ self.sos_cmd = self.finalize_sos_cmd()
self.log_info('Final sos command set to %s' % self.sos_cmd)
try:
path = self.execute_sos_command()
@@ -579,13 +579,32 @@ class SosNode():
def finalize_sos_cmd(self):
"""Use host facts and compare to the cluster type to modify the sos
command if needed"""
- self.sos_cmd = self.sos_info['sos_cmd']
+ sos_cmd = self.sos_info['sos_cmd']
label = self.determine_sos_label()
if label:
- self.sos_cmd = ' %s %s' % (self.sos_cmd, quote(label))
+ self.sos_cmd = '%s %s ' % (sos_cmd, quote(label))
if self.opts.sos_opt_line:
- return True
+ return '%s %s' % (sos_cmd, self.opts.sos_opt_line)
+
+ sos_opts = []
+
+ # sos-3.7 added options
+ if self.check_sos_version('3.7'):
+ if self.opts.plugin_timeout:
+ sos_opts.append('--plugin-timeout=%s'
+ % quote(str(self.opts.plugin_timeout)))
+
+ # sos-3.8 added options
+ if self.check_sos_version('3.8'):
+ if self.opts.allow_system_changes:
+ sos_opts.append('--allow-system-changes')
+
+ if self.opts.no_env_vars:
+ sos_opts.append('--no-env-vars')
+
+ if self.opts.since:
+ sos_opts.append('--since=%s' % quote(self.opts.since))
if self.opts.only_plugins:
plugs = [o for o in self.opts.only_plugins
@@ -596,8 +615,8 @@ class SosNode():
'enabled but do not exist' % not_only)
only = self._fmt_sos_opt_list(self.opts.only_plugins)
if only:
- self.sos_cmd += ' --only-plugins=%s' % quote(only)
- return True
+ sos_opts.append('--only-plugins=%s' % quote(only))
+ return "%s %s" % (sos_cmd, ' '.join(sos_opts))
if self.opts.skip_plugins:
# only run skip-plugins for plugins that are enabled
@@ -609,7 +628,7 @@ class SosNode():
'already not enabled' % not_skip)
skipln = self._fmt_sos_opt_list(skip)
if skipln:
- self.sos_cmd += ' --skip-plugins=%s' % quote(skipln)
+ sos_opts.append('--skip-plugins=%s' % quote(skipln))
if self.opts.enable_plugins:
# only run enable for plugins that are disabled
@@ -622,22 +641,24 @@ class SosNode():
'are already enabled or do not exist' % not_on)
enable = self._fmt_sos_opt_list(opts)
if enable:
- self.sos_cmd += ' --enable-plugins=%s' % quote(enable)
+ sos_opts.append('--enable-plugins=%s' % quote(enable))
if self.opts.plugin_options:
opts = [o for o in self.opts.plugin_options
if self._plugin_exists(o.split('.')[0])
and self._plugin_option_exists(o.split('=')[0])]
if opts:
- self.sos_cmd += ' -k %s' % quote(','.join(o for o in opts))
+ sos_opts.append('-k %s' % quote(','.join(o for o in opts)))
if self.opts.preset:
if self._preset_exists(self.opts.preset):
- self.sos_cmd += ' --preset=%s' % quote(self.opts.preset)
+ sos_opts.append('--preset=%s' % quote(self.opts.preset))
else:
self.log_debug('Requested to enable preset %s but preset does '
'not exist on node' % self.opts.preset)
+ return "%s %s" % (sos_cmd, ' '.join(sos_opts))
+
def determine_sos_label(self):
"""Determine what, if any, label should be added to the sosreport"""
label = ''