From a0035b68d288d968bd198e6a3d665359dde11496 Mon Sep 17 00:00:00 2001 From: Jake Hunsaker Date: Tue, 27 Aug 2024 22:52:57 -0400 Subject: [PATCH] [Policy] Consolidate check() across policies There is a common theme for new policies to subclass an existing one and just update the `check()` method. In almost all instances, the `check()` method remains almost entirely the same, simply changing a release file name or string. Reduce repeating ourselves by consolidating this into the base `LinuxPolicy.check()`, and leverage per-policy class attributes `os_release_file`, `os_release_name`, and `os_release_id`. The first of which will enable a policy if the specified file is found. Failing that, `os_release_name` is used to check the `NAME` field in `/etc/os-release`, and `os_release_id` is used to check the `ID` field in the same file if the name pattern does not match (or is not set). Note that we do _not_ check the `ID_LIKE` field. This allows a policy to be defined with as little as something like the following: ``` class MyPolicy(LinuxPolicy): vendor = 'Myself' os_release_file = '/etc/mylinux-release' os_release_name = 'MyLinux' os_release_id ='mynix' ``` Resolves: #1934 Signed-off-by: Jake Hunsaker --- sos/collector/sosnode.py | 6 +- sos/component.py | 2 +- sos/policies/__init__.py | 27 ++++++--- sos/policies/distros/__init__.py | 30 ++++++++-- sos/policies/distros/almalinux.py | 24 ++------ sos/policies/distros/amazon.py | 23 +------- sos/policies/distros/anolis.py | 28 +-------- sos/policies/distros/azure.py | 25 ++------ sos/policies/distros/circle.py | 29 +--------- sos/policies/distros/cloudlinux.py | 23 +------- sos/policies/distros/cos.py | 16 +---- sos/policies/distros/debian.py | 15 +---- sos/policies/distros/opencloudos.py | 23 +------- sos/policies/distros/openeuler.py | 22 +------ sos/policies/distros/redhat.py | 77 +++++-------------------- sos/policies/distros/rocky.py | 29 +--------- sos/policies/distros/suse.py | 17 ++---- sos/policies/distros/ubuntu.py | 17 +----- sos/policies/distros/uniontechserver.py | 22 +------ 19 files changed, 108 insertions(+), 347 deletions(-) diff --git a/sos/collector/sosnode.py b/sos/collector/sosnode.py index c6ce801cb9..0a3effaa4d 100644 --- a/sos/collector/sosnode.py +++ b/sos/collector/sosnode.py @@ -160,7 +160,7 @@ def set_node_manifest(self, manifest): """ self.manifest = manifest self.manifest.add_field('hostname', self._hostname) - self.manifest.add_field('policy', self.host.distro) + self.manifest.add_field('policy', self.host.os_release_name) self.manifest.add_field('sos_version', self.sos_info['version']) self.manifest.add_field('final_sos_command', '') self.manifest.add_field('transport', self._transport.name) @@ -390,14 +390,14 @@ def determine_host_policy(self): """ if self.local: self.log_info( - f"using local policy {self.commons['policy'].distro}") + f"using local policy {self.commons['policy'].os_release_name}") return self.commons['policy'] host = load(cache={}, sysroot=self.opts.sysroot, init=InitSystem(), probe_runtime=True, remote_exec=self._transport.run_command, remote_check=self.read_file('/etc/os-release')) if host: - self.log_info(f"loaded policy {host.distro} for host") + self.log_info(f"loaded policy {host.os_release_name} for host") return host self.log_error('Unable to determine host installation. Ignoring node') raise UnsupportedHostException diff --git a/sos/component.py b/sos/component.py index 0443a4e6f1..17bc22e3ed 100644 --- a/sos/component.py +++ b/sos/component.py @@ -131,7 +131,7 @@ def __init__(self, parser, parsed_args, cmdline_args): self.manifest.add_field('compression', '') self.manifest.add_field('tmpdir', self.tmpdir) self.manifest.add_field('tmpdir_fs_type', self.tmpfstype) - self.manifest.add_field('policy', self.policy.distro) + self.manifest.add_field('policy', self.policy.os_release_name) self.manifest.add_section('components') def load_local_policy(self): diff --git a/sos/policies/__init__.py b/sos/policies/__init__.py index 9ca2286dee..4394f29e7f 100644 --- a/sos/policies/__init__.py +++ b/sos/policies/__init__.py @@ -42,6 +42,7 @@ def load(cache={}, sysroot=None, init=None, probe_runtime=True, cache['policy'] = policy(sysroot=sysroot, init=init, probe_runtime=probe_runtime, remote_exec=remote_exec) + break if sys.platform != 'linux': raise Exception("SoS is not supported on this platform") @@ -75,8 +76,16 @@ class Policy(): SoSTransport in use :type remote_exec: ``SoSTranport.run_command()`` - :cvar distro: The name of the distribution the Policy represents - :vartype distro: ``str`` + :cvar os_release_name: The name of the distribution as it appears in the + os-release (-esque) file for the NAME variable. + :vartype os_release_name: ``str`` + + :cvar os_release_id: The ID variable to match in a distribution's release + file. + :vartype os_release_id: ``str`` + + :cvar os_release_file: The filepath of the distribution's os-release file + :vartype os_release_file: ``str`` :cvar vendor: The name of the vendor producing the distribution :vartype vendor: ``str`` @@ -97,7 +106,7 @@ class Policy(): msg = _("""\ This command will collect system configuration and diagnostic information \ -from this %(distro)s system. +from this %(os_release_name)s system. For more information on %(vendor)s visit: @@ -111,8 +120,9 @@ class Policy(): %(vendor_text)s """) - - distro = "Unknown" + os_release_name = 'Unknown' + os_release_file = '' + os_release_id = '' vendor = "Unknown" vendor_urls = [('Example URL', "http://www.example.com/")] vendor_text = "" @@ -459,8 +469,8 @@ def display_results(self, archive, directory, checksum, archivestat=None, def get_msg(self): """This method is used to prepare the preamble text to display to - the user in non-batch mode. If your policy sets self.distro that - text will be substituted accordingly. You can also override this + the user in non-batch mode. If your policy sets self.os_release_name, + that text will be substituted accordingly. You can also override this method to do something more complicated. :returns: Formatted banner message string @@ -471,7 +481,8 @@ def get_msg(self): else: changes_text = "No changes will be made to system configuration." width = 72 - _msg = self.msg % {'distro': self.distro, 'vendor': self.vendor, + _msg = self.msg % {'os_release_name': self.os_release_name, + 'vendor': self.vendor, 'vendor_urls': self._fmt_vendor_urls(), 'vendor_text': self.vendor_text, 'tmpdir': self.commons['tmpdir'], diff --git a/sos/policies/distros/__init__.py b/sos/policies/distros/__init__.py index 5874d31ccb..8c178020ec 100644 --- a/sos/policies/distros/__init__.py +++ b/sos/policies/distros/__init__.py @@ -40,6 +40,7 @@ except ImportError: BOTO3_LOADED = False +OS_RELEASE = "/etc/os-release" # Container environment variables for detecting if we're in a container ENV_CONTAINER = 'container' ENV_HOST_SYSROOT = 'HOST' @@ -48,11 +49,14 @@ class LinuxPolicy(Policy): """This policy is meant to be an abc class that provides common implementations used in Linux distros""" - - distro = "Linux" vendor = "None" PATH = "/bin:/sbin:/usr/bin:/usr/sbin" init = None + # the following will be used, in order, as part of check() to validate that + # we are running on a particular distro + os_release_file = '' + os_release_name = '' + os_release_id = '' # _ prefixed class attrs are used for storing any vendor-defined defaults # the non-prefixed attrs are used by the upload methods, and will be set # to the cmdline/config file values, if provided. If not provided, then @@ -145,7 +149,25 @@ def check(cls, remote=''): This function is responsible for determining if the underlying system is supported by this policy. """ - raise NotImplementedError + def _check_release(content): + _matches = [cls.os_release_name] + if cls.os_release_id: + _matches.append(cls.os_release_id) + for line in content.splitlines(): + if line.startswith(('NAME=', 'ID=')): + _distro = line.split('=')[1:][0].strip("\"'") + if _distro in _matches: + return True + return False + + if remote: + return _check_release(remote) + # use the os-specific file primarily + if os.path.isfile(cls.os_release_file): + return True + # next check os-release for a NAME or ID value we expect + with open(OS_RELEASE, "r", encoding='utf-8') as f: + return _check_release(f.read()) def kernel_version(self): return self.release @@ -171,7 +193,7 @@ def display_help(cls, section): if cls == LinuxPolicy: cls.display_self_help(section) else: - section.set_title(f"{cls.distro} Distribution Policy") + section.set_title(f"{cls.os_release_name} Distribution Policy") cls.display_distro_help(section) @classmethod diff --git a/sos/policies/distros/almalinux.py b/sos/policies/distros/almalinux.py index 5083168f5d..563bab99d2 100644 --- a/sos/policies/distros/almalinux.py +++ b/sos/policies/distros/almalinux.py @@ -8,13 +8,14 @@ # # See the LICENSE file in the source distribution for further information. -import os -from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE +from sos.policies.distros.redhat import RedHatPolicy class AlmaLinuxPolicy(RedHatPolicy): - distro = "AlmaLinux" vendor = "AlmaLinux OS Foundation" + os_release_file = '/etc/almalinux-release' + os_release_name = 'AlmaLinux' + vendor_urls = [ ('Distribution Website', 'https://www.almalinux.org/'), ('Commercial Support', 'https://tuxcare.com/linux-support-services/') @@ -26,21 +27,4 @@ def __init__(self, sysroot=None, init=None, probe_runtime=True, probe_runtime=probe_runtime, remote_exec=remote_exec) - @classmethod - def check(cls, remote=''): - if remote: - return cls.distro in remote - - if not os.path.isfile('/etc/almalinux-release'): - return False - - if os.path.exists(OS_RELEASE): - with open(OS_RELEASE, 'r', encoding='utf-8') as f: - for line in f: - if line.startswith('NAME'): - if 'AlmaLinux' in line: - return True - - return False - # vim: set et ts=4 sw=4 : diff --git a/sos/policies/distros/amazon.py b/sos/policies/distros/amazon.py index ae760e2464..86c33cd2ab 100644 --- a/sos/policies/distros/amazon.py +++ b/sos/policies/distros/amazon.py @@ -8,15 +8,14 @@ # # See the LICENSE file in the source distribution for further information. -import os -from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE +from sos.policies.distros.redhat import RedHatPolicy class AmazonPolicy(RedHatPolicy): - - distro = "Amazon Linux" vendor = "Amazon" vendor_urls = [('Distribution Website', 'https://aws.amazon.com')] + os_release_file = '' + os_release_name = 'Amazon Linux' def __init__(self, sysroot=None, init=None, probe_runtime=True, remote_exec=None): @@ -24,20 +23,4 @@ def __init__(self, sysroot=None, init=None, probe_runtime=True, probe_runtime=probe_runtime, remote_exec=remote_exec) - @classmethod - def check(cls, remote=''): - - if remote: - return cls.distro in remote - - if not os.path.exists(OS_RELEASE): - return False - - with open(OS_RELEASE, 'r', encoding='utf-8') as f: - for line in f: - if line.startswith('NAME'): - if 'Amazon Linux' in line: - return True - return False - # vim: set et ts=4 sw=4 : diff --git a/sos/policies/distros/anolis.py b/sos/policies/distros/anolis.py index 496d34bb15..5f64f8ff57 100644 --- a/sos/policies/distros/anolis.py +++ b/sos/policies/distros/anolis.py @@ -6,15 +6,14 @@ # # See the LICENSE file in the source distribution for further information. -import os -from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE +from sos.policies.distros.redhat import RedHatPolicy class AnolisPolicy(RedHatPolicy): - - distro = "Anolis OS" vendor = "The OpenAnolis Project" vendor_urls = [('Distribution Website', 'https://openanolis.org/')] + os_release_file = '/etc/anolis-release' + os_release_name = 'Anolis OS' def __init__(self, sysroot=None, init=None, probe_runtime=True, remote_exec=None): @@ -22,25 +21,4 @@ def __init__(self, sysroot=None, init=None, probe_runtime=True, probe_runtime=probe_runtime, remote_exec=remote_exec) - @classmethod - def check(cls, remote=''): - - if remote: - return cls.distro in remote - - # Return False if /etc/os-release is missing - if not os.path.exists(OS_RELEASE): - return False - - # Return False if /etc/anolis-release is missing - if not os.path.isfile('/etc/anolis-release'): - return False - - with open(OS_RELEASE, 'r', encoding='utf-8') as f: - for line in f: - if line.startswith('NAME'): - if 'Anolis OS' in line: - return True - return False - # vim: set et ts=4 sw=4 : diff --git a/sos/policies/distros/azure.py b/sos/policies/distros/azure.py index 9607ad2974..9d9b4bffde 100644 --- a/sos/policies/distros/azure.py +++ b/sos/policies/distros/azure.py @@ -8,18 +8,17 @@ # # 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 +from sos.policies.distros.redhat import RedHatPolicy class AzurePolicy(RedHatPolicy): - - distro = "Azure Linux" vendor = "Microsoft" vendor_urls = [ ('Distribution Website', 'https://github.com/microsoft/azurelinux') ] + os_release_name = 'Microsoft Azure Linux' + os_release_file = '' def __init__(self, sysroot=None, init=None, probe_runtime=True, remote_exec=None): @@ -28,22 +27,8 @@ def __init__(self, sysroot=None, init=None, probe_runtime=True, remote_exec=remote_exec) self.valid_subclasses += [AzurePlugin] - @classmethod - def check(cls, remote=''): - - if remote: - return cls.distro in remote - - if not os.path.exists(OS_RELEASE): - return False - with open(OS_RELEASE, 'r', encoding='utf-8') as f: - for line in f: - if line.startswith('NAME'): - if 'Common Base Linux Mariner' in line: - return True - if 'Microsoft Azure Linux' in line: - return True - return False +class CBLMarinerPolicy(AzurePolicy): + os_release_name = 'Common Base Linux Mariner' # vim: set et ts=4 sw=4 : diff --git a/sos/policies/distros/circle.py b/sos/policies/distros/circle.py index 99a7bf7c8e..cc28ec2cca 100644 --- a/sos/policies/distros/circle.py +++ b/sos/policies/distros/circle.py @@ -8,15 +8,14 @@ # # See the LICENSE file in the source distribution for further information. -import os -from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE +from sos.policies.distros.redhat import RedHatPolicy class CirclePolicy(RedHatPolicy): - - distro = "Circle Linux" vendor = "The Circle Linux Project" vendor_urls = [('Distribution Website', 'https://cclinux.org')] + os_release_file = '/etc/circle-release' + os_release_name = 'Circle Linux' def __init__(self, sysroot=None, init=None, probe_runtime=True, remote_exec=None): @@ -24,26 +23,4 @@ def __init__(self, sysroot=None, init=None, probe_runtime=True, probe_runtime=probe_runtime, remote_exec=remote_exec) - @classmethod - def check(cls, remote=''): - - if remote: - return cls.distro in remote - - # Return False if /etc/os-release is missing - if not os.path.exists(OS_RELEASE): - return False - - # Return False if /etc/circle-release is missing - if not os.path.isfile('/etc/circle-release'): - return False - - with open(OS_RELEASE, 'r', encoding='utf-8') as f: - for line in f: - if line.startswith('NAME'): - if 'Circle Linux' in line: - return True - - return False - # vim: set et ts=4 sw=4 : diff --git a/sos/policies/distros/cloudlinux.py b/sos/policies/distros/cloudlinux.py index 95f6a2067f..90b240a80b 100644 --- a/sos/policies/distros/cloudlinux.py +++ b/sos/policies/distros/cloudlinux.py @@ -8,17 +8,17 @@ # # See the LICENSE file in the source distribution for further information. -import os -from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE +from sos.policies.distros.redhat import RedHatPolicy class CloudLinuxPolicy(RedHatPolicy): - distro = "CloudLinux" vendor = "CloudLinux" vendor_urls = [ ('Distribution Website', 'https://www.cloudlinux.com/'), ('Commercial Support', 'https://www.cloudlinux.com/') ] + os_release_file = '/etc/cloudlinux-release' + os_release_name = 'CloudLinux' def __init__(self, sysroot=None, init=None, probe_runtime=True, remote_exec=None): @@ -26,21 +26,4 @@ def __init__(self, sysroot=None, init=None, probe_runtime=True, probe_runtime=probe_runtime, remote_exec=remote_exec) - @classmethod - def check(cls, remote=''): - if remote: - return cls.distro in remote - - if not os.path.isfile('/etc/cloudlinux-release'): - return False - - if os.path.exists(OS_RELEASE): - with open(OS_RELEASE, 'r', encoding='utf-8') as f: - for line in f: - if line.startswith('NAME'): - if 'CloudLinux' in line: - return True - - return False - # vim: set et ts=4 sw=4 : diff --git a/sos/policies/distros/cos.py b/sos/policies/distros/cos.py index 9c1d0ddef9..b88cf519c8 100644 --- a/sos/policies/distros/cos.py +++ b/sos/policies/distros/cos.py @@ -27,12 +27,13 @@ def _blank_or_comment(line): class CosPolicy(LinuxPolicy): - distro = "Container-Optimized OS" vendor = "Google Cloud Platform" vendor_urls = [ ('Distribution Website', 'https://cloud.google.com/container-optimized-os/') ] + os_release_name = 'Container-Optimized OS' + os_release_id = 'cos' valid_subclasses = [CosPlugin, IndependentPlugin] PATH = "/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin" @@ -43,17 +44,4 @@ def __init__(self, sysroot=None, init=None, probe_runtime=True, remote_exec=remote_exec) self.valid_subclasses += [CosPolicy] - @classmethod - def check(cls, remote=''): - if remote: - return cls.distro in remote - - try: - with open('/etc/os-release', 'r', encoding='utf-8') as fp: - os_release = dict(line.strip().split('=') for line in fp - if not _blank_or_comment(line)) - return os_release['ID'] == 'cos' - except (IOError, KeyError): - return False - # vim: set et ts=4 sw=4 : diff --git a/sos/policies/distros/debian.py b/sos/policies/distros/debian.py index 737e5f78f1..7db96f9d4c 100644 --- a/sos/policies/distros/debian.py +++ b/sos/policies/distros/debian.py @@ -6,17 +6,16 @@ # # 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 class DebianPolicy(LinuxPolicy): - distro = "Debian" vendor = "the Debian project" vendor_urls = [('Community Website', 'https://www.debian.org/')] + os_release_name = 'Debian' + os_release_file = '/etc/debian_version' name_pattern = 'friendly' valid_subclasses = [DebianPlugin] PATH = "/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games" \ @@ -50,16 +49,6 @@ def _get_pkg_name_for_binary(self, binary): "xz": "xz-utils" }.get(binary, binary) - @classmethod - def check(cls, remote=''): - """This method checks to see if we are running on Debian. - It returns True or False.""" - - if remote: - return cls.distro in remote - - return os.path.isfile('/etc/debian_version') - def dist_version(self): try: with open('/etc/os-release', 'r', encoding='utf-8') as fp: diff --git a/sos/policies/distros/opencloudos.py b/sos/policies/distros/opencloudos.py index 5d58cde34f..f471fa4b5d 100644 --- a/sos/policies/distros/opencloudos.py +++ b/sos/policies/distros/opencloudos.py @@ -7,14 +7,14 @@ # # See the LICENSE file in the source distribution for further information. -import os -from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE +from sos.policies.distros.redhat import RedHatPolicy class OpenCloudOSPolicy(RedHatPolicy): - distro = "OpenCloudOS Stream" vendor = "OpenCloudOS" vendor_urls = [('Distribution Website', 'https://www.opencloudos.org/')] + os_release_name = 'OpenCloudOS Stream' + os_release_file = '' def __init__(self, sysroot=None, init=None, probe_runtime=True, remote_exec=None): @@ -22,21 +22,4 @@ def __init__(self, sysroot=None, init=None, probe_runtime=True, probe_runtime=probe_runtime, remote_exec=remote_exec) - @classmethod - def check(cls, remote=''): - - if remote: - return cls.distro in remote - - if not os.path.exists(OS_RELEASE): - return False - - with open(OS_RELEASE, 'r', encoding='utf-8') as f: - for line in f: - if line.startswith('NAME'): - if 'OpenCloudOS Stream' in line: - return True - - return False - # vim: set et ts=4 sw=4 : diff --git a/sos/policies/distros/openeuler.py b/sos/policies/distros/openeuler.py index f22348049e..8610ae1ed9 100644 --- a/sos/policies/distros/openeuler.py +++ b/sos/policies/distros/openeuler.py @@ -6,15 +6,15 @@ # # 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 +from sos.policies.distros.redhat import RedHatPolicy class OpenEulerPolicy(RedHatPolicy): - distro = "openEuler" vendor = "The openEuler Project" vendor_urls = [('Distribution Website', 'https://openeuler.org/')] + os_release_name = 'openEuler' + os_release_file = '' def __init__(self, sysroot=None, init=None, probe_runtime=True, remote_exec=None): @@ -24,20 +24,4 @@ def __init__(self, sysroot=None, init=None, probe_runtime=True, self.valid_subclasses += [OpenEulerPlugin] - @classmethod - def check(cls, remote=''): - - if remote: - return cls.distro in remote - - if not os.path.exists(OS_RELEASE): - return False - - with open(OS_RELEASE, 'r', encoding='utf-8') as f: - for line in f: - if line.startswith('NAME'): - if 'openEuler' in line: - return True - return False - # vim: set et ts=4 sw=4 : diff --git a/sos/policies/distros/redhat.py b/sos/policies/distros/redhat.py index 55a9fd0bf5..abe5cc1d90 100644 --- a/sos/policies/distros/redhat.py +++ b/sos/policies/distros/redhat.py @@ -18,7 +18,7 @@ from sos.presets.redhat import (RHEL_PRESETS, RHV, RHEL, CB, RHOSP, RHOCP, RH_CFME, RH_SATELLITE, AAPEDA, AAPCONTROLLER) -from sos.policies.distros import LinuxPolicy, ENV_HOST_SYSROOT +from sos.policies.distros import LinuxPolicy, ENV_HOST_SYSROOT, OS_RELEASE from sos.policies.package_managers.rpm import RpmPackageManager from sos.policies.package_managers.flatpak import FlatpakPackageManager from sos.policies.package_managers import MultiPackageManager @@ -31,12 +31,10 @@ except ImportError: REQUESTS_LOADED = False -OS_RELEASE = "/etc/os-release" RHEL_RELEASE_STR = "Red Hat Enterprise Linux" class RedHatPolicy(LinuxPolicy): - distro = "Red Hat" vendor = "Red Hat" vendor_urls = [ ('Distribution Website', 'https://www.redhat.com/'), @@ -89,18 +87,6 @@ def __init__(self, sysroot=None, init=None, probe_runtime=True, self.set_exec_path() self.load_presets() - @classmethod - def check(cls, remote=''): - """This method checks to see if we are running on Red Hat. It must be - overriden by concrete subclasses to return True when running on a - Fedora, RHEL or other Red Hat distribution or False otherwise. - - If `remote` is provided, it should be the contents of a remote host's - os-release, or comparable, file to be used in place of the locally - available one. - """ - return False - @classmethod def display_distro_help(cls, section): if cls is not RedHatPolicy: @@ -122,7 +108,7 @@ def display_distro_help(cls, section): for subc, value in subs.items(): subln = bold(f"policies.{subc}") section.add_text( - f"{' ':>8}{subln:<35}{value.distro:<30}", + f"{' ':>8}{subln:<35}{value.os_release_name:<30}", newline=False ) @@ -216,11 +202,13 @@ class RHELPolicy(RedHatPolicy): technical support engineer. This information will be printed at the end of the upload process for any sos report execution. """ - distro = RHEL_RELEASE_STR vendor = "Red Hat" + os_release_file = '/etc/redhat-release' + os_release_name = RHEL_RELEASE_STR + os_release_id = 'rhel' msg = _("""\ This command will collect diagnostic and configuration \ -information from this %(distro)s system and installed \ +information from this %(os_release_name)s system and installed \ applications. An archive containing the collected information will be \ @@ -240,34 +228,6 @@ def __init__(self, sysroot=None, init=None, probe_runtime=True, remote_exec=remote_exec) self.register_presets(RHEL_PRESETS) - @classmethod - def check(cls, remote=''): - """Test to see if the running host is a RHEL installation. - - Checks for the presence of the "Red Hat Enterprise Linux" - release string at the beginning of the NAME field in the - `/etc/os-release` file and returns ``True`` if it is - found, and ``False`` otherwise. - - :returns: ``True`` if the host is running RHEL or ``False`` - otherwise. - """ - - if remote: - return cls.distro in remote - - if not os.path.exists(OS_RELEASE): - return False - - with open(OS_RELEASE, "r", encoding='utf-8') as f: - for line in f: - if line.startswith("NAME"): - (_, value) = line.split("=") - value = value.strip("\"'") - if value.startswith(cls.distro): - return True - return False - def prompt_for_upload_user(self): if self.commons['cmdlineopts'].upload_user: self.ui_log.info( @@ -502,9 +462,11 @@ def probe_preset(self): class CentOsPolicy(RHELPolicy): - distro = "CentOS" vendor = "CentOS" vendor_urls = [('Community Website', 'https://www.centos.org/')] + os_release_file = '/etc/centos-release' + os_release_name = 'CentOS Linux' + os_release_id = 'centos' class RedHatCoreOSPolicy(RHELPolicy): @@ -528,10 +490,10 @@ class RedHatCoreOSPolicy(RHELPolicy): impact how sos report collections are performed. """ - distro = "Red Hat CoreOS" + os_release_name = "Red Hat Enterprise Linux CoreOS" msg = _("""\ This command will collect diagnostic and configuration \ -information from this %(distro)s system. +information from this %(os_release_name)s system. An archive containing the collected information will be \ generated in %(tmpdir)s and may be provided to a %(vendor)s \ @@ -564,7 +526,7 @@ def check(cls, remote=''): try: with open(host_release, 'r', encoding='utf-8') as hfile: for line in hfile.read().splitlines(): - coreos |= 'Red Hat Enterprise Linux CoreOS' in line + coreos |= cls.os_release_name in line except IOError: # host release file not present, will fallback to RHEL policy check pass @@ -608,13 +570,14 @@ class FedoraPolicy(RedHatPolicy): for that location via --upload-user and --upload-pass (or the appropriate environment variables). """ - - distro = "Fedora" vendor = "the Fedora Project" vendor_urls = [ ('Community Website', 'https://fedoraproject.org/'), ('Community Forums', 'https://discussion.fedoraproject.org/') ] + os_release_file = '/etc/fedora-release' + os_release_name = 'Fedora Linux' + os_release_id = 'fedora' def __init__(self, sysroot=None, init=None, probe_runtime=True, remote_exec=None): @@ -622,16 +585,6 @@ def __init__(self, sysroot=None, init=None, probe_runtime=True, probe_runtime=probe_runtime, remote_exec=remote_exec) - @classmethod - def check(cls, remote=''): - """This method checks to see if we are running on Fedora. It returns - True or False.""" - - if remote: - return cls.distro in remote - - return os.path.isfile('/etc/fedora-release') - def fedora_version(self): pkg = self.pkg_by_name("fedora-release") or \ self.package_manager.all_pkgs_by_name_regex( diff --git a/sos/policies/distros/rocky.py b/sos/policies/distros/rocky.py index e1470e65df..da046ed85f 100644 --- a/sos/policies/distros/rocky.py +++ b/sos/policies/distros/rocky.py @@ -8,17 +8,17 @@ # # See the LICENSE file in the source distribution for further information. -import os -from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE +from sos.policies.distros.redhat import RedHatPolicy class RockyPolicy(RedHatPolicy): - distro = "Rocky Linux" vendor = "Rocky Enterprise Software Foundation" vendor_urls = [ ('Distribution Website', 'https://rockylinux.org'), ('Vendor Website', 'https://resf.org') ] + os_release_file = '/etc/rocky-release' + os_release_name = 'Rocky Linux' def __init__(self, sysroot=None, init=None, probe_runtime=True, remote_exec=None): @@ -26,27 +26,4 @@ def __init__(self, sysroot=None, init=None, probe_runtime=True, probe_runtime=probe_runtime, remote_exec=remote_exec) - @classmethod - def check(cls, remote=''): - if remote: - return cls.distro in remote - - # Return False if /etc/os-release is missing - if not os.path.exists(OS_RELEASE): - return False - - # Return False if /etc/rocky-release is missing - if not os.path.isfile('/etc/rocky-release'): - return False - - # If we've gotten this far, check for Rocky in - # /etc/os-release - with open(OS_RELEASE, 'r', encoding='utf-8') as f: - for line in f: - if line.startswith('NAME'): - if 'Rocky Linux' in line: - return True - - return False - # vim: set et ts=4 sw=4 : diff --git a/sos/policies/distros/suse.py b/sos/policies/distros/suse.py index d3f1ed8a7c..03fc36988b 100644 --- a/sos/policies/distros/suse.py +++ b/sos/policies/distros/suse.py @@ -17,7 +17,7 @@ class SuSEPolicy(LinuxPolicy): - distro = "SuSE" + os_release_name = "SuSE" vendor = "SuSE" vendor_urls = [('Distribution Website', 'https://www.suse.com/')] _tmp_dir = "/var/tmp" @@ -59,12 +59,13 @@ def get_local_name(self): class OpenSuSEPolicy(SuSEPolicy): - distro = "OpenSuSE" vendor = "SuSE" vendor_urls = [('Community Website', 'https://www.opensuse.org/')] + os_release_name = "OpenSuSE" + os_release_file = '/etc/SUSE-brand' msg = _("""\ This command will collect diagnostic and configuration \ -information from this %(distro)s system and installed \ +information from this %(os_release_name)s system and installed \ applications. An archive containing the collected information will be \ @@ -81,12 +82,4 @@ def __init__(self, sysroot=None, init=None, probe_runtime=True, probe_runtime=probe_runtime, remote_exec=remote_exec) - @classmethod - def check(cls, remote=''): - """This method checks to see if we are running on SuSE. - """ - - if remote: - return cls.distro in remote - - return os.path.isfile('/etc/SUSE-brand') +# vim: set et ts=4 sw=4 : diff --git a/sos/policies/distros/ubuntu.py b/sos/policies/distros/ubuntu.py index 12efadae0b..f241f4f90f 100644 --- a/sos/policies/distros/ubuntu.py +++ b/sos/policies/distros/ubuntu.py @@ -17,12 +17,13 @@ class UbuntuPolicy(DebianPolicy): - distro = "Ubuntu" vendor = "Canonical" vendor_urls = [ ('Community Website', 'https://www.ubuntu.com/'), ('Commercial Support', 'https://www.canonical.com') ] + os_release_name = 'Ubuntu' + os_release_file = '' PATH = "/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games" \ + ":/usr/local/sbin:/usr/local/bin:/snap/bin" _upload_url = "https://files.support.canonical.com/uploads/" @@ -52,20 +53,6 @@ def __init__(self, sysroot=None, init=None, probe_runtime=True, self.valid_subclasses += [UbuntuPlugin] - @classmethod - def check(cls, remote=''): - """This method checks to see if we are running on Ubuntu. - It returns True or False.""" - - if remote: - return cls.distro in remote - - try: - with open('/etc/lsb-release', 'r', encoding='utf-8') as fp: - return "Ubuntu" in fp.read() - except IOError: - return False - def dist_version(self): """ Returns the version stated in DISTRIB_RELEASE """ diff --git a/sos/policies/distros/uniontechserver.py b/sos/policies/distros/uniontechserver.py index fcb47e306b..68cdf45074 100644 --- a/sos/policies/distros/uniontechserver.py +++ b/sos/policies/distros/uniontechserver.py @@ -6,14 +6,14 @@ # # See the LICENSE file in the source distribution for further information. -import os -from sos.policies.distros.redhat import RedHatPolicy, OS_RELEASE +from sos.policies.distros.redhat import RedHatPolicy class UnionTechPolicy(RedHatPolicy): - distro = "UnionTech OS Server" vendor = "The UnionTech Project" vendor_urls = [('Distribution Website', 'https://www.chinauos.com/')] + os_release_name = 'UnionTech OS Server' + os_release_file = '' def __init__(self, sysroot=None, init=None, probe_runtime=True, remote_exec=None): @@ -21,20 +21,4 @@ def __init__(self, sysroot=None, init=None, probe_runtime=True, probe_runtime=probe_runtime, remote_exec=remote_exec) - @classmethod - def check(cls, remote=''): - - if remote: - return cls.distro in remote - - if not os.path.exists(OS_RELEASE): - return False - - with open(OS_RELEASE, 'r', encoding='utf-8') as f: - for line in f: - if line.startswith('NAME'): - if 'UnionTech OS Server' in line: - return True - return False - # vim: set et ts=4 sw=4 :