]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Revert "Use shared package cache directory by default"
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Sat, 27 Jan 2024 15:54:44 +0000 (16:54 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Sat, 27 Jan 2024 16:34:15 +0000 (17:34 +0100)
At least pacman isn't ready just yet for cache sharing, so let's
temporarily revert this commit. We'll reintroduce it in a later
PR.

This reverts commit 98a29486b68b0aee05eefb49e129433634d4446b.

12 files changed:
mkosi/__init__.py
mkosi/config.py
mkosi/context.py
mkosi/distributions/debian.py
mkosi/installer/__init__.py
mkosi/installer/apt.py
mkosi/installer/dnf.py
mkosi/installer/pacman.py
mkosi/installer/zypper.py
mkosi/resources/mkosi.md
mkosi/user.py
tests/test_json.py

index 79dadbd1b18701a09e9d0aa08e09bba1614fc5bf..794d6011d4659fe16102725ed3be4edccf53acbd 100644 (file)
@@ -52,7 +52,6 @@ from mkosi.installer import (
     clean_package_manager_metadata,
     finalize_package_manager_mounts,
     package_manager_scripts,
-    rchown_package_manager_cache_dirs,
 )
 from mkosi.kmod import gen_required_kernel_modules, process_kernel_modules
 from mkosi.log import ARG_DEBUG, complete_step, die, log_notice, log_step
@@ -1487,8 +1486,7 @@ def build_initrd(context: Context) -> Path:
         "--cache-only", str(context.config.cache_only),
         "--output-dir", str(context.workspace / "initrd"),
         *(["--workspace-dir", str(context.config.workspace_dir)] if context.config.workspace_dir else []),
-        *(["--cache-dir", str(context.config.cache_dir)] if context.config.cache_dir else []),
-        *(["--package-cache-dir", str(context.config.package_cache_dir)] if context.config.package_cache_dir else []),
+        "--cache-dir", str(context.cache_dir),
         *(["--local-mirror", str(context.config.local_mirror)] if context.config.local_mirror else []),
         "--incremental", str(context.config.incremental),
         "--acl", str(context.config.acl),
@@ -3417,7 +3415,6 @@ def finalize_default_tools(args: Args, config: Config, *, resources: Path) -> Co
         *(["--output-dir", str(config.output_dir)] if config.output_dir else []),
         *(["--workspace-dir", str(config.workspace_dir)] if config.workspace_dir else []),
         *(["--cache-dir", str(config.cache_dir)] if config.cache_dir else []),
-        *(["--package-cache-dir", str(config.package_cache_dir)] if config.package_cache_dir else []),
         "--incremental", str(config.incremental),
         "--acl", str(config.acl),
         *([f"--package={package}" for package in config.tools_tree_packages]),
@@ -3499,16 +3496,11 @@ def run_clean(args: Args, config: Config) -> None:
             with complete_step(f"Clearing out build directory of {config.name()} image…"):
                 rmtree(*config.build_dir.iterdir())
 
-    if (
-        remove_package_cache and
-        config.package_cache_dir and
-        config.package_cache_dir.exists() and
-        any(config.package_cache_dir.iterdir())
-    ):
+    if remove_package_cache and config.cache_dir and config.cache_dir.exists() and any(config.cache_dir.iterdir()):
         with complete_step(f"Clearing out package cache of {config.name()} image…"):
             rmtree(
                 *(
-                    config.package_cache_dir / p / d
+                    config.cache_dir / p / d
                     for p in ("cache", "lib")
                     for d in ("apt", "dnf", "libdnf5", "pacman", "zypp")
                 ),
@@ -3529,26 +3521,25 @@ def run_build(args: Args, config: Config, *, resources: Path) -> None:
         if Path(d).exists():
             run(["mount", "--rbind", d, d, "--options", "ro"])
 
-    # Create these as the invoking user to make sure they're owned by the user running mkosi.
-    for p in (
-        config.output_dir,
-        config.cache_dir,
-        config.package_cache_dir_or_default(),
-        config.package_state_dir_or_default(),
-        config.build_dir,
-        config.workspace_dir,
-    ):
-        if p:
-            INVOKING_USER.mkdir(p)
-
     with (
         complete_step(f"Building {config.name()} image"),
         prepend_to_environ_path(config),
-        acl_toggle_build(config, INVOKING_USER.uid),
-        rchown_package_manager_cache_dirs(config),
     ):
+        # After tools have been mounted, check if we have what we need
         check_tools(config, Verb.build)
-        build_image(args, config, resources=resources)
+
+        # Create these as the invoking user to make sure they're owned by the user running mkosi.
+        for p in (
+            config.output_dir,
+            config.cache_dir,
+            config.build_dir,
+            config.workspace_dir,
+        ):
+            if p:
+                run(["mkdir", "--parents", p], user=INVOKING_USER.uid, group=INVOKING_USER.gid)
+
+        with acl_toggle_build(config, INVOKING_USER.uid):
+            build_image(args, config, resources=resources)
 
 
 def run_verb(args: Args, images: Sequence[Config], *, resources: Path) -> None:
index 6ed481d0bdd03ffcccf39939a39b7742287b81a0..c7db14264e262a9d624477ae2913afe4106293d6 100644 (file)
@@ -1171,7 +1171,6 @@ class Config:
     output_dir: Optional[Path]
     workspace_dir: Optional[Path]
     cache_dir: Optional[Path]
-    package_cache_dir: Optional[Path]
     build_dir: Optional[Path]
     image_id: Optional[str]
     image_version: Optional[str]
@@ -1297,17 +1296,24 @@ class Config:
         if self.workspace_dir:
             return self.workspace_dir
 
-        if (cache := INVOKING_USER.cache_dir()) and cache != Path("/var/cache"):
-            return cache
+        if (cache := os.getenv("XDG_CACHE_HOME")) and Path(cache).exists():
+            return Path(cache)
+
+        # If we're running from /home and there's a cache or output directory in /home, we want to use a workspace
+        # directory in /home as well as /home might be on a separate partition or subvolume which means that to take
+        # advantage of reflinks and such, the workspace directory has to be on the same partition/subvolume.
+        if (
+            Path.cwd().is_relative_to(INVOKING_USER.home()) and
+            (INVOKING_USER.home() / ".cache").exists() and
+            (
+                self.cache_dir and self.cache_dir.is_relative_to(INVOKING_USER.home()) or
+                self.output_dir and self.output_dir.is_relative_to(INVOKING_USER.home())
+            )
+        ):
+            return INVOKING_USER.home() / ".cache"
 
         return Path("/var/tmp")
 
-    def package_cache_dir_or_default(self) -> Path:
-        return self.package_cache_dir or INVOKING_USER.cache_dir()
-
-    def package_state_dir_or_default(self) -> Path:
-        return self.package_cache_dir or INVOKING_USER.state_dir()
-
     def tools(self) -> Path:
         return self.tools_tree or Path("/")
 
@@ -1731,15 +1737,7 @@ SETTINGS = (
         section="Output",
         parse=config_make_path_parser(required=False),
         paths=("mkosi.cache",),
-        help="Incremental cache directory",
-    ),
-    ConfigSetting(
-        dest="package_cache_dir",
-        metavar="PATH",
-        name="PackageCacheDirectory",
-        section="Output",
-        parse=config_make_path_parser(required=False),
-        help="Package cache directory",
+        help="Package cache path",
     ),
     ConfigSetting(
         dest="build_dir",
@@ -3435,7 +3433,6 @@ def summary(config: Config) -> str:
                    Output Directory: {config.output_dir_or_cwd()}
                 Workspace Directory: {config.workspace_dir_or_default()}
                     Cache Directory: {none_to_none(config.cache_dir)}
-            Package Cache Directory: {none_to_default(config.package_cache_dir)}
                     Build Directory: {none_to_none(config.build_dir)}
                            Image ID: {config.image_id}
                       Image Version: {config.image_version}
index 1f81b1383f3abbb02d53d280dcaee81d7bf26ad4..4214c421d961b3c37eda13991eb449bef724dc56 100644 (file)
@@ -37,6 +37,7 @@ class Context:
         self.pkgmngr.mkdir()
         self.packages.mkdir()
         self.install_dir.mkdir(exist_ok=True)
+        self.cache_dir.mkdir(parents=True, exist_ok=True)
 
     @property
     def root(self) -> Path:
@@ -54,6 +55,10 @@ class Context:
     def packages(self) -> Path:
         return self.workspace / "packages"
 
+    @property
+    def cache_dir(self) -> Path:
+        return self.config.cache_dir or (self.workspace / "cache")
+
     @property
     def install_dir(self) -> Path:
         return self.workspace / "dest"
index 2207179cf90400ac8eafcd1592c0efb787c8d4c0..dfdc3b9a364f47efd479a38c568e3cf63b4eb32f 100644 (file)
@@ -167,7 +167,7 @@ class Installer(DistributionInstaller):
             with (
                 # The deb paths will be in the form of "/var/cache/apt/<deb>" so we transform them to the corresponding
                 # path in mkosi's package cache directory.
-                open(context.config.package_cache_dir_or_default() / Path(deb).relative_to("/var/cache"), "rb") as i,
+                open(context.cache_dir / Path(deb).relative_to("/var"), "rb") as i,
                 tempfile.NamedTemporaryFile() as o
             ):
                 run(["dpkg-deb", "--fsys-tarfile", "/dev/stdin"], stdin=i, stdout=o, sandbox=context.sandbox())
index 4256d42b2e947d2d19fd95a2c554df6a13e075e1..3b52a02f6c903bd46d4628fceb0bdd482c2c2bdf 100644 (file)
@@ -1,17 +1,13 @@
 # SPDX-License-Identifier: LGPL-2.1+
 
-import contextlib
 import os
-from collections.abc import Iterator
 from pathlib import Path
 
-from mkosi.config import Config, ConfigFeature
+from mkosi.config import ConfigFeature
 from mkosi.context import Context
-from mkosi.log import complete_step
 from mkosi.sandbox import apivfs_cmd, finalize_crypto_mounts
 from mkosi.tree import rmtree
 from mkosi.types import PathString
-from mkosi.user import INVOKING_USER
 from mkosi.util import flatten
 
 
@@ -78,27 +74,16 @@ def finalize_package_manager_mounts(context: Context) -> list[PathString]:
     ]
 
     mounts += flatten(
-        ["--bind", context.config.package_cache_dir_or_default() / d, Path("/var/cache") / d]
-        for d in ("apt", dnf_subdir(context), "pacman/pkg", "zypp")
-        if (context.config.package_cache_dir_or_default() / d).exists()
-    )
-
-    mounts += flatten(
-        ["--bind", context.config.package_state_dir_or_default() / d, Path("/var/lib") / d]
-        for d in ("apt", dnf_subdir(context))
-        if (context.config.package_state_dir_or_default() / d).exists()
+        ["--bind", context.cache_dir / d, Path("/var") / d]
+        for d in (
+            "lib/apt",
+            "cache/apt",
+            f"cache/{dnf_subdir(context)}",
+            f"lib/{dnf_subdir(context)}",
+            "cache/pacman/pkg",
+            "cache/zypp",
+        )
+        if (context.cache_dir / d).exists()
     )
 
     return mounts
-
-
-@contextlib.contextmanager
-def rchown_package_manager_cache_dirs(config: Config) -> Iterator[None]:
-    try:
-        yield
-    finally:
-        if INVOKING_USER.is_regular_user():
-            with complete_step("Fixing ownership of package manager cache directories"):
-                for p in ("apt", "dnf", "libdnf5", "pacman", "zypp"):
-                    for d in (config.package_cache_dir_or_default(), config.package_state_dir_or_default()):
-                        INVOKING_USER.rchown(d / p)
index 465bd561753f83e146fea1872d83ea96c647b4cf..81d38961dda4625a1c0a66db1975f2cb815f94bf 100644 (file)
@@ -9,7 +9,6 @@ from mkosi.mounts import finalize_ephemeral_source_mounts
 from mkosi.run import find_binary, run
 from mkosi.sandbox import apivfs_cmd
 from mkosi.types import PathString
-from mkosi.user import INVOKING_USER
 from mkosi.util import sort_packages, umask
 
 
@@ -44,8 +43,8 @@ def setup_apt(context: Context, repos: Iterable[AptRepository]) -> None:
         (context.root / "var/lib/dpkg").mkdir(parents=True, exist_ok=True)
         (context.root / "var/lib/dpkg/status").touch()
 
-    INVOKING_USER.mkdir(context.config.package_cache_dir_or_default() / "apt")
-    INVOKING_USER.mkdir(context.config.package_state_dir_or_default() / "apt")
+    (context.cache_dir / "lib/apt").mkdir(exist_ok=True, parents=True)
+    (context.cache_dir / "cache/apt").mkdir(exist_ok=True, parents=True)
 
     # We have a special apt.conf outside of pkgmngr dir that only configures "Dir::Etc" that we pass to APT_CONFIG to
     # tell apt it should read config files from /etc/apt in case this is overridden by distributions. This is required
index abc6a395b08d0998946498510916ea59b122abd0..d195470d0e696189c9e6b7b9a7694544f33d3d9c 100644 (file)
@@ -10,7 +10,6 @@ from mkosi.mounts import finalize_ephemeral_source_mounts
 from mkosi.run import find_binary, run
 from mkosi.sandbox import apivfs_cmd
 from mkosi.types import PathString
-from mkosi.user import INVOKING_USER
 from mkosi.util import sort_packages
 
 
@@ -31,8 +30,8 @@ def setup_dnf(context: Context, repositories: Iterable[RpmRepository], filelists
     (context.pkgmngr / "etc/dnf/vars").mkdir(exist_ok=True, parents=True)
     (context.pkgmngr / "etc/yum.repos.d").mkdir(exist_ok=True, parents=True)
 
-    INVOKING_USER.mkdir(context.config.package_cache_dir_or_default() / dnf_subdir(context))
-    INVOKING_USER.mkdir(context.config.package_state_dir_or_default() / dnf_subdir(context))
+    (context.cache_dir / "cache" / dnf_subdir(context)).mkdir(exist_ok=True, parents=True)
+    (context.cache_dir / "lib" / dnf_subdir(context)).mkdir(exist_ok=True, parents=True)
 
     config = context.pkgmngr / "etc/dnf/dnf.conf"
 
index 8ea5524fbd1f7811e868356bdc0c6c749079c3ff..941fb8a00be2d4e43a990881cc67cf79aa6aafb8 100644 (file)
@@ -10,7 +10,6 @@ from mkosi.mounts import finalize_ephemeral_source_mounts
 from mkosi.run import run
 from mkosi.sandbox import apivfs_cmd
 from mkosi.types import PathString
-from mkosi.user import INVOKING_USER
 from mkosi.util import sort_packages, umask
 from mkosi.versioncomp import GenericVersion
 
@@ -32,7 +31,7 @@ def setup_pacman(context: Context, repositories: Iterable[PacmanRepository]) ->
     with umask(~0o755):
         (context.root / "var/lib/pacman").mkdir(exist_ok=True, parents=True)
 
-    INVOKING_USER.mkdir(context.config.package_cache_dir_or_default() / "pacman/pkg")
+    (context.cache_dir / "cache/pacman/pkg").mkdir(parents=True, exist_ok=True)
 
     config = context.pkgmngr / "etc/pacman.conf"
     if config.exists():
index c3237aea7bb0f45027b0d29fb8fc3e9bcdb92d38..2996d046cb467ed658cf41298fd4d1fa0b9df766 100644 (file)
@@ -10,7 +10,6 @@ from mkosi.mounts import finalize_ephemeral_source_mounts
 from mkosi.run import run
 from mkosi.sandbox import apivfs_cmd
 from mkosi.types import PathString
-from mkosi.user import INVOKING_USER
 from mkosi.util import sort_packages
 
 
@@ -18,7 +17,7 @@ def setup_zypper(context: Context, repos: Iterable[RpmRepository]) -> None:
     config = context.pkgmngr / "etc/zypp/zypp.conf"
     config.parent.mkdir(exist_ok=True, parents=True)
 
-    INVOKING_USER.mkdir(context.config.package_cache_dir_or_default() / "zypp")
+    (context.cache_dir / "cache/zypp").mkdir(exist_ok=True, parents=True)
 
     # rpm.install.excludedocs can only be configured in zypp.conf so we append
     # to any user provided config file. Let's also bump the refresh delay to
index ac3d44c4ce122bb4915a2b9f52a76bc53de30fa7..1ca1e63cac5561591eb26c2062ee21a4c9f25628 100644 (file)
@@ -695,17 +695,10 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`,
 
 `CacheDirectory=`, `--cache-dir=`
 
-: Takes a path to a directory to use as the incremental cache directory
-  for the incremental images produced when the `Incremental=` option is
-  enabled. If this option is not used, but a `mkosi.cache/` directory is
-  found in the local directory it is automatically used for this
-  purpose.
-
-`PackageCacheDirectory=`, `--package-cache-dir`
-
-: Takes a path to a directory to use as the package cache directory for
-  the distribution package manager used. If unset, a suitable directory
-  in the user's home directory or system is used.
+: Takes a path to a directory to use as package cache for the
+  distribution package manager used. If this option is not used, but a
+  `mkosi.cache/` directory is found in the local directory it is
+  automatically used for this purpose.
 
 `BuildDirectory=`, `--build-dir=`
 
index 27371d9b97ce8abb44536953bbda9622681774f0..c468b43b3a421432ea8e7126b2021502e7a046ac 100644 (file)
@@ -9,7 +9,7 @@ import pwd
 from pathlib import Path
 
 from mkosi.log import die
-from mkosi.run import run, spawn
+from mkosi.run import spawn
 from mkosi.util import flock
 
 SUBRANGE = 65536
@@ -39,41 +39,6 @@ class INVOKING_USER:
     def home(cls) -> Path:
         return Path(f"~{cls.name()}").expanduser()
 
-    @classmethod
-    def is_regular_user(cls) -> bool:
-        return cls.uid >= 1000
-
-    @classmethod
-    def cache_dir(cls) -> Path:
-        if (cache := os.getenv("XDG_CACHE_HOME") or (cache := os.getenv("CACHE_DIRECTORY"))):
-            return Path(cache)
-
-        if (cls.is_regular_user() and Path.cwd().is_relative_to(INVOKING_USER.home())):
-            return INVOKING_USER.home() / ".cache"
-
-        return Path("/var/cache")
-
-    @classmethod
-    def state_dir(cls) -> Path:
-        if (state := os.getenv("XDG_STATE_HOME") or (state := os.getenv("STATE_DIRECTORY"))):
-            return Path(state)
-
-        if (cls.is_regular_user() and Path.cwd().is_relative_to(INVOKING_USER.home())):
-            return INVOKING_USER.home() / ".local/state"
-
-        return Path("/var/lib")
-
-    @classmethod
-    def mkdir(cls, path: Path) -> None:
-        user = cls.uid if cls.is_regular_user() and path.is_relative_to(cls.home()) else os.getuid()
-        group = cls.gid if cls.is_regular_user() and path.is_relative_to(cls.home()) else os.getgid()
-        run(["mkdir", "--parents", path], user=user, group=group)
-
-    @classmethod
-    def rchown(cls, path: Path) -> None:
-        if cls.is_regular_user() and path.is_relative_to(INVOKING_USER.home()) and path.exists():
-            run(["chown", "--recursive", f"{INVOKING_USER.uid}:{INVOKING_USER.gid}", path])
-
 
 def read_subrange(path: Path) -> int:
     uid = str(os.getuid())
index aede03b2983877c5225a99f639104e79c304689f..b6dc04a287fcb389017aa07b3d047c7ce5134dad 100644 (file)
@@ -182,7 +182,6 @@ def test_config() -> None:
             "Output": "outfile",
             "OutputDirectory": "/your/output/here",
             "Overlay": true,
-            "PackageCacheDirectory": "/a/b/c",
             "PackageDirectories": [],
             "PackageManagerTrees": [
                 {
@@ -357,7 +356,6 @@ def test_config() -> None:
         output_dir = Path("/your/output/here"),
         output_format = OutputFormat.uki,
         overlay = True,
-        package_cache_dir = Path("/a/b/c"),
         package_directories = [],
         package_manager_trees = [ConfigTree(Path("/foo/bar"), None)],
         packages = [],