]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Rebuild default tools tree before cleaning up other images
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Thu, 16 Jan 2025 23:02:52 +0000 (00:02 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Thu, 16 Jan 2025 23:02:52 +0000 (00:02 +0100)
It turns out we have to put the used package manager in the cache
manifest as the metadata cache needs to be refreshed if the package
manager used changes, otherwise the metadata cache will be reused but
the new package manager won't actually be able to find any metadata
since the metadata cache contains metadata for another package manager.

To avoid running into all the problems we had previously trying to do
this, we have to make sure that the default tools tree is always available
whenever we run have_cache() on a (non-default tools tree) image, so that
the package manager we decide to use to build the image is always the same.

To achieve that, we make sure to rebuild the tools tree before doing checks
and cleaning up other images when doing a regular build. This means whenever
we call have_cache() the default tools tree will be available if it is used.

mkosi/__init__.py

index c5f62df4350e2fa5ca847a597a40b261d297037d..565d0d009b899778022b3c5615939838a46e2913 100644 (file)
@@ -4736,46 +4736,6 @@ def run_verb(args: Args, images: Sequence[Config], *, resources: Path) -> None:
             hint="Make sure to (re)build the image first with 'mkosi build' or use '--force'",
         )
 
-    output = last.output_dir_or_cwd() / last.output_with_compression
-
-    if (
-        args.verb == Verb.build
-        and not args.force
-        and output.exists()
-        and not output.is_symlink()
-        and last.output_format != OutputFormat.none
-    ):
-        logging.info(f"Output path {output} exists already. (Use --force to rebuild.)")
-        return
-
-    if args.verb.needs_build():
-        if args.verb != Verb.build and not args.force and not output.exists():
-            die(
-                f"Image '{last.name()}' has not been built yet",
-                hint="Make sure to build the image first with 'mkosi build' or use '--force'",
-            )
-
-        if not last.repart_offline and os.getuid() != 0:
-            die(f"Must be root to build {last.name()} image configured with RepartOffline=no")
-
-        check_workspace_directory(last)
-
-        if last.incremental == Incremental.strict:
-            if args.force > 1:
-                die(
-                    "Cannot remove incremental caches when building with Incremental=strict",
-                    hint="Build once with '-i yes' to update the image cache",
-                )
-
-            for config in images:
-                if have_cache(config):
-                    continue
-
-                die(
-                    f"Strict incremental mode is enabled and cache for image {config.name()} is out-of-date",
-                    hint="Build once with '-i yes' to update the image cache",
-                )
-
     # If we're doing an incremental build and the cache is not out of date, don't clean up the
     # tools tree so that we can reuse the previous one.
     if tools and (
@@ -4789,18 +4749,6 @@ def run_verb(args: Args, images: Sequence[Config], *, resources: Path) -> None:
 
         run_clean(args, tools)
 
-    # First, process all directory removals because otherwise if different images share directories
-    # a later image build could end up deleting the output generated by an earlier image build.
-    if args.verb.needs_build() and (needs_build(args, last) or args.wipe_build_dir):
-        for config in images:
-            run_clean(args, config)
-
-        if last.distribution != Distribution.custom:
-            initrd = finalize_default_initrd(last, tools=False, resources=resources)
-
-            if args.force > 1 or not have_cache(initrd):
-                remove_cache_entries(initrd)
-
     if tools and not (tools.output_dir_or_cwd() / tools.output).exists():
         check_tools(tools, Verb.build)
         ensure_directories_exist(tools)
@@ -4839,6 +4787,58 @@ def run_verb(args: Args, images: Sequence[Config], *, resources: Path) -> None:
             Verb.sandbox: run_sandbox,
         }[args.verb](args, last)
 
+    output = last.output_dir_or_cwd() / last.output_with_compression
+
+    if (
+        args.verb == Verb.build
+        and not args.force
+        and output.exists()
+        and not output.is_symlink()
+        and last.output_format != OutputFormat.none
+    ):
+        logging.info(f"Output path {output} exists already. (Use --force to rebuild.)")
+        return
+
+    if args.verb.needs_build():
+        if args.verb != Verb.build and not args.force and not output.exists():
+            die(
+                f"Image '{last.name()}' has not been built yet",
+                hint="Make sure to build the image first with 'mkosi build' or use '--force'",
+            )
+
+        if not last.repart_offline and os.getuid() != 0:
+            die(f"Must be root to build {last.name()} image configured with RepartOffline=no")
+
+        check_workspace_directory(last)
+
+        if last.incremental == Incremental.strict:
+            if args.force > 1:
+                die(
+                    "Cannot remove incremental caches when building with Incremental=strict",
+                    hint="Build once with '-i yes' to update the image cache",
+                )
+
+            for config in images:
+                if have_cache(config):
+                    continue
+
+                die(
+                    f"Strict incremental mode is enabled and cache for image {config.name()} is out-of-date",
+                    hint="Build once with '-i yes' to update the image cache",
+                )
+
+    # First, process all directory removals because otherwise if different images share directories
+    # a later image build could end up deleting the output generated by an earlier image build.
+    if args.verb.needs_build() and (needs_build(args, last) or args.wipe_build_dir):
+        for config in images:
+            run_clean(args, config)
+
+        if last.distribution != Distribution.custom:
+            initrd = finalize_default_initrd(last, resources=resources)
+
+            if args.force > 1 or not have_cache(initrd):
+                remove_cache_entries(initrd)
+
     for i, config in enumerate(images):
         if args.verb != Verb.build:
             check_tools(config, args.verb)