From: Daan De Meyer Date: Thu, 27 Apr 2023 13:21:03 +0000 (+0200) Subject: Cache only files installed on top of base trees X-Git-Tag: v15~190 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=91dc159a73d32b2beca0339655002ec5b066e2e7;p=thirdparty%2Fmkosi.git Cache only files installed on top of base trees Currently, when base trees are used in incremental mode, we cache the base trees as well. When running from a cache copy, any changes to the base trees are not taken into account. Let's change this and only cache the files we add/change/delete on top of the base layers. This makes sure that we can still use our cache even if the base layer changes, since we won't ignore all changes made to the base layer. --- diff --git a/mkosi/__init__.py b/mkosi/__init__.py index 5095f6d41..e8322779c 100644 --- a/mkosi/__init__.py +++ b/mkosi/__init__.py @@ -377,6 +377,16 @@ def configure_autologin(state: MkosiState) -> None: +@contextlib.contextmanager +def mount_cache_overlay(state: MkosiState) -> Iterator[None]: + if not state.config.incremental: + yield + return + + with mount_overlay([state.root], state.cache_overlay, state.workdir, state.root, read_only=False): + yield + + def mount_build_overlay(state: MkosiState, read_only: bool = False) -> ContextManager[Path]: return mount_overlay([state.root], state.build_overlay, state.workdir, state.root, read_only) @@ -888,7 +898,7 @@ def save_cache(state: MkosiState) -> None: with complete_step("Installing cache copies"): unlink_try_hard(final) - shutil.move(state.root, final) + shutil.move(state.cache_overlay, final) acl_toggle_remove(state.config, final, state.uid, allow=True) if state.config.build_script: @@ -1500,15 +1510,16 @@ def invoke_repart(state: MkosiState, skip: Sequence[str] = [], split: bool = Fal def build_image(state: MkosiState, *, for_cache: bool, manifest: Optional[Manifest] = None) -> None: with mount_image(state): + install_base_trees(state) cached = reuse_cache_tree(state) if not for_cache else False if not cached: - install_base_trees(state) - install_skeleton_trees(state) - install_distribution(state) - run_prepare_script(state, build=False) - install_build_packages(state) - run_prepare_script(state, build=True) + with mount_cache_overlay(state): + install_skeleton_trees(state) + install_distribution(state) + run_prepare_script(state, build=False) + install_build_packages(state) + run_prepare_script(state, build=True) if for_cache: return diff --git a/mkosi/state.py b/mkosi/state.py index b8f6bad61..8d6df09d4 100644 --- a/mkosi/state.py +++ b/mkosi/state.py @@ -40,6 +40,7 @@ class MkosiState: self.root.mkdir(exist_ok=True, mode=0o755) self.build_overlay.mkdir(exist_ok=True, mode=0o755) + self.cache_overlay.mkdir(exist_ok=True, mode=0o755) self.workdir.mkdir(exist_ok=True) self.staging.mkdir(exist_ok=True) @@ -47,6 +48,10 @@ class MkosiState: def root(self) -> Path: return self.workspace / "root" + @property + def cache_overlay(self) -> Path: + return self.workspace / "cache-overlay" + @property def build_overlay(self) -> Path: return self.workspace / "build-overlay"