diff options
author | Jake Hunsaker <jhunsake@redhat.com> | 2020-04-16 10:44:48 -0400 |
---|---|---|
committer | Jake Hunsaker <jhunsake@redhat.com> | 2020-04-22 10:58:15 -0400 |
commit | a885b3cb61dd4d86848978944a85d56cc7cf46de (patch) | |
tree | 45c68ed20e2409f5115493d25b0bab11d6a1b8de | |
parent | 0a9ee64550acfc3e792d5b6a9529c866fb833ba5 (diff) | |
download | sos-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__.py | 42 | ||||
-rw-r--r-- | sos/collector/sosnode.py | 41 |
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 = '' |