From 9f2789dc20ed97a6282f30a1e37973cfb43c65b5 Mon Sep 17 00:00:00 2001 From: Mürsel Türk Date: Mon, 19 Sep 2022 20:31:40 +0200 Subject: Add support for gentoo linux --- inspect.py | 8 +++++-- tools/inspect_apps.py | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++ tools/inspect_os.py | 8 +++++++ 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/inspect.py b/inspect.py index aba1731..19e52f9 100755 --- a/inspect.py +++ b/inspect.py @@ -10,6 +10,7 @@ from tools.inspect_apps import ( list_applications_apk, list_applications_dpkg, list_applications_pacman, + list_applications_portage, list_applications_rpm, list_applications_windows ) @@ -20,8 +21,9 @@ fmt = "{asctime}, {name}:{lineno}:{funcName}(), {levelname}, {message}" logging.basicConfig(level=logging.DEBUG, format=fmt, style="{") APK = re.compile(r"^(Alpine).*$") -DEB = re.compile(r"^(Debian|Ubuntu|Linux\sMint|LMDE).*$") +DPKG = re.compile(r"^(Debian|Ubuntu|Linux\sMint|LMDE).*$") PACMAN = re.compile(r"^(Arch|Manjaro).*$") +PORTAGE = re.compile(r"^(Gentoo).*$") RPM = re.compile(r"^(CentOS|AlmaLinux|Scientific|Rocky|Oracle|openSUSE|Fedora).*$") # noqa WIN = re.compile(r"^(Microsoft|Windows).*$") @@ -70,10 +72,12 @@ def main(vmdk_path): for fspath, _ in fs_mps: if APK.match(os_name): apps = list_applications_apk(fspath) - elif DEB.match(os_name): + elif DPKG.match(os_name): apps = list_applications_dpkg(fspath) elif PACMAN.match(os_name): apps = list_applications_pacman(fspath) + elif PORTAGE.match(os_name): + apps = list_applications_portage(fspath) elif RPM.match(os_name): apps = list_applications_rpm(fspath) elif WIN.match(os_name): diff --git a/tools/inspect_apps.py b/tools/inspect_apps.py index 613649b..a1a1157 100644 --- a/tools/inspect_apps.py +++ b/tools/inspect_apps.py @@ -9,6 +9,7 @@ __all__ = [ "list_applications_apk", "list_applications_dpkg", "list_applications_pacman", + "list_applications_portage", "list_applications_rpm", "list_applications_windows" ] @@ -221,6 +222,63 @@ def list_applications_pacman(path): return pkgs +@log +def list_applications_portage(path): + """Find all packages installed on the linux distribution Gentoo Linux. + + See also: + https://wiki.gentoo.org/wiki/Portage + + Args: + path (str): Path to the mounted filesystem. + + Returns: + List of packages. For example: + [{'name': 'sys-devel/bison', 'version': '3.8.2'}, ...] + """ + portage_db = None + + locations = [ + "var/db/pkg", + "db/pkg" # separated /var partition + ] + + for location in locations: + db = os.path.join(path, location) + if os.path.exists(db): + portage_db = db + break + + # btrfs? + if portage_db is None: + for dir in subdirs(path): + new_path = os.path.join(path, dir) + for location in locations: + db = os.path.join(new_path, location) + if os.path.exists(db): + portage_db = db + break + if portage_db is not None: + break + + if portage_db is None: + L.debug("portage database not found") + return [] + + pkgs = [] + for cat in subdirs(portage_db): + for pkg in subdirs(os.path.join(portage_db, cat)): + # https://projects.gentoo.org/pms/8/pms.html#x1-150003 + if m := re.match(r"^(.+)-(\d.*)$", pkg): + name, version = m.groups() + pkgs.append({ + "name": "/".join([cat, name]), + "version": version + }) + + return pkgs + + @log def list_applications_rpm(path): """Find all packages installed on a rpm-based linux distribution. diff --git a/tools/inspect_os.py b/tools/inspect_os.py index 9848c2e..892ca8a 100644 --- a/tools/inspect_os.py +++ b/tools/inspect_os.py @@ -61,6 +61,14 @@ def get_linux_os_info(path): # AlmaLinux 8.* and Rocky Linux 8.* also have centos-release. if m := re.match(r"^(.*)\srelease\s(.*)$", f.read()): name, version = m.groups() + elif "gentoo-release" in release_files: + # Gentoo now has a VERSION_ID tag in os-release, which did not exist + # before. See also https://bugs.gentoo.org/788190. For consistency, + # gentoo-release is parsed before os-release at this point. + L.debug("parsing %s", release_files["gentoo-release"]) + with open(release_files["gentoo-release"]) as f: + if m := re.match(r"^(Gentoo).*release\s(.*)$", f.read()): + name, version = m.groups() elif "os-release" in release_files: L.debug("parsing %s", release_files["os-release"]) with open(release_files["os-release"]) as f: -- cgit v1.2.3-55-g7522