Bump bundled distro version to 1.8.0 (#81765)

* Bump bundled distro version to 1.8.0

* Bump bundled distro version from to 1.8.0 from 1.6.0

Fixes: #81713

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>

* Remove sanity entries

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>

---------

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
pull/82912/head
Abhijeet Kasurde 2 months ago committed by GitHub
parent d86ad77d6f
commit a870e7d0c6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,3 @@
---
bugfixes:
- distro - bump bundled distro version from 1.6.0 to 1.8.0 (https://github.com/ansible/ansible/issues/81713).

@ -41,40 +41,39 @@ import shlex
import subprocess
import sys
import warnings
from typing import (
Any,
Callable,
Dict,
Iterable,
Optional,
Sequence,
TextIO,
Tuple,
Type,
)
__version__ = "1.6.0"
# Use `if False` to avoid an ImportError on Python 2. After dropping Python 2
# support, can use typing.TYPE_CHECKING instead. See:
# https://docs.python.org/3/library/typing.html#typing.TYPE_CHECKING
if False: # pragma: nocover
from typing import (
Any,
Callable,
Dict,
Iterable,
Optional,
Sequence,
TextIO,
Tuple,
Type,
TypedDict,
Union,
)
try:
from typing import TypedDict
except ImportError:
# Python 3.7
TypedDict = dict
VersionDict = TypedDict(
"VersionDict", {"major": str, "minor": str, "build_number": str}
)
InfoDict = TypedDict(
"InfoDict",
{
"id": str,
"version": str,
"version_parts": VersionDict,
"like": str,
"codename": str,
},
)
__version__ = "1.8.0"
class VersionDict(TypedDict):
major: str
minor: str
build_number: str
class InfoDict(TypedDict):
id: str
version: str
version_parts: VersionDict
like: str
codename: str
_UNIXCONFDIR = os.environ.get("UNIXCONFDIR", "/etc")
@ -127,6 +126,26 @@ _DISTRO_RELEASE_CONTENT_REVERSED_PATTERN = re.compile(
# Pattern for base file name of distro release file
_DISTRO_RELEASE_BASENAME_PATTERN = re.compile(r"(\w+)[-_](release|version)$")
# Base file names to be looked up for if _UNIXCONFDIR is not readable.
_DISTRO_RELEASE_BASENAMES = [
"SuSE-release",
"arch-release",
"base-release",
"centos-release",
"fedora-release",
"gentoo-release",
"mageia-release",
"mandrake-release",
"mandriva-release",
"mandrivalinux-release",
"manjaro-release",
"oracle-release",
"redhat-release",
"rocky-release",
"sl-release",
"slackware-version",
]
# Base file names to be ignored when searching for distro release file
_DISTRO_RELEASE_IGNORE_BASENAMES = (
"debian_version",
@ -139,8 +158,7 @@ _DISTRO_RELEASE_IGNORE_BASENAMES = (
)
def linux_distribution(full_distribution_name=True):
# type: (bool) -> Tuple[str, str, str]
def linux_distribution(full_distribution_name: bool = True) -> Tuple[str, str, str]:
"""
.. deprecated:: 1.6.0
@ -183,8 +201,7 @@ def linux_distribution(full_distribution_name=True):
return _distro.linux_distribution(full_distribution_name)
def id():
# type: () -> str
def id() -> str:
"""
Return the distro ID of the current distribution, as a
machine-readable string.
@ -228,6 +245,7 @@ def id():
"freebsd" FreeBSD
"midnightbsd" MidnightBSD
"rocky" Rocky Linux
"aix" AIX
"guix" Guix System
============== =========================================
@ -266,8 +284,7 @@ def id():
return _distro.id()
def name(pretty=False):
# type: (bool) -> str
def name(pretty: bool = False) -> str:
"""
Return the name of the current OS distribution, as a human-readable
string.
@ -306,8 +323,7 @@ def name(pretty=False):
return _distro.name(pretty)
def version(pretty=False, best=False):
# type: (bool, bool) -> str
def version(pretty: bool = False, best: bool = False) -> str:
"""
Return the version of the current OS distribution, as a human-readable
string.
@ -355,8 +371,7 @@ def version(pretty=False, best=False):
return _distro.version(pretty, best)
def version_parts(best=False):
# type: (bool) -> Tuple[str, str, str]
def version_parts(best: bool = False) -> Tuple[str, str, str]:
"""
Return the version of the current OS distribution as a tuple
``(major, minor, build_number)`` with items as follows:
@ -373,8 +388,7 @@ def version_parts(best=False):
return _distro.version_parts(best)
def major_version(best=False):
# type: (bool) -> str
def major_version(best: bool = False) -> str:
"""
Return the major version of the current OS distribution, as a string,
if provided.
@ -387,8 +401,7 @@ def major_version(best=False):
return _distro.major_version(best)
def minor_version(best=False):
# type: (bool) -> str
def minor_version(best: bool = False) -> str:
"""
Return the minor version of the current OS distribution, as a string,
if provided.
@ -401,8 +414,7 @@ def minor_version(best=False):
return _distro.minor_version(best)
def build_number(best=False):
# type: (bool) -> str
def build_number(best: bool = False) -> str:
"""
Return the build number of the current OS distribution, as a string,
if provided.
@ -415,8 +427,7 @@ def build_number(best=False):
return _distro.build_number(best)
def like():
# type: () -> str
def like() -> str:
"""
Return a space-separated list of distro IDs of distributions that are
closely related to the current OS distribution in regards to packaging
@ -433,8 +444,7 @@ def like():
return _distro.like()
def codename():
# type: () -> str
def codename() -> str:
"""
Return the codename for the release of the current OS distribution,
as a string.
@ -458,8 +468,7 @@ def codename():
return _distro.codename()
def info(pretty=False, best=False):
# type: (bool, bool) -> InfoDict
def info(pretty: bool = False, best: bool = False) -> InfoDict:
"""
Return certain machine-readable information items about the current OS
distribution in a dictionary, as shown in the following example:
@ -503,8 +512,7 @@ def info(pretty=False, best=False):
return _distro.info(pretty, best)
def os_release_info():
# type: () -> Dict[str, str]
def os_release_info() -> Dict[str, str]:
"""
Return a dictionary containing key-value pairs for the information items
from the os-release file data source of the current OS distribution.
@ -514,8 +522,7 @@ def os_release_info():
return _distro.os_release_info()
def lsb_release_info():
# type: () -> Dict[str, str]
def lsb_release_info() -> Dict[str, str]:
"""
Return a dictionary containing key-value pairs for the information items
from the lsb_release command data source of the current OS distribution.
@ -526,8 +533,7 @@ def lsb_release_info():
return _distro.lsb_release_info()
def distro_release_info():
# type: () -> Dict[str, str]
def distro_release_info() -> Dict[str, str]:
"""
Return a dictionary containing key-value pairs for the information items
from the distro release file data source of the current OS distribution.
@ -537,8 +543,7 @@ def distro_release_info():
return _distro.distro_release_info()
def uname_info():
# type: () -> Dict[str, str]
def uname_info() -> Dict[str, str]:
"""
Return a dictionary containing key-value pairs for the information items
from the distro release file data source of the current OS distribution.
@ -546,8 +551,7 @@ def uname_info():
return _distro.uname_info()
def os_release_attr(attribute):
# type: (str) -> str
def os_release_attr(attribute: str) -> str:
"""
Return a single named information item from the os-release file data source
of the current OS distribution.
@ -566,8 +570,7 @@ def os_release_attr(attribute):
return _distro.os_release_attr(attribute)
def lsb_release_attr(attribute):
# type: (str) -> str
def lsb_release_attr(attribute: str) -> str:
"""
Return a single named information item from the lsb_release command output
data source of the current OS distribution.
@ -587,8 +590,7 @@ def lsb_release_attr(attribute):
return _distro.lsb_release_attr(attribute)
def distro_release_attr(attribute):
# type: (str) -> str
def distro_release_attr(attribute: str) -> str:
"""
Return a single named information item from the distro release file
data source of the current OS distribution.
@ -607,8 +609,7 @@ def distro_release_attr(attribute):
return _distro.distro_release_attr(attribute)
def uname_attr(attribute):
# type: (str) -> str
def uname_attr(attribute: str) -> str:
"""
Return a single named information item from the distro release file
data source of the current OS distribution.
@ -629,25 +630,23 @@ try:
from functools import cached_property
except ImportError:
# Python < 3.8
class cached_property(object): # type: ignore
class cached_property: # type: ignore
"""A version of @property which caches the value. On access, it calls the
underlying function and sets the value in `__dict__` so future accesses
will not re-call the property.
"""
def __init__(self, f):
# type: (Callable[[Any], Any]) -> None
def __init__(self, f: Callable[[Any], Any]) -> None:
self._fname = f.__name__
self._f = f
def __get__(self, obj, owner):
# type: (Any, Type[Any]) -> Any
assert obj is not None, "call {} on an instance".format(self._fname)
def __get__(self, obj: Any, owner: Type[Any]) -> Any:
assert obj is not None, f"call {self._fname} on an instance"
ret = obj.__dict__[self._fname] = self._f(obj)
return ret
class LinuxDistribution(object):
class LinuxDistribution:
"""
Provides information about a OS distribution.
@ -667,13 +666,13 @@ class LinuxDistribution(object):
def __init__(
self,
include_lsb=True,
os_release_file="",
distro_release_file="",
include_uname=True,
root_dir=None,
):
# type: (bool, str, str, bool, Optional[str]) -> None
include_lsb: Optional[bool] = None,
os_release_file: str = "",
distro_release_file: str = "",
include_uname: Optional[bool] = None,
root_dir: Optional[str] = None,
include_oslevel: Optional[bool] = None,
) -> None:
"""
The initialization method of this class gathers information from the
available data sources, and stores that in private instance attributes.
@ -713,7 +712,13 @@ class LinuxDistribution(object):
be empty.
* ``root_dir`` (string): The absolute path to the root directory to use
to find distro-related information files.
to find distro-related information files. Note that ``include_*``
parameters must not be enabled in combination with ``root_dir``.
* ``include_oslevel`` (bool): Controls whether (AIX) oslevel command
output is included as a data source. If the oslevel command is not
available in the program execution path the data source will be
empty.
Public instance attributes:
@ -732,9 +737,20 @@ class LinuxDistribution(object):
parameter. This controls whether the uname information will
be loaded.
* ``include_oslevel`` (bool): The result of the ``include_oslevel``
parameter. This controls whether (AIX) oslevel information will be
loaded.
* ``root_dir`` (string): The result of the ``root_dir`` parameter.
The absolute path to the root directory to use to find distro-related
information files.
Raises:
* :py:exc:`IOError`: Some I/O issue with an os-release file or distro
* :py:exc:`ValueError`: Initialization parameters combination is not
supported.
* :py:exc:`OSError`: Some I/O issue with an os-release file or distro
release file.
* :py:exc:`UnicodeError`: A data source has unexpected characters or
@ -764,11 +780,24 @@ class LinuxDistribution(object):
self.os_release_file = usr_lib_os_release_file
self.distro_release_file = distro_release_file or "" # updated later
self.include_lsb = include_lsb
self.include_uname = include_uname
def __repr__(self):
# type: () -> str
is_root_dir_defined = root_dir is not None
if is_root_dir_defined and (include_lsb or include_uname or include_oslevel):
raise ValueError(
"Including subprocess data sources from specific root_dir is disallowed"
" to prevent false information"
)
self.include_lsb = (
include_lsb if include_lsb is not None else not is_root_dir_defined
)
self.include_uname = (
include_uname if include_uname is not None else not is_root_dir_defined
)
self.include_oslevel = (
include_oslevel if include_oslevel is not None else not is_root_dir_defined
)
def __repr__(self) -> str:
"""Return repr of all info"""
return (
"LinuxDistribution("
@ -776,14 +805,18 @@ class LinuxDistribution(object):
"distro_release_file={self.distro_release_file!r}, "
"include_lsb={self.include_lsb!r}, "
"include_uname={self.include_uname!r}, "
"include_oslevel={self.include_oslevel!r}, "
"root_dir={self.root_dir!r}, "
"_os_release_info={self._os_release_info!r}, "
"_lsb_release_info={self._lsb_release_info!r}, "
"_distro_release_info={self._distro_release_info!r}, "
"_uname_info={self._uname_info!r})".format(self=self)
"_uname_info={self._uname_info!r}, "
"_oslevel_info={self._oslevel_info!r})".format(self=self)
)
def linux_distribution(self, full_distribution_name=True):
# type: (bool) -> Tuple[str, str, str]
def linux_distribution(
self, full_distribution_name: bool = True
) -> Tuple[str, str, str]:
"""
Return information about the OS distribution that is compatible
with Python's :func:`platform.linux_distribution`, supporting a subset
@ -797,15 +830,13 @@ class LinuxDistribution(object):
self._os_release_info.get("release_codename") or self.codename(),
)
def id(self):
# type: () -> str
def id(self) -> str:
"""Return the distro ID of the OS distribution, as a string.
For details, see :func:`distro.id`.
"""
def normalize(distro_id, table):
# type: (str, Dict[str, str]) -> str
def normalize(distro_id: str, table: Dict[str, str]) -> str:
distro_id = distro_id.lower().replace(" ", "_")
return table.get(distro_id, distro_id)
@ -827,8 +858,7 @@ class LinuxDistribution(object):
return ""
def name(self, pretty=False):
# type: (bool) -> str
def name(self, pretty: bool = False) -> str:
"""
Return the name of the OS distribution, as a string.
@ -848,11 +878,10 @@ class LinuxDistribution(object):
name = self.distro_release_attr("name") or self.uname_attr("name")
version = self.version(pretty=True)
if version:
name = name + " " + version
name = f"{name} {version}"
return name or ""
def version(self, pretty=False, best=False):
# type: (bool, bool) -> str
def version(self, pretty: bool = False, best: bool = False) -> str:
"""
Return the version of the OS distribution, as a string.
@ -870,7 +899,10 @@ class LinuxDistribution(object):
).get("version_id", ""),
self.uname_attr("release"),
]
if self.id() == "debian" or "debian" in self.like().split():
if self.uname_attr("id").startswith("aix"):
# On AIX platforms, prefer oslevel command output.
versions.insert(0, self.oslevel_info())
elif self.id() == "debian" or "debian" in self.like().split():
# On Debian-like, add debian_version file content to candidates list.
versions.append(self._debian_version)
version = ""
@ -888,11 +920,10 @@ class LinuxDistribution(object):
version = v
break
if pretty and version and self.codename():
version = "{0} ({1})".format(version, self.codename())
version = f"{version} ({self.codename()})"
return version
def version_parts(self, best=False):
# type: (bool) -> Tuple[str, str, str]
def version_parts(self, best: bool = False) -> Tuple[str, str, str]:
"""
Return the version of the OS distribution, as a tuple of version
numbers.
@ -908,8 +939,7 @@ class LinuxDistribution(object):
return major, minor or "", build_number or ""
return "", "", ""
def major_version(self, best=False):
# type: (bool) -> str
def major_version(self, best: bool = False) -> str:
"""
Return the major version number of the current distribution.
@ -917,8 +947,7 @@ class LinuxDistribution(object):
"""
return self.version_parts(best)[0]
def minor_version(self, best=False):
# type: (bool) -> str
def minor_version(self, best: bool = False) -> str:
"""
Return the minor version number of the current distribution.
@ -926,8 +955,7 @@ class LinuxDistribution(object):
"""
return self.version_parts(best)[1]
def build_number(self, best=False):
# type: (bool) -> str
def build_number(self, best: bool = False) -> str:
"""
Return the build number of the current distribution.
@ -935,8 +963,7 @@ class LinuxDistribution(object):
"""
return self.version_parts(best)[2]
def like(self):
# type: () -> str
def like(self) -> str:
"""
Return the IDs of distributions that are like the OS distribution.
@ -944,8 +971,7 @@ class LinuxDistribution(object):
"""
return self.os_release_attr("id_like") or ""
def codename(self):
# type: () -> str
def codename(self) -> str:
"""
Return the codename of the OS distribution.
@ -962,8 +988,7 @@ class LinuxDistribution(object):
or ""
)
def info(self, pretty=False, best=False):
# type: (bool, bool) -> InfoDict
def info(self, pretty: bool = False, best: bool = False) -> InfoDict:
"""
Return certain machine-readable information about the OS
distribution.
@ -982,8 +1007,7 @@ class LinuxDistribution(object):
codename=self.codename(),
)
def os_release_info(self):
# type: () -> Dict[str, str]
def os_release_info(self) -> Dict[str, str]:
"""
Return a dictionary containing key-value pairs for the information
items from the os-release file data source of the OS distribution.
@ -992,8 +1016,7 @@ class LinuxDistribution(object):
"""
return self._os_release_info
def lsb_release_info(self):
# type: () -> Dict[str, str]
def lsb_release_info(self) -> Dict[str, str]:
"""
Return a dictionary containing key-value pairs for the information
items from the lsb_release command data source of the OS
@ -1003,8 +1026,7 @@ class LinuxDistribution(object):
"""
return self._lsb_release_info
def distro_release_info(self):
# type: () -> Dict[str, str]
def distro_release_info(self) -> Dict[str, str]:
"""
Return a dictionary containing key-value pairs for the information
items from the distro release file data source of the OS
@ -1014,8 +1036,7 @@ class LinuxDistribution(object):
"""
return self._distro_release_info
def uname_info(self):
# type: () -> Dict[str, str]
def uname_info(self) -> Dict[str, str]:
"""
Return a dictionary containing key-value pairs for the information
items from the uname command data source of the OS distribution.
@ -1024,8 +1045,13 @@ class LinuxDistribution(object):
"""
return self._uname_info
def os_release_attr(self, attribute):
# type: (str) -> str
def oslevel_info(self) -> str:
"""
Return AIX' oslevel command output.
"""
return self._oslevel_info
def os_release_attr(self, attribute: str) -> str:
"""
Return a single named information item from the os-release file data
source of the OS distribution.
@ -1034,8 +1060,7 @@ class LinuxDistribution(object):
"""
return self._os_release_info.get(attribute, "")
def lsb_release_attr(self, attribute):
# type: (str) -> str
def lsb_release_attr(self, attribute: str) -> str:
"""
Return a single named information item from the lsb_release command
output data source of the OS distribution.
@ -1044,8 +1069,7 @@ class LinuxDistribution(object):
"""
return self._lsb_release_info.get(attribute, "")
def distro_release_attr(self, attribute):
# type: (str) -> str
def distro_release_attr(self, attribute: str) -> str:
"""
Return a single named information item from the distro release file
data source of the OS distribution.
@ -1054,8 +1078,7 @@ class LinuxDistribution(object):
"""
return self._distro_release_info.get(attribute, "")
def uname_attr(self, attribute):
# type: (str) -> str
def uname_attr(self, attribute: str) -> str:
"""
Return a single named information item from the uname command
output data source of the OS distribution.
@ -1065,8 +1088,7 @@ class LinuxDistribution(object):
return self._uname_info.get(attribute, "")
@cached_property
def _os_release_info(self):
# type: () -> Dict[str, str]
def _os_release_info(self) -> Dict[str, str]:
"""
Get the information items from the specified os-release file.
@ -1074,13 +1096,12 @@ class LinuxDistribution(object):
A dictionary containing all information items.
"""
if os.path.isfile(self.os_release_file):
with open(self.os_release_file) as release_file:
with open(self.os_release_file, encoding="utf-8") as release_file:
return self._parse_os_release_content(release_file)
return {}
@staticmethod
def _parse_os_release_content(lines):
# type: (TextIO) -> Dict[str, str]
def _parse_os_release_content(lines: TextIO) -> Dict[str, str]:
"""
Parse the lines of an os-release file.
@ -1097,16 +1118,6 @@ class LinuxDistribution(object):
lexer = shlex.shlex(lines, posix=True)
lexer.whitespace_split = True
# The shlex module defines its `wordchars` variable using literals,
# making it dependent on the encoding of the Python source file.
# In Python 2.6 and 2.7, the shlex source file is encoded in
# 'iso-8859-1', and the `wordchars` variable is defined as a byte
# string. This causes a UnicodeDecodeError to be raised when the
# parsed content is a unicode object. The following fix resolves that
# (... but it should be fixed in shlex...):
if sys.version_info[0] == 2 and isinstance(lexer.wordchars, bytes):
lexer.wordchars = lexer.wordchars.decode("iso-8859-1")
tokens = list(lexer)
for token in tokens:
# At this point, all shell-like parsing has been done (i.e.
@ -1140,8 +1151,7 @@ class LinuxDistribution(object):
return props
@cached_property
def _lsb_release_info(self):
# type: () -> Dict[str, str]
def _lsb_release_info(self) -> Dict[str, str]:
"""
Get the information items from the lsb_release command output.
@ -1150,19 +1160,17 @@ class LinuxDistribution(object):
"""
if not self.include_lsb:
return {}
with open(os.devnull, "wb") as devnull:
try:
cmd = ("lsb_release", "-a")
stdout = subprocess.check_output(cmd, stderr=devnull)
# Command not found or lsb_release returned error
except (OSError, subprocess.CalledProcessError):
return {}
try:
cmd = ("lsb_release", "-a")
stdout = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
# Command not found or lsb_release returned error
except (OSError, subprocess.CalledProcessError):
return {}
content = self._to_str(stdout).splitlines()
return self._parse_lsb_release_content(content)
@staticmethod
def _parse_lsb_release_content(lines):
# type: (Iterable[str]) -> Dict[str, str]
def _parse_lsb_release_content(lines: Iterable[str]) -> Dict[str, str]:
"""
Parse the output of the lsb_release command.
@ -1186,31 +1194,39 @@ class LinuxDistribution(object):
return props
@cached_property
def _uname_info(self):
# type: () -> Dict[str, str]
def _uname_info(self) -> Dict[str, str]:
if not self.include_uname:
return {}
with open(os.devnull, "wb") as devnull:
try:
cmd = ("uname", "-rs")
stdout = subprocess.check_output(cmd, stderr=devnull)
except OSError:
return {}
try:
cmd = ("uname", "-rs")
stdout = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
except OSError:
return {}
content = self._to_str(stdout).splitlines()
return self._parse_uname_content(content)
@cached_property
def _debian_version(self):
# type: () -> str
def _oslevel_info(self) -> str:
if not self.include_oslevel:
return ""
try:
stdout = subprocess.check_output("oslevel", stderr=subprocess.DEVNULL)
except (OSError, subprocess.CalledProcessError):
return ""
return self._to_str(stdout).strip()
@cached_property
def _debian_version(self) -> str:
try:
with open(os.path.join(self.etc_dir, "debian_version")) as fp:
with open(
os.path.join(self.etc_dir, "debian_version"), encoding="ascii"
) as fp:
return fp.readline().rstrip()
except (OSError, IOError):
except FileNotFoundError:
return ""
@staticmethod
def _parse_uname_content(lines):
# type: (Sequence[str]) -> Dict[str, str]
def _parse_uname_content(lines: Sequence[str]) -> Dict[str, str]:
if not lines:
return {}
props = {}
@ -1229,23 +1245,12 @@ class LinuxDistribution(object):
return props
@staticmethod
def _to_str(text):
# type: (Union[bytes, str]) -> str
def _to_str(bytestring: bytes) -> str:
encoding = sys.getfilesystemencoding()
encoding = "utf-8" if encoding == "ascii" else encoding
if sys.version_info[0] >= 3:
if isinstance(text, bytes):
return text.decode(encoding)
else:
if isinstance(text, unicode): # noqa
return text.encode(encoding)
return text
return bytestring.decode(encoding)
@cached_property
def _distro_release_info(self):
# type: () -> Dict[str, str]
def _distro_release_info(self) -> Dict[str, str]:
"""
Get the information items from the specified distro release file.
@ -1262,14 +1267,14 @@ class LinuxDistribution(object):
# file), because we want to use what was specified as best as
# possible.
match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename)
if "name" in distro_info and "cloudlinux" in distro_info["name"].lower():
distro_info["id"] = "cloudlinux"
elif match:
distro_info["id"] = match.group(1)
return distro_info
else:
try:
basenames = os.listdir(self.etc_dir)
basenames = [
basename
for basename in os.listdir(self.etc_dir)
if basename not in _DISTRO_RELEASE_IGNORE_BASENAMES
and os.path.isfile(os.path.join(self.etc_dir, basename))
]
# We sort for repeatability in cases where there are multiple
# distro specific files; e.g. CentOS, Oracle, Enterprise all
# containing `redhat-release` on top of their own.
@ -1279,42 +1284,31 @@ class LinuxDistribution(object):
# sure about the *-release files. Check common entries of
# /etc for information. If they turn out to not be there the
# error is handled in `_parse_distro_release_file()`.
basenames = [
"SuSE-release",
"arch-release",
"base-release",
"centos-release",
"fedora-release",
"gentoo-release",
"mageia-release",
"mandrake-release",
"mandriva-release",
"mandrivalinux-release",
"manjaro-release",
"oracle-release",
"redhat-release",
"rocky-release",
"sl-release",
"slackware-version",
]
basenames = _DISTRO_RELEASE_BASENAMES
for basename in basenames:
if basename in _DISTRO_RELEASE_IGNORE_BASENAMES:
continue
match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename)
if match:
filepath = os.path.join(self.etc_dir, basename)
distro_info = self._parse_distro_release_file(filepath)
if "name" in distro_info:
# The name is always present if the pattern matches
self.distro_release_file = filepath
distro_info["id"] = match.group(1)
if "cloudlinux" in distro_info["name"].lower():
distro_info["id"] = "cloudlinux"
return distro_info
return {}
if match is None:
continue
filepath = os.path.join(self.etc_dir, basename)
distro_info = self._parse_distro_release_file(filepath)
# The name is always present if the pattern matches.
if "name" not in distro_info:
continue
self.distro_release_file = filepath
break
else: # the loop didn't "break": no candidate.
return {}
if match is not None:
distro_info["id"] = match.group(1)
# CloudLinux < 7: manually enrich info with proper id.
if "cloudlinux" in distro_info.get("name", "").lower():
distro_info["id"] = "cloudlinux"
return distro_info
def _parse_distro_release_file(self, filepath):
# type: (str) -> Dict[str, str]
def _parse_distro_release_file(self, filepath: str) -> Dict[str, str]:
"""
Parse a distro release file.
@ -1326,19 +1320,18 @@ class LinuxDistribution(object):
A dictionary containing all information items.
"""
try:
with open(filepath) as fp:
with open(filepath, encoding="utf-8") as fp:
# Only parse the first line. For instance, on SLES there
# are multiple lines. We don't want them...
return self._parse_distro_release_content(fp.readline())
except (OSError, IOError):
except OSError:
# Ignore not being able to read a specific, seemingly version
# related file.
# See https://github.com/python-distro/distro/issues/162
return {}
@staticmethod
def _parse_distro_release_content(line):
# type: (str) -> Dict[str, str]
def _parse_distro_release_content(line: str) -> Dict[str, str]:
"""
Parse a line from a distro release file.
@ -1366,8 +1359,7 @@ class LinuxDistribution(object):
_distro = LinuxDistribution()
def main():
# type: () -> None
def main() -> None:
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler(sys.stdout))
@ -1389,7 +1381,10 @@ def main():
if args.root_dir:
dist = LinuxDistribution(
include_lsb=False, include_uname=False, root_dir=args.root_dir
include_lsb=False,
include_uname=False,
include_oslevel=False,
root_dir=args.root_dir,
)
else:
dist = _distro

@ -58,8 +58,6 @@ lib/ansible/module_utils/compat/selinux.py import-3.12!skip # pass/fail depends
lib/ansible/module_utils/compat/selinux.py pylint:unidiomatic-typecheck
lib/ansible/module_utils/distro/_distro.py no-assert
lib/ansible/module_utils/distro/_distro.py pep8!skip # bundled code we don't want to modify
lib/ansible/module_utils/distro/_distro.py pylint:undefined-variable # ignore bundled
lib/ansible/module_utils/distro/_distro.py pylint:using-constant-test # bundled code we don't want to modify
lib/ansible/module_utils/distro/__init__.py empty-init # breaks namespacing, bundled, do not override
lib/ansible/module_utils/facts/__init__.py empty-init # breaks namespacing, deprecate and eventually remove
lib/ansible/module_utils/powershell/Ansible.ModuleUtils.ArgvParser.psm1 pslint:PSUseApprovedVerbs

Loading…
Cancel
Save