]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
mkosi: add helper to reduce duplicated code
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 10 Jun 2022 14:42:47 +0000 (16:42 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 20 Jun 2022 17:00:00 +0000 (19:00 +0200)
The same logic was used for dnf/tdnf/rpm/dpkg/apt, so let's split
it out to a helper.

I opted to use full paths with "/". Such paths are easier to read
and we avoid the risk of removing something from the host if somebody
uses an absolute path by mistake.

mkosi/__init__.py

index 8123ef83fa0a10acb706b7e8e49a93b38354d99c..c47b718a646c7b1a2adfac43c25d7fea6ecb888e 100644 (file)
@@ -1943,111 +1943,96 @@ def make_rpm_list(args: MkosiArgs, packages: Set[str], do_run_build_script: bool
     return packages
 
 
-def clean_dnf_metadata(root: Path, always: bool) -> None:
-    """Remove dnf metadata if /bin/dnf is not present in the image
+def flatten(lists: Iterable[Iterable[T]]) -> List[T]:
+    """Flatten a sequence of sequences into a single list."""
+    return list(itertools.chain.from_iterable(lists))
 
-    If dnf is not installed, there doesn't seem to be much use in
-    keeping the dnf metadata, since it's not usable from within the
-    image anyway.
-    """
-    paths = [
-        root / "var/lib/dnf",
-        *root.glob("var/log/dnf.*"),
-        *root.glob("var/log/hawkey.*"),
-        root / "var/cache/dnf",
-    ]
 
-    cond = always or not os.access(root / "bin/dnf", os.F_OK, follow_symlinks=False)
+def clean_paths(
+        root: Path,
+        globs: Sequence[str],
+        tool: str,
+        always: bool) -> None:
+    """Remove globs under root if always or if tool is not found under root."""
 
-    if not cond or not any(path.exists() for path in paths):
+    tool = root / tool.lstrip('/')
+    cond = always or not os.access(tool, os.F_OK, follow_symlinks=False)
+
+    paths = flatten(root.glob(glob.lstrip('/')) for glob in globs)
+
+    if not cond or not paths:
         return
 
-    with complete_step("Cleaning dnf metadata…"):
+    with complete_step(f"Cleaning {tool.name} metadata…"):
         for path in paths:
             unlink_try_hard(path)
 
 
-def clean_yum_metadata(root: Path, always: bool) -> None:
-    """Remove yum metadata if /bin/yum is not present in the image"""
+def clean_dnf_metadata(root: Path, always: bool) -> None:
+    """Remove dnf metadata if /bin/dnf is not present in the image
+
+    If dnf is not installed, there doesn't seem to be much use in keeping the
+    dnf metadata, since it's not usable from within the image anyway.
+    """
     paths = [
-        root / "var/lib/yum",
-        *root.glob("var/log/yum.*"),
-        root / "var/cache/yum",
+        "/var/lib/dnf",
+        "/var/log/dnf.*",
+        "/var/log/hawkey.*",
+        "/var/cache/dnf",
     ]
 
-    cond = always or not os.access(root / "bin/yum", os.F_OK, follow_symlinks=False)
+    clean_paths(root, paths, tool='/bin/dnf', always=always)
 
-    if not cond or not any(path.exists() for path in paths):
-        return
 
-    with complete_step("Cleaning yum metadata…"):
-        for path in paths:
-            unlink_try_hard(path)
+def clean_yum_metadata(root: Path, always: bool) -> None:
+    """Remove yum metadata if /bin/yum is not present in the image"""
+    paths = [
+        "/var/lib/yum",
+        "/var/log/yum.*",
+        "/var/cache/yum",
+    ]
+
+    clean_paths(root, paths, tool='/bin/yum', always=always)
 
 
 def clean_rpm_metadata(root: Path, always: bool) -> None:
     """Remove rpm metadata if /bin/rpm is not present in the image"""
-    path = root / "var/lib/rpm"
-
-    cond = always or not os.access(root / "bin/rpm", os.F_OK, follow_symlinks=False)
-
-    if not cond or not path.exists():
-        return
+    paths = [
+        "/var/lib/rpm",
+    ]
 
-    with complete_step("Cleaning rpm metadata…"):
-        unlink_try_hard(path)
+    clean_paths(root, paths, tool='/bin/rpm', always=always)
 
 
 def clean_tdnf_metadata(root: Path, always: bool) -> None:
-    """Remove tdnf metadata if /bin/tdnf is not present in the image"""
+    """Remove tdnf metadata if /usr/bin/tdnf is not present in the image"""
     paths = [
-        *root.glob("var/log/tdnf.*"),
-        root / "var/cache/tdnf",
+        "/var/log/tdnf.*",
+        "/var/cache/tdnf",
     ]
 
-    cond = always or not os.access(root / "usr/bin/tdnf", os.F_OK, follow_symlinks=False)
-
-    if not cond or not any(path.exists() for path in paths):
-        return
-
-    with complete_step("Cleaning tdnf metadata…"):
-        for path in paths:
-            unlink_try_hard(path)
+    clean_paths(root, paths, tool='/usr/bin/tdnf', always=always)
 
 
 def clean_apt_metadata(root: Path, always: bool) -> None:
     """Remove apt metadata if /usr/bin/apt is not present in the image"""
     paths = [
-        root / "var/lib/apt",
-        root / "var/log/apt",
-        root / "var/cache/apt",
+        "/var/lib/apt",
+        "/var/log/apt",
+        "/var/cache/apt",
     ]
 
-    cond = always or not os.access(root / "usr/bin/apt", os.F_OK, follow_symlinks=False)
-
-    if not cond or not any(path.exists() for path in paths):
-        return
-
-    with complete_step("Cleaning apt metadata…"):
-        for path in paths:
-            unlink_try_hard(path)
+    clean_paths(root, paths, tool='/usr/bin/apt', always=always)
 
 
 def clean_dpkg_metadata(root: Path, always: bool) -> None:
     """Remove dpkg metadata if /usr/bin/dpkg is not present in the image"""
     paths = [
-        root / "var/lib/dpkg",
-        root / "var/log/dpkg.log",
+        "/var/lib/dpkg",
+        "/var/log/dpkg.log",
     ]
 
-    cond = always or not os.access(root / "usr/bin/dpkg", os.F_OK, follow_symlinks=False)
-
-    if not cond or not any(path.exists() for path in paths):
-        return
-
-    with complete_step("Cleaning dpkg metadata…"):
-        for path in paths:
-            unlink_try_hard(path)
+    clean_paths(root, paths, tool='/usr/bin/dpkg', always=always)
 
 
 def clean_package_manager_metadata(args: MkosiArgs, root: Path) -> None:
@@ -2063,12 +2048,13 @@ def clean_package_manager_metadata(args: MkosiArgs, root: Path) -> None:
 
     # we try then all: metadata will only be touched if any of them are in the
     # final image
-    clean_dnf_metadata(root, always=args.clean_package_metadata is True)
-    clean_yum_metadata(root, always=args.clean_package_metadata is True)
-    clean_rpm_metadata(root, always=args.clean_package_metadata is True)
-    clean_tdnf_metadata(root, always=args.clean_package_metadata is True)
-    clean_apt_metadata(root, always=args.clean_package_metadata is True)
-    clean_dpkg_metadata(root, always=args.clean_package_metadata is True)
+    always = args.clean_package_metadata is True
+    clean_dnf_metadata(root, always=always)
+    clean_yum_metadata(root, always=always)
+    clean_rpm_metadata(root, always=always)
+    clean_tdnf_metadata(root, always=always)
+    clean_apt_metadata(root, always=always)
+    clean_dpkg_metadata(root, always=always)
     # FIXME: implement cleanup for other package managers: swupd, pacman