diff options
-rw-r--r-- | man/en/sos-report.1 | 10 | ||||
-rw-r--r-- | sos/collector/__init__.py | 4 | ||||
-rw-r--r-- | sos/report/__init__.py | 4 | ||||
-rw-r--r-- | sos/report/plugins/__init__.py | 24 | ||||
-rw-r--r-- | sos/report/plugins/networking.py | 2 | ||||
-rw-r--r-- | tests/unittests/plugin_tests.py | 2 |
6 files changed, 35 insertions, 11 deletions
diff --git a/man/en/sos-report.1 b/man/en/sos-report.1 index f6bd6c6a..36b337df 100644 --- a/man/en/sos-report.1 +++ b/man/en/sos-report.1 @@ -18,6 +18,7 @@ sos report \- Collect and package diagnostic and support data [--threads threads]\fR [--plugin-timeout TIMEOUT]\fR [--cmd-timeout TIMEOUT]\fR + [--namespaces NAMESPACES]\fR [-s|--sysroot SYSROOT]\fR [-c|--chroot {auto|always|never}\fR [--tmp-dir directory]\fR @@ -289,6 +290,15 @@ 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 \--namespaces NAMESPACES +For plugins that iterate collections over namespaces that exist on the system, +for example the networking plugin collecting `ip` command output for each network +namespace, use this option to limit the number of namespaces that will be collected. + +Use '0' (default) for no limit - all namespaces will be used for collections. + +Note that specific plugins may provide a similar `namespaces` plugin option. If +the plugin option is used, it will override this option. .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 f072287e..57ef074e 100644 --- a/sos/collector/__init__.py +++ b/sos/collector/__init__.py @@ -74,6 +74,7 @@ class SoSCollector(SoSComponent): 'map_file': '/etc/sos/cleaner/default_mapping', 'master': '', 'primary': '', + 'namespaces': None, 'nodes': [], 'no_env_vars': False, 'no_local': False, @@ -281,6 +282,9 @@ class SoSCollector(SoSComponent): sos_grp.add_argument('-o', '--only-plugins', action="extend", default=[], help='Run these plugins only') + sos_grp.add_argument('--namespaces', default=None, + help='limit number of namespaces to collect ' + 'output for - 0 means unlimited') sos_grp.add_argument('--no-env-vars', action='store_true', default=False, help='Do not collect env vars in sosreports') diff --git a/sos/report/__init__.py b/sos/report/__init__.py index 411c4eb0..4e9e5fcb 100644 --- a/sos/report/__init__.py +++ b/sos/report/__init__.py @@ -100,6 +100,7 @@ class SoSReport(SoSComponent): 'skip_commands': [], 'skip_files': [], 'skip_plugins': [], + 'namespaces': None, 'no_report': False, 'no_env_vars': False, 'no_postproc': False, @@ -250,6 +251,9 @@ class SoSReport(SoSComponent): type=int, default=25, help="limit the size of collected logs " "(in MiB)") + report_grp.add_argument("--namespaces", default=None, + help="limit number of namespaces to collect " + "output for - 0 means unlimited") report_grp.add_argument("-n", "--skip-plugins", action="extend", dest="skip_plugins", type=str, help="disable these plugins", default=[]) diff --git a/sos/report/plugins/__init__.py b/sos/report/plugins/__init__.py index 1bc7b6fe..d851ef3e 100644 --- a/sos/report/plugins/__init__.py +++ b/sos/report/plugins/__init__.py @@ -1272,6 +1272,11 @@ class Plugin(object): val = parms['enabled'] if val is not None: return val + else: + # if the value is `None`, use any non-zero default here, + # but still return `None` if no default is given since + # optionname did exist and had a `None` value + return default or val return default @@ -2849,11 +2854,13 @@ class Plugin(object): continue return pids - def get_network_namespaces(self, ns_pattern=None, ns_max=0): + def get_network_namespaces(self, ns_pattern=None, ns_max=None): + if ns_max is None and self.commons['cmdlineopts'].namespaces: + ns_max = self.commons['cmdlineopts'].namespaces return self.filter_namespaces(self.commons['namespaces']['network'], ns_pattern, ns_max) - def filter_namespaces(self, ns_list, ns_pattern=None, ns_max=0): + def filter_namespaces(self, ns_list, ns_pattern=None, ns_max=None): """Filter a list of namespaces by regex pattern or max number of namespaces (options originally present in the networking plugin.) """ @@ -2865,15 +2872,14 @@ class Plugin(object): '(?:%s$)' % '$|'.join(ns_pattern.split()).replace('*', '.*') ) for ns in ns_list: - # if ns_pattern defined, append only namespaces - # matching with pattern + # if ns_pattern defined, skip namespaces not matching the pattern if ns_pattern: - if bool(re.match(pattern, ns)): - out_ns.append(ns) + if not bool(re.match(pattern, ns)): + continue - # if ns_max is defined and ns_pattern is not defined - # remove from out_ns namespaces with higher index than defined - elif ns_max != 0: + # if ns_max is defined at all, limit returned list to that number + # this allows the use of both '0' and `None` to mean unlimited + elif ns_max: out_ns.append(ns) if len(out_ns) == ns_max: self._log_warn("Limiting namespace iteration " diff --git a/sos/report/plugins/networking.py b/sos/report/plugins/networking.py index 632e3cfe..ae6cf0a1 100644 --- a/sos/report/plugins/networking.py +++ b/sos/report/plugins/networking.py @@ -24,7 +24,7 @@ class Networking(Plugin): "collected, namespaces pattern should be separated by whitespace " + "as for example \"eth* ens2\"", "fast", ""), ("namespaces", "Number of namespaces to collect, 0 for unlimited. " + - "Incompatible with the namespace_pattern plugin option", "slow", 0), + "Incompatible with the namespace_pattern option", "slow", None), ("ethtool_namespaces", "Define if ethtool commands should be " + "collected for namespaces", "slow", True), ("eepromdump", "collect 'ethtool -e' for all devices", "slow", False) diff --git a/tests/unittests/plugin_tests.py b/tests/unittests/plugin_tests.py index 1d6ce73a..8dc038cb 100644 --- a/tests/unittests/plugin_tests.py +++ b/tests/unittests/plugin_tests.py @@ -244,7 +244,7 @@ class PluginTests(unittest.TestCase): 'cmdlineopts': MockOptions(), 'devices': {} }) - self.assertEquals(p.get_option("opt"), 0) + self.assertEquals(p.get_option("opt"), None) def test_get_unset_plugin_option_with_default(self): # this shows that even when we pass in a default to get, |