Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ The `distro` package implements a robust and inclusive way of retrieving the
information about a distribution based on new standards and old methods,
namely from these data sources (from high to low precedence):

* The os-release file `/etc/os-release`, if present.
* The os-release file `/etc/os-release` if present, with a fall-back on `/usr/lib/os-release` if needed.
* The output of the `lsb_release` command, if available.
* The distro release file (`/etc/*(-|_)(release|version)`), if present.
* The `uname` command for BSD based distrubtions.
Expand Down
23 changes: 21 additions & 2 deletions distro.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@


_UNIXCONFDIR = os.environ.get("UNIXCONFDIR", "/etc")
_UNIXUSRLIBDIR = os.environ.get("UNIXUSRLIBDIR", "/usr/lib")
_OS_RELEASE_BASENAME = "os-release"

#: Translation table for normalizing the "ID" attribute defined in os-release
Expand Down Expand Up @@ -714,9 +715,27 @@ def __init__(
"""
self.root_dir = root_dir
self.etc_dir = os.path.join(root_dir, "etc") if root_dir else _UNIXCONFDIR
self.os_release_file = os_release_file or os.path.join(
self.etc_dir, _OS_RELEASE_BASENAME
self.usr_lib_dir = (
os.path.join(root_dir, "usr/lib") if root_dir else _UNIXUSRLIBDIR
)

if os_release_file:
self.os_release_file = os_release_file
else:
etc_dir_os_release_file = os.path.join(self.etc_dir, _OS_RELEASE_BASENAME)
usr_lib_os_release_file = os.path.join(
self.usr_lib_dir, _OS_RELEASE_BASENAME
)

# NOTE: The idea is to respect order **and** have it set
# at all times for API backwards compatibility.
if os.path.isfile(etc_dir_os_release_file) or not os.path.isfile(
usr_lib_os_release_file
):
self.os_release_file = etc_dir_os_release_file
else:
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
Expand Down
5 changes: 3 additions & 2 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ If you want to add test data for more distributions, please
create an issue in the `distro issue tracker`_
and provide the following information in the issue:

* The content of the `/etc/os-release` file, if any.
* The os-release file `/etc/os-release` if present, with a fall-back on `/usr/lib/os-release` if needed.
* The file names and content of the `/etc/*release` and `/etc/*version` files, if any.
* The output of the command: `lsb_release -a`, if available.
* The file names and content of any other files you are aware of that provide
Expand Down Expand Up @@ -184,7 +184,8 @@ Os-release file
===============

The os-release file is looked up using the path name ``/etc/os-release``. Its
optional additional location ``/usr/lib/os-release`` is ignored.
optional additional location ``/usr/lib/os-release`` would be looked up for if
the former couldn't be read.

The os-release file is expected to be encoded in UTF-8.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
NAME="usr_lib_os-release_only"
ID=usrlibosreleaseonly
PRETTY_NAME="/usr/lib/os-release only"
19 changes: 18 additions & 1 deletion tests/test_distro.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import distro

RELATIVE_UNIXCONFDIR = distro._UNIXCONFDIR[1:]
RELATIVE_UNIXUSRLIBDIR = distro._UNIXUSRLIBDIR[1:]
MODULE_DISTRO = distro._distro


Expand Down Expand Up @@ -118,17 +119,20 @@ def setup_method(self, test_method):
# changes it:
self._saved_path = os.environ["PATH"]
self._saved_UNIXCONFDIR = distro._UNIXCONFDIR
self._saved_UNIXUSRLIBDIR = distro._UNIXUSRLIBDIR

def teardown_method(self, test_method):
os.environ["PATH"] = self._saved_path
distro._UNIXCONFDIR = self._saved_UNIXCONFDIR
distro._UNIXUSRLIBDIR = self._saved_UNIXUSRLIBDIR

def _setup_for_distro(self, distro_root):
distro_bin = os.path.join(distro_root, "bin")
# We don't want to pick up a possibly present lsb_release in the
# distro that runs this test, so we use a PATH with only one entry:
os.environ["PATH"] = distro_bin
distro._UNIXCONFDIR = os.path.join(distro_root, RELATIVE_UNIXCONFDIR)
distro._UNIXUSRLIBDIR = os.path.join(distro_root, RELATIVE_UNIXUSRLIBDIR)


@pytest.mark.skipif(not IS_LINUX, reason="Irrelevant on non-linux")
Expand Down Expand Up @@ -708,6 +712,19 @@ def test_bad_uname(self):
assert self.distro.uname_attr("name") == ""
assert self.distro.uname_attr("release") == ""

def test_usrlibosreleaseonly(self):
self._setup_for_distro(
os.path.join(TESTDISTROS, "distro", "usrlibosreleaseonly")
)
self.distro = distro.LinuxDistribution()

desired_outcome = {
"id": "usrlibosreleaseonly",
"name": "usr_lib_os-release_only",
"pretty_name": "/usr/lib/os-release only",
}
self._test_outcome(desired_outcome)


@pytest.mark.skipif(not IS_LINUX, reason="Irrelevant on non-linux")
class TestDistroRelease:
Expand Down Expand Up @@ -2113,7 +2130,7 @@ def test_repr(self):
repr_str = repr(distro._distro)
assert "LinuxDistribution" in repr_str
for attr in MODULE_DISTRO.__dict__.keys():
if attr in ("root_dir", "etc_dir"):
if attr in ("root_dir", "etc_dir", "usr_lib_dir"):
continue
assert attr + "=" in repr_str

Expand Down