From 6426257fd0b3c5e176e2a3a29bdaa07aee0cbc0d Mon Sep 17 00:00:00 2001 From: Mürsel Türk Date: Mon, 10 Oct 2022 22:04:19 +0200 Subject: Improve detection of used package manager --- inspect.py | 42 ++++++++++++++++++------------------------ tools/inspect_os.py | 38 +++++++++++++++++++++++++++++++++----- 2 files changed, 51 insertions(+), 29 deletions(-) diff --git a/inspect.py b/inspect.py index 5f1842f..a6a3e9e 100755 --- a/inspect.py +++ b/inspect.py @@ -3,7 +3,6 @@ import argparse import logging import os -import re import sys from tools import libvmdk, libvslvm, lklfuse, nbdfuse, subfiles, unmount, rmdir @@ -37,13 +36,6 @@ if args.verbose: else: logging.basicConfig(level=logging.CRITICAL) -APK = re.compile(r"^(Alpine).*$") -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).*$") - if args.backend == "libvmdk": image_mp = libvmdk.mount(args.image) else: @@ -92,22 +84,24 @@ for k, v in fs_mps: break apps = [] -if os_name := os_info.get("name"): - for k, _ in fs_mps: - if APK.match(os_name): - apps = list_applications_apk(k) - elif DPKG.match(os_name): - apps = list_applications_dpkg(k) - elif PACMAN.match(os_name): - apps = list_applications_pacman(k) - elif PORTAGE.match(os_name): - apps = list_applications_portage(k) - elif RPM.match(os_name): - apps = list_applications_rpm(k) - elif WIN.match(os_name): - apps = list_applications_windows(k) - if apps: - break +package_manager = os_info.get("package_manager", "") +for k, _ in fs_mps: + if package_manager == "apk": + apps = list_applications_apk(k) + elif package_manager == "dpkg": + apps = list_applications_dpkg(k) + elif package_manager == "pacman": + apps = list_applications_pacman(k) + elif package_manager == "portage": + apps = list_applications_portage(k) + elif package_manager == "rpm": + apps = list_applications_rpm(k) + elif package_manager == "win": + apps = list_applications_windows(k) + else: + break + if apps: + break for k, _ in fs_mps: unmount(k) diff --git a/tools/inspect_os.py b/tools/inspect_os.py index e374464..ce03ee9 100644 --- a/tools/inspect_os.py +++ b/tools/inspect_os.py @@ -31,7 +31,8 @@ def get_linux_os_info(path): Returns: Name and version of linux distribution as a dictionary. For example: - {'name': 'CentOS Linux', 'version': '6.0 (Final)'} + {'name': 'CentOS Linux', 'version': '6.0 (Final)', + 'package_manager': 'rpm'} """ release_files = {} for root, dirs, _ in os.walk(path): @@ -54,7 +55,7 @@ def get_linux_os_info(path): L.debug("release files: %s", release_files) - name = version = "" + name = version = package_manager = "" if "centos-release" in release_files: L.debug("parsing %s", release_files["centos-release"]) # CentOS 6.* doesn't have os-release, but centos-release. @@ -63,6 +64,7 @@ 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() + package_manager = "rpm" 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, @@ -71,6 +73,7 @@ def get_linux_os_info(path): with open(release_files["gentoo-release"]) as f: if m := re.match(r"^(Gentoo).*release\s(.*)$", f.read()): name, version = m.groups() + package_manager = "portage" elif "os-release" in release_files: L.debug("parsing %s", release_files["os-release"]) with open(release_files["os-release"]) as f: @@ -86,6 +89,24 @@ def get_linux_os_info(path): # These are using a rolling release model. if not version: version = kv.get("BUILD_ID", "") + id_like = kv.get("ID_LIKE", kv.get("ID", "")) + id_like = id_like.strip().strip("'\"").split() + for i in id_like: + if i == "alpine": + package_manager = "apk" + elif i in ("debian", "ubuntu"): + package_manager = "dpkg" + elif i == "arch": + package_manager = "pacman" + elif i in ("centos", "fedora", "rhel"): + package_manager = "rpm" + elif i in ("opensuse", "suse"): + package_manager = "rpm" + elif i == "ol": # Oracle Linux 6.10 + package_manager = "rpm" + else: + continue + break elif "system-release" in release_files: # RedHat (RHEL) provides the redhat-release file. However, it does not # seem to be reliable for determining which operating system it is. @@ -95,13 +116,19 @@ def get_linux_os_info(path): with open(release_files["system-release"]) as f: if m := re.match(r"^(.*)\srelease\s(.*)$", f.read()): name, version = m.groups() + package_manager = "rpm" if not name or not version: return {} name = name.strip().strip("'\"") version = version.strip().strip("'\"") - return {"name": name, "version": version} + + return { + "name": name, + "version": version, + "package_manager": package_manager + } @log @@ -113,7 +140,8 @@ def get_windows_os_info(path): Returns: Name and version of windows distribution as a dictionary. For example: - {'name': 'Microsoft Windows XP', 'version': '5.1'} + {'name': 'Microsoft Windows XP', 'version': '5.1', + 'package_manager': 'win'} """ software = None @@ -154,4 +182,4 @@ def get_windows_os_info(path): if not name or not version: return {} - return {"name": name, "version": version} + return {"name": name, "version": version, "package_manager": "win"} -- cgit v1.2.3-55-g7522