aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins_overview.py3
-rw-r--r--sos/__init__.py2
-rw-r--r--sos/archive.py16
-rw-r--r--sos/cleaner/__init__.py11
-rw-r--r--sos/cleaner/archives/generic.py5
-rw-r--r--sos/cleaner/archives/insights.py3
-rw-r--r--sos/cleaner/archives/sos.py5
-rw-r--r--sos/cleaner/mappings/hostname_map.py7
-rw-r--r--sos/cleaner/mappings/mac_map.py4
-rw-r--r--sos/cleaner/parsers/__init__.py2
-rw-r--r--sos/cleaner/parsers/hostname_parser.py2
-rw-r--r--sos/cleaner/parsers/ip_parser.py2
-rw-r--r--sos/cleaner/parsers/ipv6_parser.py2
-rw-r--r--sos/cleaner/parsers/keyword_parser.py2
-rw-r--r--sos/cleaner/parsers/mac_parser.py5
-rw-r--r--sos/cleaner/parsers/username_parser.py2
-rw-r--r--sos/collector/__init__.py4
-rw-r--r--sos/collector/clusters/__init__.py4
-rw-r--r--sos/collector/clusters/ocp.py2
-rw-r--r--sos/collector/clusters/pacemaker.py2
-rw-r--r--sos/collector/exceptions.py26
-rw-r--r--sos/collector/sosnode.py45
-rw-r--r--sos/collector/transports/__init__.py7
-rw-r--r--sos/collector/transports/control_persist.py4
-rw-r--r--sos/collector/transports/oc.py6
-rw-r--r--sos/collector/transports/saltstack.py2
-rw-r--r--sos/help/__init__.py4
-rw-r--r--sos/options.py1
-rw-r--r--sos/policies/__init__.py6
-rw-r--r--sos/policies/distros/__init__.py10
-rw-r--r--sos/policies/distros/amazon.py8
-rw-r--r--sos/policies/distros/anolis.py8
-rw-r--r--sos/policies/distros/azure.py8
-rw-r--r--sos/policies/distros/circle.py8
-rw-r--r--sos/policies/distros/cos.py6
-rw-r--r--sos/policies/distros/debian.py10
-rw-r--r--sos/policies/distros/opencloudos.py8
-rw-r--r--sos/policies/distros/openeuler.py8
-rw-r--r--sos/policies/distros/redhat.py38
-rw-r--r--sos/policies/distros/rocky.py8
-rw-r--r--sos/policies/distros/suse.py12
-rw-r--r--sos/policies/distros/ubuntu.py14
-rw-r--r--sos/policies/distros/uniontechserver.py8
-rw-r--r--sos/policies/init_systems/systemd.py2
-rw-r--r--sos/policies/package_managers/__init__.py3
-rw-r--r--sos/policies/runtimes/crio.py2
-rw-r--r--sos/report/__init__.py15
-rw-r--r--sos/report/plugins/__init__.py20
-rw-r--r--sos/report/plugins/foreman.py1
-rw-r--r--sos/report/plugins/kubernetes.py67
-rw-r--r--sos/report/reporting.py2
-rw-r--r--sos/utilities.py3
-rw-r--r--tests/report_tests/plugin_tests/logs.py3
-rw-r--r--tests/sos_tests.py25
-rw-r--r--tests/unittests/option_tests.py2
-rw-r--r--tests/unittests/plugin_tests.py3
-rw-r--r--tox.ini21
57 files changed, 276 insertions, 233 deletions
diff --git a/plugins_overview.py b/plugins_overview.py
index 520cf300..96484cb4 100644
--- a/plugins_overview.py
+++ b/plugins_overview.py
@@ -46,7 +46,8 @@ def add_valid_item(dest, item):
# split by comma; add each valid item to the `dest` list
def add_all_items(method, dest, wrapopen=r'\(', wrapclose=r'\)'):
regexp = f"{method}{wrapopen}(.*?){wrapclose}"
- for match in re.findall(regexp, plugcontent, flags=re.MULTILINE | re.DOTALL):
+ for match in re.findall(regexp, plugcontent,
+ flags=re.MULTILINE | re.DOTALL):
# tuple of distros ended by either (class|from|import)
if isinstance(match, tuple):
for item in list(match):
diff --git a/sos/__init__.py b/sos/__init__.py
index 412a8906..209d94d5 100644
--- a/sos/__init__.py
+++ b/sos/__init__.py
@@ -18,11 +18,11 @@ __version__ = "4.7.1"
import os
import sys
+import gettext
from argparse import ArgumentParser
from sos.options import SosListOption
-import gettext
gettext_dir = "/usr/share/locale"
gettext_app = "sos"
gettext.bindtextdomain(gettext_app, gettext_dir)
diff --git a/sos/archive.py b/sos/archive.py
index 2ec60f51..e03b8cd6 100644
--- a/sos/archive.py
+++ b/sos/archive.py
@@ -73,6 +73,9 @@ class Archive(object):
return
self.log.debug(self._format_msg(msg))
+ def name(self):
+ return self._name
+
# this is our contract to clients of the Archive class hierarchy.
# All sub-classes need to implement these methods (or inherit concrete
# implementations from a parent class.
@@ -124,8 +127,7 @@ class Archive(object):
An archive that is subsequently compressed or simply closing an
archive that supports in-line handling. If method is automatic then
the following methods are tried in order: xz, gzip"""
-
- self.close()
+ pass
class FileCacheArchive(Archive):
@@ -167,6 +169,7 @@ class FileCacheArchive(Archive):
return os.path.join(self.sysroot, path)
def _make_leading_paths(self, src, mode=0o700):
+ # pylint: disable=too-many-locals
"""Create leading path components
The standard python `os.makedirs` is insufficient for our
@@ -664,6 +667,9 @@ class FileCacheArchive(Archive):
msg = f"gpg exited with code {r['status']}"
raise Exception(msg)
+ def _build_archive(self, method):
+ pass
+
class TarFileArchive(FileCacheArchive):
""" archive class using python TarFile to create tar archives"""
@@ -673,8 +679,8 @@ class TarFileArchive(FileCacheArchive):
def __init__(self, name, tmpdir, policy, threads, enc_opts, sysroot,
manifest=None):
- super(TarFileArchive, self).__init__(name, tmpdir, policy, threads,
- enc_opts, sysroot, manifest)
+ super().__init__(name, tmpdir, policy, threads,
+ enc_opts, sysroot, manifest)
self._suffix = "tar"
self._archive_name = os.path.join(
tmpdir, self.name() # lgtm [py/init-calls-subclass]
@@ -724,7 +730,7 @@ class TarFileArchive(FileCacheArchive):
def name_max(self):
# GNU Tar format supports unlimited file name length. Just return
# the limit of the underlying FileCacheArchive.
- return super(TarFileArchive, self).name_max()
+ return super().name_max()
def _build_archive(self, method):
if method == 'auto':
diff --git a/sos/cleaner/__init__.py b/sos/cleaner/__init__.py
index 1379abf3..be8d8e03 100644
--- a/sos/cleaner/__init__.py
+++ b/sos/cleaner/__init__.py
@@ -13,13 +13,16 @@ import json
import logging
import os
import shutil
-import sos.cleaner.preppers
import tempfile
import fnmatch
from concurrent.futures import ThreadPoolExecutor
from datetime import datetime
from pwd import getpwuid
+from textwrap import fill
+
+import sos.cleaner.preppers
+
from sos import __version__
from sos.component import SoSComponent
from sos.cleaner.parsers.ip_parser import SoSIPParser
@@ -34,7 +37,6 @@ from sos.cleaner.archives.sos import (SoSReportArchive, SoSReportDirectory,
from sos.cleaner.archives.generic import DataDirArchive, TarballArchive
from sos.cleaner.archives.insights import InsightsArchive
from sos.utilities import get_human_readable, import_module, ImporterHelper
-from textwrap import fill
class SoSCleaner(SoSComponent):
@@ -97,7 +99,7 @@ class SoSCleaner(SoSComponent):
hook_commons=None):
if not in_place:
# we are running `sos clean` directly
- super(SoSCleaner, self).__init__(parser, args, cmdline)
+ super().__init__(parser, args, cmdline)
self.from_cmdline = True
else:
# we are being hooked by either SoSReport or SoSCollector, don't
@@ -665,7 +667,7 @@ third party.
for archive in self.report_paths:
self._prepare_archive_with_prepper(archive, prepper)
- def obfuscate_report(self, archive):
+ def obfuscate_report(self, archive): # pylint: disable=too-many-branches
"""Individually handle each archive or directory we've discovered by
running through each file therein.
@@ -744,6 +746,7 @@ third party.
f"{archive.archive_name}: {err}")
def obfuscate_file(self, filename, short_name=None, arc_name=None):
+ # pylint: disable=too-many-locals
"""Obfuscate and individual file, line by line.
Lines processed, even if no substitutions occur, are then written to a
diff --git a/sos/cleaner/archives/generic.py b/sos/cleaner/archives/generic.py
index 2ce6f09b..1a2d9db5 100644
--- a/sos/cleaner/archives/generic.py
+++ b/sos/cleaner/archives/generic.py
@@ -8,12 +8,11 @@
#
# See the LICENSE file in the source distribution for further information.
-
-from sos.cleaner.archives import SoSObfuscationArchive
-
import os
import tarfile
+from sos.cleaner.archives import SoSObfuscationArchive
+
class DataDirArchive(SoSObfuscationArchive):
"""A plain directory on the filesystem that is not directly associated with
diff --git a/sos/cleaner/archives/insights.py b/sos/cleaner/archives/insights.py
index 872c6b36..391d9d21 100644
--- a/sos/cleaner/archives/insights.py
+++ b/sos/cleaner/archives/insights.py
@@ -8,11 +8,10 @@
#
# See the LICENSE file in the source distribution for further information.
+import tarfile
from sos.cleaner.archives import SoSObfuscationArchive
-import tarfile
-
class InsightsArchive(SoSObfuscationArchive):
"""This class represents archives generated by the insights-client utility
diff --git a/sos/cleaner/archives/sos.py b/sos/cleaner/archives/sos.py
index 4c58d09d..ace71d54 100644
--- a/sos/cleaner/archives/sos.py
+++ b/sos/cleaner/archives/sos.py
@@ -8,12 +8,11 @@
#
# See the LICENSE file in the source distribution for further information.
-
-from sos.cleaner.archives import SoSObfuscationArchive
-
import os
import tarfile
+from sos.cleaner.archives import SoSObfuscationArchive
+
class SoSReportArchive(SoSObfuscationArchive):
"""This is the class representing an sos report, or in other words the
diff --git a/sos/cleaner/mappings/hostname_map.py b/sos/cleaner/mappings/hostname_map.py
index a0a85418..a19fd2a8 100644
--- a/sos/cleaner/mappings/hostname_map.py
+++ b/sos/cleaner/mappings/hostname_map.py
@@ -128,6 +128,7 @@ class SoSHostnameMap(SoSMap):
return False
def get(self, item):
+ # pylint: disable=too-many-branches
prefix = ''
suffix = ''
final = None
@@ -170,21 +171,21 @@ class SoSHostnameMap(SoSMap):
elif not _host_substr and (_test[0].endswith('.') or
item.endswith(_existing)):
# new hostname in known domain
- final = super(SoSHostnameMap, self).get(item)
+ final = super().get(item)
break
elif item.split(_test[0]):
# string that includes existing FQDN obfuscation substring
# so, only obfuscate the FQDN part
try:
itm = item.split(_test[0])[1]
- final = _test[0] + super(SoSHostnameMap, self).get(itm)
+ final = _test[0] + super().get(itm)
break
except Exception:
# fallback to still obfuscating the entire item
pass
if not final:
- final = super(SoSHostnameMap, self).get(item)
+ final = super().get(item)
return prefix + final + suffix
def sanitize_item(self, item):
diff --git a/sos/cleaner/mappings/mac_map.py b/sos/cleaner/mappings/mac_map.py
index c9d38d16..464344ab 100644
--- a/sos/cleaner/mappings/mac_map.py
+++ b/sos/cleaner/mappings/mac_map.py
@@ -52,11 +52,11 @@ class SoSMacMap(SoSMap):
def add(self, item):
item = item.replace('-', ':').lower().strip('=.,').strip()
- return super(SoSMacMap, self).add(item)
+ return super().add(item)
def get(self, item):
item = item.replace('-', ':').lower().strip('=.,').strip()
- return super(SoSMacMap, self).get(item)
+ return super().get(item)
def sanitize_item(self, item):
"""Randomize the device hextets, and append those to our 'vendor'
diff --git a/sos/cleaner/parsers/__init__.py b/sos/cleaner/parsers/__init__.py
index 73dbe656..e89e5a40 100644
--- a/sos/cleaner/parsers/__init__.py
+++ b/sos/cleaner/parsers/__init__.py
@@ -8,6 +8,8 @@
#
# See the LICENSE file in the source distribution for further information.
+# pylint: disable=no-member
+
import re
diff --git a/sos/cleaner/parsers/hostname_parser.py b/sos/cleaner/parsers/hostname_parser.py
index 642aa05d..2252ef46 100644
--- a/sos/cleaner/parsers/hostname_parser.py
+++ b/sos/cleaner/parsers/hostname_parser.py
@@ -23,7 +23,7 @@ class SoSHostnameParser(SoSCleanerParser):
def __init__(self, config, skip_clean_files=[]):
self.mapping = SoSHostnameMap()
- super(SoSHostnameParser, self).__init__(config, skip_clean_files)
+ super().__init__(config, skip_clean_files)
def parse_line(self, line):
"""This will be called for every line in every file we process, so that
diff --git a/sos/cleaner/parsers/ip_parser.py b/sos/cleaner/parsers/ip_parser.py
index f6d464a5..94db75f6 100644
--- a/sos/cleaner/parsers/ip_parser.py
+++ b/sos/cleaner/parsers/ip_parser.py
@@ -46,4 +46,4 @@ class SoSIPParser(SoSCleanerParser):
def __init__(self, config, skip_clean_files=[]):
self.mapping = SoSIPMap()
- super(SoSIPParser, self).__init__(config, skip_clean_files)
+ super().__init__(config, skip_clean_files)
diff --git a/sos/cleaner/parsers/ipv6_parser.py b/sos/cleaner/parsers/ipv6_parser.py
index dfd7282a..9a0da497 100644
--- a/sos/cleaner/parsers/ipv6_parser.py
+++ b/sos/cleaner/parsers/ipv6_parser.py
@@ -37,7 +37,7 @@ class SoSIPv6Parser(SoSCleanerParser):
def __init__(self, config, skip_clean_files=[]):
self.mapping = SoSIPv6Map()
- super(SoSIPv6Parser, self).__init__(config, skip_clean_files)
+ super().__init__(config, skip_clean_files)
def get_map_contents(self):
"""Structure the dataset contents properly so that they can be reloaded
diff --git a/sos/cleaner/parsers/keyword_parser.py b/sos/cleaner/parsers/keyword_parser.py
index 3c6c442b..3d9d636c 100644
--- a/sos/cleaner/parsers/keyword_parser.py
+++ b/sos/cleaner/parsers/keyword_parser.py
@@ -22,7 +22,7 @@ class SoSKeywordParser(SoSCleanerParser):
def __init__(self, config, skip_clean_files=[]):
self.mapping = SoSKeywordMap()
- super(SoSKeywordParser, self).__init__(config, skip_clean_files)
+ super().__init__(config, skip_clean_files)
def _parse_line(self, line):
return line, 0
diff --git a/sos/cleaner/parsers/mac_parser.py b/sos/cleaner/parsers/mac_parser.py
index 78e40c3d..edf40d8a 100644
--- a/sos/cleaner/parsers/mac_parser.py
+++ b/sos/cleaner/parsers/mac_parser.py
@@ -8,10 +8,11 @@
#
# See the LICENSE file in the source distribution for further information.
+import re
+
from sos.cleaner.parsers import SoSCleanerParser
from sos.cleaner.mappings.mac_map import SoSMacMap
-import re
# aa:bb:cc:fe:ff:dd:ee:ff
IPV6_REG_8HEX = (
@@ -51,7 +52,7 @@ class SoSMacParser(SoSCleanerParser):
def __init__(self, config, skip_clean_files=[]):
self.mapping = SoSMacMap()
- super(SoSMacParser, self).__init__(config, skip_clean_files)
+ super().__init__(config, skip_clean_files)
def reduce_mac_match(self, match):
"""Strips away leading and trailing non-alphanum characters from any
diff --git a/sos/cleaner/parsers/username_parser.py b/sos/cleaner/parsers/username_parser.py
index c999ff55..b8825f9e 100644
--- a/sos/cleaner/parsers/username_parser.py
+++ b/sos/cleaner/parsers/username_parser.py
@@ -28,7 +28,7 @@ class SoSUsernameParser(SoSCleanerParser):
def __init__(self, config, skip_clean_files=[]):
self.mapping = SoSUsernameMap()
- super(SoSUsernameParser, self).__init__(config, skip_clean_files)
+ super().__init__(config, skip_clean_files)
def _parse_line(self, line):
return line, 0
diff --git a/sos/collector/__init__.py b/sos/collector/__init__.py
index 4cdb10a2..1a43083c 100644
--- a/sos/collector/__init__.py
+++ b/sos/collector/__init__.py
@@ -8,6 +8,8 @@
#
# See the LICENSE file in the source distribution for further information.
+# pylint: disable=too-many-locals,too-many-branches
+
import fnmatch
import inspect
import json
@@ -145,7 +147,7 @@ class SoSCollector(SoSComponent):
}
def __init__(self, parser, parsed_args, cmdline_args):
- super(SoSCollector, self).__init__(parser, parsed_args, cmdline_args)
+ super().__init__(parser, parsed_args, cmdline_args)
os.umask(0o77)
self.client_list = []
self.node_list = []
diff --git a/sos/collector/clusters/__init__.py b/sos/collector/clusters/__init__.py
index 5a993d85..0dbd4a28 100644
--- a/sos/collector/clusters/__init__.py
+++ b/sos/collector/clusters/__init__.py
@@ -10,9 +10,9 @@
import logging
+from threading import Lock
from sos.options import ClusterOption
from sos.utilities import bold
-from threading import Lock
class Cluster():
@@ -91,7 +91,7 @@ class Cluster():
return cls.__name__.lower()
@classmethod
- def display_help(cls, section):
+ def display_help(cls, section): # pylint: disable=too-many-branches
if cls is Cluster:
cls.display_self_help(section)
return
diff --git a/sos/collector/clusters/ocp.py b/sos/collector/clusters/ocp.py
index cc878770..d4af8747 100644
--- a/sos/collector/clusters/ocp.py
+++ b/sos/collector/clusters/ocp.py
@@ -117,7 +117,7 @@ class ocp(Cluster):
return _res['status'] == 0
def check_enabled(self):
- if super(ocp, self).check_enabled():
+ if super().check_enabled():
return True
self.token = self.get_option('token') or os.getenv('SOSOCPTOKEN', None)
if self.token:
diff --git a/sos/collector/clusters/pacemaker.py b/sos/collector/clusters/pacemaker.py
index 3c25fcaa..6c3ee302 100644
--- a/sos/collector/clusters/pacemaker.py
+++ b/sos/collector/clusters/pacemaker.py
@@ -10,9 +10,9 @@
import re
+from xml.etree import ElementTree
from sos.collector.clusters import Cluster
from sos.utilities import sos_parse_version
-from xml.etree import ElementTree
class pacemaker(Cluster):
diff --git a/sos/collector/exceptions.py b/sos/collector/exceptions.py
index cb1c2314..233c9a9e 100644
--- a/sos/collector/exceptions.py
+++ b/sos/collector/exceptions.py
@@ -14,7 +14,7 @@ class InvalidPasswordException(Exception):
def __init__(self):
message = 'Invalid password provided'
- super(InvalidPasswordException, self).__init__(message)
+ super().__init__(message)
class TimeoutPasswordAuthException(Exception):
@@ -23,7 +23,7 @@ class TimeoutPasswordAuthException(Exception):
def __init__(self):
message = 'Timeout hit while waiting for password validation'
- super(TimeoutPasswordAuthException, self).__init__(message)
+ super().__init__(message)
class PasswordRequestException(Exception):
@@ -32,7 +32,7 @@ class PasswordRequestException(Exception):
def __init__(self):
message = 'Host requested password, but none provided'
- super(PasswordRequestException, self).__init__(message)
+ super().__init__(message)
class AuthPermissionDeniedException(Exception):
@@ -40,7 +40,7 @@ class AuthPermissionDeniedException(Exception):
def __init__(self):
message = 'Permission denied while trying to authenticate'
- super(AuthPermissionDeniedException, self).__init__(message)
+ super().__init__(message)
class ConnectionException(Exception):
@@ -49,7 +49,7 @@ class ConnectionException(Exception):
def __init__(self, address='', port=''):
message = (f"Could not connect to host {address} on specified port "
f"{port}")
- super(ConnectionException, self).__init__(message)
+ super().__init__(message)
class CommandTimeoutException(Exception):
@@ -59,7 +59,7 @@ class CommandTimeoutException(Exception):
message = 'Timeout expired'
if command:
message += f" executing {command}"
- super(CommandTimeoutException, self).__init__(message)
+ super().__init__(message)
class ConnectionTimeoutException(Exception):
@@ -67,7 +67,7 @@ class ConnectionTimeoutException(Exception):
def __init__(self):
message = 'Timeout expires while trying to connect'
- super(ConnectionTimeoutException, self).__init__(message)
+ super().__init__(message)
class ControlSocketMissingException(Exception):
@@ -75,7 +75,7 @@ class ControlSocketMissingException(Exception):
def __init__(self, path=''):
message = f"SSH control socket {path} does not exist"
- super(ControlSocketMissingException, self).__init__(message)
+ super().__init__(message)
class ControlPersistUnsupportedException(Exception):
@@ -83,7 +83,7 @@ class ControlPersistUnsupportedException(Exception):
def __init__(self):
message = 'ControlPersist unsupported by local SSH installation'
- super(ControlPersistUnsupportedException, self).__init__(message)
+ super().__init__(message)
class UnsupportedHostException(Exception):
@@ -91,7 +91,7 @@ class UnsupportedHostException(Exception):
def __init__(self):
message = 'Host did not match any supported distributions'
- super(UnsupportedHostException, self).__init__(message)
+ super().__init__(message)
class InvalidTransportException(Exception):
@@ -101,7 +101,7 @@ class InvalidTransportException(Exception):
def __init__(self, transport=None):
message = ("Connection failed: unknown or unsupported transport "
f"{transport if transport else ''}")
- super(InvalidTransportException, self).__init__(message)
+ super().__init__(message)
class SaltStackMasterUnsupportedException(Exception):
@@ -109,7 +109,7 @@ class SaltStackMasterUnsupportedException(Exception):
def __init__(self):
message = 'Master unsupported by local SaltStack installation'
- super(SaltStackMasterUnsupportedException, self).__init__(message)
+ super().__init__(message)
class JujuNotInstalledException(Exception):
@@ -120,7 +120,7 @@ class JujuNotInstalledException(Exception):
'Juju is not installed, '
'please ensure you have installed juju.'
)
- super(JujuNotInstalledException, self).__init__(message)
+ super().__init__(message)
__all__ = [
diff --git a/sos/collector/sosnode.py b/sos/collector/sosnode.py
index 1efd6e5b..88044617 100644
--- a/sos/collector/sosnode.py
+++ b/sos/collector/sosnode.py
@@ -8,6 +8,8 @@
#
# See the LICENSE file in the source distribution for further information.
+# pylint: disable=too-many-branches
+
import fnmatch
import inspect
import logging
@@ -838,36 +840,25 @@ class SosNode():
def retrieve_sosreport(self):
"""Collect the sosreport archive from the node"""
- if self.sos_path:
- if self.need_sudo or self.opts.become_root:
- try:
- self.make_archive_readable(self.sos_path)
- except Exception:
- self.log_error('Failed to make archive readable')
- return False
- self.log_info(f'Retrieving sos report from {self.address}')
- self.ui_msg('Retrieving sos report...')
+ if self.need_sudo or self.opts.become_root:
try:
- ret = self.retrieve_file(self.sos_path)
- except Exception as err:
- self.log_error(err)
- return False
- if ret:
- self.ui_msg('Successfully collected sos report')
- self.file_list.append(self.sos_path.split('/')[-1])
- return True
- else:
- self.ui_msg('Failed to retrieve sos report')
+ self.make_archive_readable(self.sos_path)
+ except Exception:
+ self.log_error('Failed to make archive readable')
return False
+ self.log_info(f'Retrieving sos report from {self.address}')
+ self.ui_msg('Retrieving sos report...')
+ try:
+ ret = self.retrieve_file(self.sos_path)
+ except Exception as err:
+ self.log_error(err)
+ return False
+ if ret:
+ self.ui_msg('Successfully collected sos report')
+ self.file_list.append(self.sos_path.split('/')[-1])
+ return True
else:
- # sos sometimes fails but still returns a 0 exit code
- if self.stderr.read():
- e = self.stderr.read()
- else:
- e = [x.strip() for x in self.stdout.readlines() if x.strip][-1]
- self.soslog.error(
- f'Failed to run sos report on {self.address}: {e}')
- self.log_error(f'Failed to run sos report. {e}')
+ self.ui_msg('Failed to retrieve sos report')
return False
def remove_sos_archive(self):
diff --git a/sos/collector/transports/__init__.py b/sos/collector/transports/__init__.py
index 92bd9195..b501b4a5 100644
--- a/sos/collector/transports/__init__.py
+++ b/sos/collector/transports/__init__.py
@@ -10,10 +10,11 @@
import inspect
import logging
-import pexpect
import re
-
from shlex import quote
+
+import pexpect
+
from sos.collector.exceptions import (ConnectionException,
CommandTimeoutException)
from sos.utilities import bold
@@ -322,7 +323,7 @@ class RemoteTransport():
:type result: ``pexpect.spawn``
"""
if index == 2:
- if not self.opts.sudo_pw and not self.opt.nopasswd_sudo:
+ if not self.opts.sudo_pw and not self.opts.nopasswd_sudo:
msg = ("Unable to run command: sudo password "
"required but not provided")
self.log_error(msg)
diff --git a/sos/collector/transports/control_persist.py b/sos/collector/transports/control_persist.py
index b8a979bf..839cbe65 100644
--- a/sos/collector/transports/control_persist.py
+++ b/sos/collector/transports/control_persist.py
@@ -10,8 +10,8 @@
import os
-import pexpect
import subprocess
+import pexpect
from sos.collector.transports import RemoteTransport
from sos.collector.exceptions import (InvalidPasswordException,
@@ -69,7 +69,7 @@ class SSHControlPersist(RemoteTransport):
raise ControlPersistUnsupportedException
return True
- def _connect(self, password=''):
+ def _connect(self, password=''): # pylint: disable=too-many-branches
"""
Using ControlPersist, create the initial connection to the node.
diff --git a/sos/collector/transports/oc.py b/sos/collector/transports/oc.py
index e011b0f6..8a45db5a 100644
--- a/sos/collector/transports/oc.py
+++ b/sos/collector/transports/oc.py
@@ -204,7 +204,7 @@ class OCTransport(RemoteTransport):
if cmd.startswith('oc'):
return (f"oc -n {self.project} exec --request-timeout=0 "
f"{self.pod_name} -- chroot /host {cmd}")
- return super(OCTransport, self)._format_cmd_for_exec(cmd)
+ return super()._format_cmd_for_exec(cmd)
def run_command(self, cmd, timeout=180, need_root=False, env=None,
use_shell=False):
@@ -214,8 +214,8 @@ class OCTransport(RemoteTransport):
# since we always execute within a bash shell, force disable use_shell
# to avoid double-quoting
- return super(OCTransport, self).run_command(cmd, timeout, need_root,
- env, use_shell=False)
+ return super().run_command(cmd, timeout, need_root,
+ env, use_shell=False)
def _disconnect(self):
if os.path.exists(self.pod_tmp_conf):
diff --git a/sos/collector/transports/saltstack.py b/sos/collector/transports/saltstack.py
index f0660c8a..70abbdff 100644
--- a/sos/collector/transports/saltstack.py
+++ b/sos/collector/transports/saltstack.py
@@ -39,7 +39,7 @@ class SaltStackMaster(RemoteTransport):
Run a command on the remote host using SaltStack Master.
If the output is json, convert it to a string.
"""
- ret = super(SaltStackMaster, self).run_command(
+ ret = super().run_command(
cmd, timeout, need_root, env, use_shell)
with contextlib.suppress(Exception):
ret['output'] = self._convert_output_json(ret['output'])
diff --git a/sos/help/__init__.py b/sos/help/__init__.py
index c3625087..2de2f388 100644
--- a/sos/help/__init__.py
+++ b/sos/help/__init__.py
@@ -14,11 +14,11 @@ import sys
import os
from collections import OrderedDict
+from textwrap import fill
from sos.component import SoSComponent
from sos.policies import import_policy
from sos.report.plugins import Plugin
from sos.utilities import bold, ImporterHelper
-from textwrap import fill
try:
TERMSIZE = min(os.get_terminal_size().columns, 120)
@@ -41,7 +41,7 @@ class SoSHelper(SoSComponent):
}
def __init__(self, parser, args, cmdline):
- super(SoSHelper, self).__init__(parser, args, cmdline)
+ super().__init__(parser, args, cmdline)
self.topic = self.opts.topic
@classmethod
diff --git a/sos/options.py b/sos/options.py
index 6ec1e4a6..1ef5d1d6 100644
--- a/sos/options.py
+++ b/sos/options.py
@@ -239,6 +239,7 @@ class SoSOptions():
_update_from_section("global", config)
_update_from_section(component, config)
if config.has_section("plugin_options") and hasattr(self, 'plugopts'):
+ # pylint: disable=no-member
for key, val in config.items("plugin_options"):
if not key.split('.')[0] in self.skip_plugins:
self.plugopts.append(key + '=' + val)
diff --git a/sos/policies/__init__.py b/sos/policies/__init__.py
index 52f096ea..7a2997d0 100644
--- a/sos/policies/__init__.py
+++ b/sos/policies/__init__.py
@@ -1,3 +1,4 @@
+
import logging
import os
import platform
@@ -9,6 +10,7 @@ import string
import sys
from pwd import getpwuid
+from textwrap import fill
from sos.presets import (NO_PRESET, GENERIC_PRESETS, PRESETS_PATH,
PresetDefaults, DESC, NOTE, OPTS)
from sos.policies.package_managers import PackageManager
@@ -17,7 +19,6 @@ from sos.utilities import (ImporterHelper, import_module, get_human_readable,
from sos.report.plugins import IndependentPlugin, ExperimentalPlugin
from sos.options import SoSOptions
from sos import _sos as _
-from textwrap import fill
def import_policy(name):
@@ -234,7 +235,7 @@ any third party.
the Policy `name_pattern`
:rtype: ``str``
"""
- name = self.get_local_name().split('.')[0]
+ name = self.get_local_name().split('.')[0] # pylint: disable=no-member
case = self.case_id
label = self.commons['cmdlineopts'].label
date = ''
@@ -252,6 +253,7 @@ any third party.
else:
nstr = self.name_pattern
+ # pylint: disable-next=no-member
return self.sanitize_filename(time.strftime(nstr))
# for some specific binaries like "xz", we need to determine package
diff --git a/sos/policies/distros/__init__.py b/sos/policies/distros/__init__.py
index 6f832bf5..be291e83 100644
--- a/sos/policies/distros/__init__.py
+++ b/sos/policies/distros/__init__.py
@@ -8,6 +8,8 @@
#
# See the LICENSE file in the source distribution for further information.
+# pylint: disable=too-many-branches
+
import os
import re
@@ -91,9 +93,9 @@ class LinuxPolicy(Policy):
def __init__(self, sysroot=None, init=None, probe_runtime=True,
remote_exec=None):
- super(LinuxPolicy, self).__init__(sysroot=sysroot,
- probe_runtime=probe_runtime,
- remote_exec=remote_exec)
+ super().__init__(sysroot=sysroot,
+ probe_runtime=probe_runtime,
+ remote_exec=remote_exec)
if sysroot:
self.sysroot = sysroot
@@ -1018,6 +1020,7 @@ class LinuxPolicy(Policy):
return ''
def restart_sos_container(self):
+ # pylint: disable=no-member
"""Restarts the container created for sos collect if it has stopped.
This is called immediately after create_sos_container() as the command
@@ -1029,6 +1032,7 @@ class LinuxPolicy(Policy):
return f"{self.container_runtime} start {self.sos_container_name}"
def format_container_command(self, cmd):
+ # pylint: disable=no-member
"""Returns the command that allows us to exec into the created
container for sos collect.
diff --git a/sos/policies/distros/amazon.py b/sos/policies/distros/amazon.py
index c19e7e2e..a888079a 100644
--- a/sos/policies/distros/amazon.py
+++ b/sos/policies/distros/amazon.py
@@ -8,8 +8,8 @@
#
# See the LICENSE file in the source distribution for further information.
-from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE
import os
+from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE
class AmazonPolicy(RedHatPolicy):
@@ -20,9 +20,9 @@ class AmazonPolicy(RedHatPolicy):
def __init__(self, sysroot=None, init=None, probe_runtime=True,
remote_exec=None):
- super(AmazonPolicy, self).__init__(sysroot=sysroot, init=init,
- probe_runtime=probe_runtime,
- remote_exec=remote_exec)
+ super().__init__(sysroot=sysroot, init=init,
+ probe_runtime=probe_runtime,
+ remote_exec=remote_exec)
@classmethod
def check(cls, remote=''):
diff --git a/sos/policies/distros/anolis.py b/sos/policies/distros/anolis.py
index 12822a74..79973be7 100644
--- a/sos/policies/distros/anolis.py
+++ b/sos/policies/distros/anolis.py
@@ -6,8 +6,8 @@
#
# See the LICENSE file in the source distribution for further information.
-from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE
import os
+from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE
class AnolisPolicy(RedHatPolicy):
@@ -18,9 +18,9 @@ class AnolisPolicy(RedHatPolicy):
def __init__(self, sysroot=None, init=None, probe_runtime=True,
remote_exec=None):
- super(AnolisPolicy, self).__init__(sysroot=sysroot, init=init,
- probe_runtime=probe_runtime,
- remote_exec=remote_exec)
+ super().__init__(sysroot=sysroot, init=init,
+ probe_runtime=probe_runtime,
+ remote_exec=remote_exec)
@classmethod
def check(cls, remote=''):
diff --git a/sos/policies/distros/azure.py b/sos/policies/distros/azure.py
index b521d1e1..6f0e45ad 100644
--- a/sos/policies/distros/azure.py
+++ b/sos/policies/distros/azure.py
@@ -8,9 +8,9 @@
#
# See the LICENSE file in the source distribution for further information.
+import os
from sos.report.plugins import AzurePlugin
from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE
-import os
class AzurePolicy(RedHatPolicy):
@@ -23,9 +23,9 @@ class AzurePolicy(RedHatPolicy):
def __init__(self, sysroot=None, init=None, probe_runtime=True,
remote_exec=None):
- super(AzurePolicy, self).__init__(sysroot=sysroot, init=init,
- probe_runtime=probe_runtime,
- remote_exec=remote_exec)
+ super().__init__(sysroot=sysroot, init=init,
+ probe_runtime=probe_runtime,
+ remote_exec=remote_exec)
self.valid_subclasses += [AzurePlugin]
@classmethod
diff --git a/sos/policies/distros/circle.py b/sos/policies/distros/circle.py
index 763348dd..8532963b 100644
--- a/sos/policies/distros/circle.py
+++ b/sos/policies/distros/circle.py
@@ -8,8 +8,8 @@
#
# See the LICENSE file in the source distribution for further information.
-from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE
import os
+from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE
class CirclePolicy(RedHatPolicy):
@@ -20,9 +20,9 @@ class CirclePolicy(RedHatPolicy):
def __init__(self, sysroot=None, init=None, probe_runtime=True,
remote_exec=None):
- super(CirclePolicy, self).__init__(sysroot=sysroot, init=init,
- probe_runtime=probe_runtime,
- remote_exec=remote_exec)
+ super().__init__(sysroot=sysroot, init=init,
+ probe_runtime=probe_runtime,
+ remote_exec=remote_exec)
@classmethod
def check(cls, remote=''):
diff --git a/sos/policies/distros/cos.py b/sos/policies/distros/cos.py
index 217c41ce..bf28d03c 100644
--- a/sos/policies/distros/cos.py
+++ b/sos/policies/distros/cos.py
@@ -38,9 +38,9 @@ class CosPolicy(LinuxPolicy):
def __init__(self, sysroot=None, init=None, probe_runtime=True,
remote_exec=None):
- super(CosPolicy, self).__init__(sysroot=sysroot, init=init,
- probe_runtime=probe_runtime,
- remote_exec=remote_exec)
+ super().__init__(sysroot=sysroot, init=init,
+ probe_runtime=probe_runtime,
+ remote_exec=remote_exec)
self.valid_subclasses += [CosPolicy]
@classmethod
diff --git a/sos/policies/distros/debian.py b/sos/policies/distros/debian.py
index fe6bcd1d..26743792 100644
--- a/sos/policies/distros/debian.py
+++ b/sos/policies/distros/debian.py
@@ -6,12 +6,12 @@
#
# See the LICENSE file in the source distribution for further information.
+import os
+
from sos.report.plugins import DebianPlugin
from sos.policies.distros import LinuxPolicy
from sos.policies.package_managers.dpkg import DpkgPackageManager
-import os
-
class DebianPolicy(LinuxPolicy):
distro = "Debian"
@@ -37,9 +37,9 @@ class DebianPolicy(LinuxPolicy):
def __init__(self, sysroot=None, init=None, probe_runtime=True,
remote_exec=None):
- super(DebianPolicy, self).__init__(sysroot=sysroot, init=init,
- probe_runtime=probe_runtime,
- remote_exec=remote_exec)
+ super().__init__(sysroot=sysroot, init=init,
+ probe_runtime=probe_runtime,
+ remote_exec=remote_exec)
self.package_manager = DpkgPackageManager(chroot=self.sysroot,
remote_exec=remote_exec)
self.valid_subclasses += [DebianPlugin]
diff --git a/sos/policies/distros/opencloudos.py b/sos/policies/distros/opencloudos.py
index df510e55..ff3c8af5 100644
--- a/sos/policies/distros/opencloudos.py
+++ b/sos/policies/distros/opencloudos.py
@@ -7,8 +7,8 @@
#
# See the LICENSE file in the source distribution for further information.
-from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE
import os
+from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE
class OpenCloudOSPolicy(RedHatPolicy):
@@ -18,9 +18,9 @@ class OpenCloudOSPolicy(RedHatPolicy):
def __init__(self, sysroot=None, init=None, probe_runtime=True,
remote_exec=None):
- super(OpenCloudOSPolicy, self).__init__(sysroot=sysroot, init=init,
- probe_runtime=probe_runtime,
- remote_exec=remote_exec)
+ super().__init__(sysroot=sysroot, init=init,
+ probe_runtime=probe_runtime,
+ remote_exec=remote_exec)
@classmethod
def check(cls, remote=''):
diff --git a/sos/policies/distros/openeuler.py b/sos/policies/distros/openeuler.py
index 2781cf5d..2c361ec1 100644
--- a/sos/policies/distros/openeuler.py
+++ b/sos/policies/distros/openeuler.py
@@ -6,9 +6,9 @@
#
# See the LICENSE file in the source distribution for further information.
+import os
from sos.report.plugins import OpenEulerPlugin
from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE
-import os
class OpenEulerPolicy(RedHatPolicy):
@@ -18,9 +18,9 @@ class OpenEulerPolicy(RedHatPolicy):
def __init__(self, sysroot=None, init=None, probe_runtime=True,
remote_exec=None):
- super(OpenEulerPolicy, self).__init__(sysroot=sysroot, init=init,
- probe_runtime=probe_runtime,
- remote_exec=remote_exec)
+ super().__init__(sysroot=sysroot, init=init,
+ probe_runtime=probe_runtime,
+ remote_exec=remote_exec)
self.valid_subclasses += [OpenEulerPlugin]
diff --git a/sos/policies/distros/redhat.py b/sos/policies/distros/redhat.py
index a72fe6d0..edea151e 100644
--- a/sos/policies/distros/redhat.py
+++ b/sos/policies/distros/redhat.py
@@ -57,9 +57,9 @@ class RedHatPolicy(LinuxPolicy):
def __init__(self, sysroot=None, init=None, probe_runtime=True,
remote_exec=None):
- super(RedHatPolicy, self).__init__(sysroot=sysroot, init=init,
- probe_runtime=probe_runtime,
- remote_exec=remote_exec)
+ super().__init__(sysroot=sysroot, init=init,
+ probe_runtime=probe_runtime,
+ remote_exec=remote_exec)
self.usrmove = False
self.package_manager = MultiPackageManager(
@@ -235,9 +235,9 @@ support representative.
def __init__(self, sysroot=None, init=None, probe_runtime=True,
remote_exec=None):
- super(RHELPolicy, self).__init__(sysroot=sysroot, init=init,
- probe_runtime=probe_runtime,
- remote_exec=remote_exec)
+ super().__init__(sysroot=sysroot, init=init,
+ probe_runtime=probe_runtime,
+ remote_exec=remote_exec)
self.register_presets(RHEL_PRESETS)
@classmethod
@@ -354,13 +354,13 @@ support representative.
fname = os.path.join(self.upload_directory, fname)
return fname
- def upload_sftp(self):
+ def upload_sftp(self): # pylint: disable=too-many-branches
"""Override the base upload_sftp to allow for setting an on-demand
generated anonymous login for the RH SFTP server if a username and
password are not given
"""
if RH_SFTP_HOST.split('//')[1] not in self.get_upload_url():
- return super(RHELPolicy, self).upload_sftp()
+ return super().upload_sftp()
if not REQUESTS_LOADED:
raise Exception("python3-requests is not installed and is required"
@@ -426,8 +426,7 @@ support representative.
f"{anon.status_code}): {anon.json()}"
)
if _user and _token:
- return super(RHELPolicy, self).upload_sftp(user=_user,
- password=_token)
+ return super().upload_sftp(user=_user, password=_token)
raise Exception("Could not retrieve valid or anonymous credentials")
def upload_archive(self, archive):
@@ -439,7 +438,7 @@ support representative.
(not self.get_upload_user() or
not self.get_upload_password()):
self.upload_url = RH_SFTP_HOST
- uploaded = super(RHELPolicy, self).upload_archive(archive)
+ uploaded = super().upload_archive(archive)
except Exception as e:
uploaded = False
if not self.upload_url.startswith(RH_API_HOST):
@@ -450,7 +449,7 @@ support representative.
f"{e}. Trying {RH_SFTP_HOST}")
)
self.upload_url = RH_SFTP_HOST
- uploaded = super(RHELPolicy, self).upload_archive(archive)
+ uploaded = super().upload_archive(archive)
return uploaded
def dist_version(self):
@@ -537,9 +536,9 @@ support representative.
def __init__(self, sysroot=None, init=None, probe_runtime=True,
remote_exec=None):
- super(RedHatCoreOSPolicy, self).__init__(sysroot=sysroot, init=init,
- probe_runtime=probe_runtime,
- remote_exec=remote_exec)
+ super().__init__(sysroot=sysroot, init=init,
+ probe_runtime=probe_runtime,
+ remote_exec=remote_exec)
@classmethod
def check(cls, remote=''):
@@ -608,9 +607,9 @@ class FedoraPolicy(RedHatPolicy):
def __init__(self, sysroot=None, init=None, probe_runtime=True,
remote_exec=None):
- super(FedoraPolicy, self).__init__(sysroot=sysroot, init=init,
- probe_runtime=probe_runtime,
- remote_exec=remote_exec)
+ super().__init__(sysroot=sysroot, init=init,
+ probe_runtime=probe_runtime,
+ remote_exec=remote_exec)
@classmethod
def check(cls, remote=''):
@@ -624,7 +623,8 @@ class FedoraPolicy(RedHatPolicy):
def fedora_version(self):
pkg = self.pkg_by_name("fedora-release") or \
- self.all_pkgs_by_name_regex("fedora-release-.*")[-1]
+ self.package_manager.all_pkgs_by_name_regex(
+ "fedora-release-.*")[-1]
return int(pkg["version"])
# vim: set et ts=4 sw=4 :
diff --git a/sos/policies/distros/rocky.py b/sos/policies/distros/rocky.py
index ce442540..c51f535c 100644
--- a/sos/policies/distros/rocky.py
+++ b/sos/policies/distros/rocky.py
@@ -8,8 +8,8 @@
#
# See the LICENSE file in the source distribution for further information.
-from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE
import os
+from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE
class RockyPolicy(RedHatPolicy):
@@ -22,9 +22,9 @@ class RockyPolicy(RedHatPolicy):
def __init__(self, sysroot=None, init=None, probe_runtime=True,
remote_exec=None):
- super(RockyPolicy, self).__init__(sysroot=sysroot, init=init,
- probe_runtime=probe_runtime,
- remote_exec=remote_exec)
+ super().__init__(sysroot=sysroot, init=init,
+ probe_runtime=probe_runtime,
+ remote_exec=remote_exec)
@classmethod
def check(cls, remote=''):
diff --git a/sos/policies/distros/suse.py b/sos/policies/distros/suse.py
index 9422daf8..8c7900e5 100644
--- a/sos/policies/distros/suse.py
+++ b/sos/policies/distros/suse.py
@@ -24,9 +24,9 @@ class SuSEPolicy(LinuxPolicy):
def __init__(self, sysroot=None, init=None, probe_runtime=True,
remote_exec=None):
- super(SuSEPolicy, self).__init__(sysroot=sysroot, init=init,
- probe_runtime=probe_runtime,
- remote_exec=remote_exec)
+ super().__init__(sysroot=sysroot, init=init,
+ probe_runtime=probe_runtime,
+ remote_exec=remote_exec)
self.valid_subclasses += [SuSEPlugin, RedHatPlugin]
self.usrmove = False
@@ -77,9 +77,9 @@ No changes will be made to system configuration.
def __init__(self, sysroot=None, init=None, probe_runtime=True,
remote_exec=None):
- super(OpenSuSEPolicy, self).__init__(sysroot=sysroot, init=init,
- probe_runtime=probe_runtime,
- remote_exec=remote_exec)
+ super().__init__(sysroot=sysroot, init=init,
+ probe_runtime=probe_runtime,
+ remote_exec=remote_exec)
@classmethod
def check(cls, remote):
diff --git a/sos/policies/distros/ubuntu.py b/sos/policies/distros/ubuntu.py
index 671187fe..8d63c972 100644
--- a/sos/policies/distros/ubuntu.py
+++ b/sos/policies/distros/ubuntu.py
@@ -6,6 +6,8 @@
#
# See the LICENSE file in the source distribution for further information.
+import os
+
from sos.report.plugins import UbuntuPlugin
from sos.policies.distros.debian import DebianPolicy
@@ -13,8 +15,6 @@ from sos.policies.package_managers.snap import SnapPackageManager
from sos.policies.package_managers.dpkg import DpkgPackageManager
from sos.policies.package_managers import MultiPackageManager
-import os
-
class UbuntuPolicy(DebianPolicy):
distro = "Ubuntu"
@@ -32,9 +32,9 @@ class UbuntuPolicy(DebianPolicy):
def __init__(self, sysroot=None, init=None, probe_runtime=True,
remote_exec=None):
- super(UbuntuPolicy, self).__init__(sysroot=sysroot, init=init,
- probe_runtime=probe_runtime,
- remote_exec=remote_exec)
+ super().__init__(sysroot=sysroot, init=init,
+ probe_runtime=probe_runtime,
+ remote_exec=remote_exec)
self.package_manager = MultiPackageManager(
primary=DpkgPackageManager,
@@ -83,7 +83,7 @@ class UbuntuPolicy(DebianPolicy):
if self.upload_url.startswith(self._upload_url):
return (self._upload_user, self._upload_password)
else:
- return super(UbuntuPolicy, self).get_upload_https_auth()
+ return super().get_upload_https_auth()
def get_upload_url_string(self):
if self.upload_url.startswith(self._upload_url):
@@ -97,6 +97,6 @@ class UbuntuPolicy(DebianPolicy):
return self._upload_url
fname = os.path.basename(self.upload_archive_name)
return self._upload_url + fname
- return super(UbuntuPolicy, self).get_upload_url()
+ return super().get_upload_url()
# vim: set et ts=4 sw=4 :
diff --git a/sos/policies/distros/uniontechserver.py b/sos/policies/distros/uniontechserver.py
index 15a8819b..29163dbf 100644
--- a/sos/policies/distros/uniontechserver.py
+++ b/sos/policies/distros/uniontechserver.py
@@ -6,8 +6,8 @@
#
# See the LICENSE file in the source distribution for further information.
-from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE
import os
+from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE
class UnionTechPolicy(RedHatPolicy):
@@ -17,9 +17,9 @@ class UnionTechPolicy(RedHatPolicy):
def __init__(self, sysroot=None, init=None, probe_runtime=True,
remote_exec=None):
- super(UnionTechPolicy, self).__init__(sysroot=sysroot, init=init,
- probe_runtime=probe_runtime,
- remote_exec=remote_exec)
+ super().__init__(sysroot=sysroot, init=init,
+ probe_runtime=probe_runtime,
+ remote_exec=remote_exec)
@classmethod
def check(cls, remote=''):
diff --git a/sos/policies/init_systems/systemd.py b/sos/policies/init_systems/systemd.py
index 0f49197c..b76bcdf9 100644
--- a/sos/policies/init_systems/systemd.py
+++ b/sos/policies/init_systems/systemd.py
@@ -16,7 +16,7 @@ class SystemdInit(InitSystem):
"""InitSystem abstraction for SystemD systems"""
def __init__(self, chroot=None):
- super(SystemdInit, self).__init__(
+ super().__init__(
init_cmd='systemctl',
list_cmd='list-unit-files --type=service',
query_cmd='status',
diff --git a/sos/policies/package_managers/__init__.py b/sos/policies/package_managers/__init__.py
index 594ca827..acea40b0 100644
--- a/sos/policies/package_managers/__init__.py
+++ b/sos/policies/package_managers/__init__.py
@@ -304,8 +304,7 @@ class MultiPackageManager(PackageManager):
"""
def __init__(self, primary, fallbacks, chroot=None, remote_exec=None):
- super(MultiPackageManager, self).__init__(chroot=chroot,
- remote_exec=remote_exec)
+ super().__init__(chroot=chroot, remote_exec=remote_exec)
if not issubclass(primary, PackageManager):
raise Exception(
diff --git a/sos/policies/runtimes/crio.py b/sos/policies/runtimes/crio.py
index d7726f8b..085a5ecd 100644
--- a/sos/policies/runtimes/crio.py
+++ b/sos/policies/runtimes/crio.py
@@ -9,9 +9,9 @@
# See the LICENSE file in the source distribution for further information.
import json
+from shlex import quote
from sos.policies.runtimes import ContainerRuntime
from sos.utilities import sos_get_command_output
-from shlex import quote
class CrioContainerRuntime(ContainerRuntime):
diff --git a/sos/report/__init__.py b/sos/report/__init__.py
index cf3d0d76..0edbdead 100644
--- a/sos/report/__init__.py
+++ b/sos/report/__init__.py
@@ -8,22 +8,25 @@
#
# See the LICENSE file in the source distribution for further information.
+# pylint: disable=too-many-branches,too-many-locals
+
import sys
import traceback
import os
import errno
import logging
-
+import hashlib
+import pdb
from datetime import datetime
import glob
+
+from shutil import rmtree
+from concurrent.futures import ThreadPoolExecutor, TimeoutError
+
import sos.report.plugins
from sos.utilities import (ImporterHelper, SoSTimeoutError, bold,
sos_get_command_output, TIMEOUT_DEFAULT, listdir,
is_executable)
-from shutil import rmtree
-import hashlib
-from concurrent.futures import ThreadPoolExecutor, TimeoutError
-import pdb
from sos import _sos as _
from sos import __version__
@@ -141,7 +144,7 @@ class SoSReport(SoSComponent):
}
def __init__(self, parser, args, cmdline):
- super(SoSReport, self).__init__(parser, args, cmdline)
+ super().__init__(parser, args, cmdline)
self.loaded_plugins = []
self.skipped_plugins = []
self.all_options = []
diff --git a/sos/report/plugins/__init__.py b/sos/report/plugins/__init__.py
index 504b0f30..a7978b58 100644
--- a/sos/report/plugins/__init__.py
+++ b/sos/report/plugins/__init__.py
@@ -8,15 +8,10 @@
#
# See the LICENSE file in the source distribution for further information.
-""" This exports methods available for use by plugins for sos """
+# pylint: disable=too-many-locals,too-many-branches
-from sos.utilities import (sos_get_command_output, import_module, grep,
- fileobj, tail, is_executable, TIMEOUT_DEFAULT,
- path_exists, path_isdir, path_isfile, path_islink,
- listdir, path_join, bold, file_is_binary,
- recursive_dict_values_by_key)
+""" This exports methods available for use by plugins for sos """
-from sos.archive import P_FILE, P_LINK
import contextlib
import os
import glob
@@ -30,6 +25,14 @@ import textwrap
from datetime import datetime
+from sos.utilities import (sos_get_command_output, import_module, grep,
+ fileobj, tail, is_executable, TIMEOUT_DEFAULT,
+ path_exists, path_isdir, path_isfile, path_islink,
+ listdir, path_join, bold, file_is_binary,
+ recursive_dict_values_by_key)
+
+from sos.archive import P_FILE, P_LINK
+
def regex_findall(regex, fname):
"""Return a list of all non overlapping matches in the string(s)"""
@@ -542,6 +545,7 @@ class Plugin():
# Default predicates
predicate = None
cmd_predicate = None
+ short_desc = "<no description available>"
def __init__(self, commons):
@@ -818,6 +822,7 @@ class Plugin():
)
if hasattr(cls, 'verify_packages'):
+ # pylint: disable=no-member
section.add_text(
"\nVerfies packages (when using --verify): "
f"{', '.join(pkg for pkg in cls.verify_packages)}",
@@ -1977,6 +1982,7 @@ class Plugin():
subdir=subdir)
def _add_cmd_output(self, **kwargs):
+ # pylint: disable=no-member
"""Internal helper to add a single command to the collection list."""
pred = kwargs.pop('pred') if 'pred' in kwargs else SoSPredicate(self)
if 'priority' not in kwargs:
diff --git a/sos/report/plugins/foreman.py b/sos/report/plugins/foreman.py
index 5ca4439e..2adc6313 100644
--- a/sos/report/plugins/foreman.py
+++ b/sos/report/plugins/foreman.py
@@ -182,6 +182,7 @@ class Foreman(Plugin):
self.collect_proxies()
def collect_foreman_db(self):
+ # pylint: disable=too-many-locals
""" Collect foreman db and dynflow data """
days = f'{self.get_option("days")} days'
interval = quote(days)
diff --git a/sos/report/plugins/kubernetes.py b/sos/report/plugins/kubernetes.py
index eb3e3747..66cbf810 100644
--- a/sos/report/plugins/kubernetes.py
+++ b/sos/report/plugins/kubernetes.py
@@ -11,9 +11,9 @@
from fnmatch import translate
import re
+import json
from sos.report.plugins import (Plugin, RedHatPlugin, DebianPlugin,
UbuntuPlugin, PluginOpt)
-import json
class Kubernetes(Plugin):
@@ -191,37 +191,40 @@ class Kubernetes(Plugin):
)
if self.get_option('podlogs'):
- k_cmd = f'{self.kube_cmd} get -o json {knsp}'
- ret = self.exec_cmd(f'{k_cmd} pods')
- if ret['status'] == 0:
- pods = json.loads(ret['output'])
- # allow shell-style regex
- reg = (translate(self.get_option('podlogs-filter')) if
- self.get_option('podlogs-filter') else None)
- for pod in pods["items"]:
- if reg and not re.match(reg, pod["metadata"]["name"]):
- continue
- _subdir = (f'cluster-info/'
- f'{pod["metadata"]["namespace"]}/podlogs/'
- f'{pod["metadata"]["name"]}')
- if "containers" in pod["spec"]:
- for cont in pod["spec"]["containers"]:
- pod_name = pod["metadata"]["name"]
- cont_name = cont["name"]
- self.add_cmd_output(
- f'{self.kube_cmd} {knsp} logs '
- f'{pod_name} -c {cont_name}',
- subdir=_subdir
- )
- if "initContainers" in pod["spec"]:
- for cont in pod["spec"]["initContainers"]:
- pod_name = pod["metadata"]["name"]
- cont_name = cont["name"]
- self.add_cmd_output(
- f'{self.kube_cmd} {knsp} logs '
- f'{pod_name} -c {cont_name}',
- subdir=_subdir
- )
+ self._get_pod_logs(knsp)
+
+ def _get_pod_logs(self, namespace):
+ k_cmd = f'{self.kube_cmd} get -o json {namespace}'
+ ret = self.exec_cmd(f'{k_cmd} pods')
+ if ret['status'] == 0:
+ pods = json.loads(ret['output'])
+ # allow shell-style regex
+ reg = (translate(self.get_option('podlogs-filter')) if
+ self.get_option('podlogs-filter') else None)
+ for pod in pods["items"]:
+ if reg and not re.match(reg, pod["metadata"]["name"]):
+ continue
+ _subdir = (f'cluster-info/'
+ f'{pod["metadata"]["namespace"]}/podlogs/'
+ f'{pod["metadata"]["name"]}')
+ if "containers" in pod["spec"]:
+ for cont in pod["spec"]["containers"]:
+ pod_name = pod["metadata"]["name"]
+ cont_name = cont["name"]
+ self.add_cmd_output(
+ f'{self.kube_cmd} {namespace} logs '
+ f'{pod_name} -c {cont_name}',
+ subdir=_subdir
+ )
+ if "initContainers" in pod["spec"]:
+ for cont in pod["spec"]["initContainers"]:
+ pod_name = pod["metadata"]["name"]
+ cont_name = cont["name"]
+ self.add_cmd_output(
+ f'{self.kube_cmd} {namespace} logs '
+ f'{pod_name} -c {cont_name}',
+ subdir=_subdir
+ )
def collect_all_resources(self):
""" Collect details about all resources """
diff --git a/sos/report/reporting.py b/sos/report/reporting.py
index fc7b56a5..c08b6151 100644
--- a/sos/report/reporting.py
+++ b/sos/report/reporting.py
@@ -21,6 +21,8 @@ except ImportError:
class Node(object):
+ data = {}
+
def __str__(self):
return json.dumps(self.data)
diff --git a/sos/utilities.py b/sos/utilities.py
index 8f165ab4..c0a93ada 100644
--- a/sos/utilities.py
+++ b/sos/utilities.py
@@ -219,6 +219,7 @@ def sos_get_command_output(command, timeout=TIMEOUT_DEFAULT, stderr=False,
chroot=None, chdir=None, env=None, foreground=False,
binary=False, sizelimit=None, poller=None,
to_file=False):
+ # pylint: disable=too-many-locals,too-many-branches
"""Execute a command and return a dictionary of status and output,
optionally changing root or current working directory before
executing command.
@@ -498,7 +499,7 @@ class AsyncReader(threading.Thread):
"""
def __init__(self, channel, sizelimit, binary):
- super(AsyncReader, self).__init__()
+ super().__init__()
self.chan = channel
self.binary = binary
self.chunksize = 2048
diff --git a/tests/report_tests/plugin_tests/logs.py b/tests/report_tests/plugin_tests/logs.py
index c3811b3f..2f4841fb 100644
--- a/tests/report_tests/plugin_tests/logs.py
+++ b/tests/report_tests/plugin_tests/logs.py
@@ -9,10 +9,9 @@
import random
import os
-
-from sos_tests import StageOneReportTest, StageTwoReportTest
from string import ascii_uppercase, digits
from time import sleep
+from sos_tests import StageOneReportTest, StageTwoReportTest
class LogsPluginTest(StageOneReportTest):
diff --git a/tests/sos_tests.py b/tests/sos_tests.py
index 655a9472..a2cca0d9 100644
--- a/tests/sos_tests.py
+++ b/tests/sos_tests.py
@@ -6,13 +6,6 @@
#
# See the LICENSE file in the source distribution for further information.
-
-from avocado.core.exceptions import TestSkipError
-from avocado.core.output import LOG_UI
-from avocado import Test
-from avocado.utils import archive, process, distro, software_manager
-from avocado.utils.cpu import get_arch
-from avocado.utils.software_manager import distro_packages
from fnmatch import fnmatch
import glob
@@ -24,6 +17,13 @@ import shutil
import socket
import re
+from avocado.core.exceptions import TestSkipError
+from avocado.core.output import LOG_UI
+from avocado import Test
+from avocado.utils import archive, process, distro, software_manager
+from avocado.utils.cpu import get_arch
+from avocado.utils.software_manager import distro_packages
+
SOS_TEST_DIR = os.path.dirname(os.path.realpath(__file__))
SOS_REPO_ROOT = os.path.realpath(os.path.join(SOS_TEST_DIR, '../'))
SOS_PLUGIN_DIR = os.path.realpath(
@@ -148,6 +148,8 @@ class BaseSoSTest(Test):
if self._exception_expected:
self.cmd_output = err.result
else:
+ # pylint: disable=no-member
+ # We've already checked above for the result attribute for err
msg = err.result.stderr.decode() or err.result.stdout.decode()
# a little hacky, but using self.log methods here will not
# print to console unless we ratchet up the verbosity for the
@@ -399,6 +401,7 @@ class BaseSoSReportTest(BaseSoSTest):
try:
process.run(cmd, timeout=10)
except Exception as err:
+ # pylint: disable=no-member
if err.result.interrupted:
self.error("Timeout while decrypting")
if 'Bad session key' in err.result.stderr.decode():
@@ -473,7 +476,7 @@ class BaseSoSReportTest(BaseSoSTest):
f"--tmp-dir {self.tmpdir} {self.sos_cmd}")
def _execute_sos_cmd(self):
- super(BaseSoSReportTest, self)._execute_sos_cmd()
+ super()._execute_sos_cmd()
self.archive = re.findall(
'/.*sosreport-.*tar.*',
self.cmd_output.stdout
@@ -489,7 +492,7 @@ class BaseSoSReportTest(BaseSoSTest):
return None
def setUp(self):
- super(BaseSoSReportTest, self).setUp()
+ super().setUp()
self.archive_path = self._get_archive_path()
def get_name_in_archive(self, fname):
@@ -834,12 +837,12 @@ class StageTwoReportTest(BaseSoSReportTest):
self.packages['centos'] = self.packages['rhel']
self.packages['centos-stream'] = self.packages['rhel']
- super(StageTwoReportTest, self).setUp()
+ super().setUp()
def tearDown(self):
if self.end_of_test_case:
self.teardown_mocking()
- super(StageTwoReportTest, self).tearDown()
+ super().tearDown()
def teardown_mocking(self):
"""Undo any and all mocked setup that we did for tests
diff --git a/tests/unittests/option_tests.py b/tests/unittests/option_tests.py
index 65b53608..a1fa4807 100644
--- a/tests/unittests/option_tests.py
+++ b/tests/unittests/option_tests.py
@@ -30,7 +30,7 @@ class MockPlugin(Plugin):
]
def __init__(self, commons):
- super(MockPlugin, self).__init__(commons=commons)
+ super().__init__(commons=commons)
class GlobalOptionTest(unittest.TestCase):
diff --git a/tests/unittests/plugin_tests.py b/tests/unittests/plugin_tests.py
index 4be93780..d659fb3d 100644
--- a/tests/unittests/plugin_tests.py
+++ b/tests/unittests/plugin_tests.py
@@ -12,13 +12,12 @@ import shutil
import random
from io import StringIO
-
+from string import ascii_lowercase
from sos.report.plugins import (Plugin, regex_findall,
_mangle_command, PluginOpt)
from sos.archive import TarFileArchive
from sos.policies.distros import LinuxPolicy
from sos.policies.init_systems import InitSystem
-from string import ascii_lowercase
PATH = os.path.dirname(__file__)
diff --git a/tox.ini b/tox.ini
index 096d795f..49d3aac6 100644
--- a/tox.ini
+++ b/tox.ini
@@ -20,11 +20,11 @@ foreman_tests =
[testenv:flake8]
deps = flake8
-commands = flake8 sos tests
+commands = flake8
[testenv:pylint]
deps = pylint
-commands = pylint --rcfile=tox.ini sos tests
+commands = pylint --rcfile=tox.ini .
[testenv:unit_tests]
basepython = python3
@@ -57,6 +57,13 @@ deps =
commands =
nosetests -v --with-coverage --cover-package=sos tests/unittests --cover-html
+[flake8]
+exclude =
+ .git,
+ .tox,
+ debian,
+ docs
+
[pylint]
# C0114, # missing-module-docstring
# C0115, # missing-class-docstring
@@ -72,5 +79,13 @@ enable =
R0912, # too-many-branches
R0914, # too-many-locals
R1725, # super-with-arguments
- W1404 # implicit-str-concat
+ W1404, # implicit-str-concat
+ W4901, # deprecated-module
+ W4902, # deprecated-method
+ W4903 # deprecated-argument
max-line-length = 79
+recursive = y
+ignore =
+ .git,
+ .tox,
+ debian