env |= {"MKOSI_HOST_DISTRIBUTION": str(hd)}
if hr:
env |= {"MKOSI_HOST_RELEASE": hr}
+ if config.tools_tree:
+ env |= {"MKOSI_DEFAULT_TOOLS_TREE_PATH": os.fspath(config.tools_tree)}
cmdline = [*args.cmdline]
)
-def dump_history_json(tools: Optional[Config], images: Sequence[Config]) -> str:
- return json.dumps(
- {"Tools": tools.to_dict() if tools else None, "Images": [config.to_dict() for config in images]},
- cls=JsonEncoder,
- indent=4,
- sort_keys=True,
- )
+def dump_json(dict: dict[str, Any]) -> str:
+ return json.dumps(dict, cls=JsonEncoder, indent=4, sort_keys=True)
def run_verb(args: Args, tools: Optional[Config], images: Sequence[Config], *, resources: Path) -> None:
if args.verb == Verb.summary:
if args.json:
- text = dump_history_json(tools, images)
+ text = dump_json(
+ {
+ "Tools": tools.to_dict() if tools else None,
+ "Images": [config.to_dict() for config in images],
+ }
+ )
else:
text = f"{summary(tools)}\n" if tools else ""
text += "\n".join(summary(config) for config in images)
"been built yet",
hint="Make sure to (re)build the tools tree first with 'mkosi build' or use '--force'",
)
- elif in_sandbox():
- die(
- "Cannot rebuild out-of-date default tools tree from inside mkosi sandbox",
- hint="Exit mkosi sandbox and re-enter the sandbox again with mkosi -f sandbox to "
- "rebuild the default tools tree",
- )
elif last.incremental == Incremental.strict:
die(
"Default tools tree is out-of-date but the strict incremental mode is enabled",
keyring_dir=Path(keyring_dir),
metadata_dir=Path(metadata_dir),
)
- _, _, manifest = cache_tree_paths(tools)
- manifest.write_text(
- json.dumps(tools.cache_manifest(), cls=JsonEncoder, indent=4, sort_keys=True)
- )
- if not args.verb.needs_build():
+ _, _, manifest = cache_tree_paths(tools)
+ manifest.write_text(dump_json(tools.cache_manifest()))
+ Path(".mkosi-private/history/tools.json").unlink(missing_ok=True)
+
+ if tools and last.history and not Path(".mkosi-private/history/tools.json").exists():
+ Path(".mkosi-private/history").mkdir(parents=True, exist_ok=True)
+ Path(".mkosi-private/history/tools.json").write_text(dump_json(tools.to_dict()))
+
+ if args.verb.needs_tools():
return {
Verb.ssh: run_ssh,
Verb.journalctl: run_journalctl,
if last.history and history:
Path(".mkosi-private/history").mkdir(parents=True, exist_ok=True)
- Path(".mkosi-private/history/latest.json").write_text(dump_history_json(tools, images))
+ Path(".mkosi-private/history/latest.json").write_text(
+ dump_json({"Images": [config.to_dict() for config in images]})
+ )
if args.verb == Verb.build:
return
Verb.dependencies,
)
+ def needs_tools(self) -> bool:
+ return self in (Verb.sandbox, Verb.journalctl, Verb.coredumpctl, Verb.ssh)
+
def needs_build(self) -> bool:
return self in (
Verb.build,
return ns
-def have_history(args: Args) -> bool:
- return (
- args.directory is not None
- and args.verb.needs_build()
- and ((args.verb != Verb.build and not args.force) or args.rerun_build_scripts)
- and Path(".mkosi-private/history/latest.json").exists()
- )
+def have_history(args: Args, tools: bool = False) -> bool:
+ filename = "tools" if tools else "latest"
+
+ if args.directory is None:
+ return False
+
+ if args.verb in (Verb.build, Verb.cat_config, Verb.clean):
+ return False
+
+ if args.verb == Verb.summary and args.force > 0:
+ return False
+
+ if args.verb.needs_tools() and args.force > 0:
+ return False
+
+ if args.verb.needs_build() and args.force > 0 and not args.rerun_build_scripts:
+ return False
+
+ return Path(f".mkosi-private/history/{filename}.json").exists()
def finalize_default_tools(
if args.debug_sandbox:
ARG_DEBUG_SANDBOX.set(args.debug_sandbox)
+ if args.rerun_build_scripts and not args.verb.needs_build():
+ die(f"--rerun-build-scripts cannot be used with the '{args.verb}' command")
+
if args.cmdline and not args.verb.supports_cmdline():
- die(f"Arguments after verb are not supported for {args.verb}.")
+ die(f"Arguments after verb are not supported for the '{args.verb}' command")
# If --debug was passed, apply it as soon as possible.
if ARG_DEBUG.get():
if have_history(args):
try:
j = json.loads(Path(".mkosi-private/history/latest.json").read_text())
- tools = Config.from_json(j["Tools"]) if j["Tools"] is not None else None
*subimages, prev = [Config.from_json(c) for c in j["Images"]]
except (KeyError, ValueError):
die(
context.only_sections = ("Include", "Runtime", "Host")
else:
context.only_sections = tuple(only_sections)
- tools = None
subimages = []
prev = None
+ if not in_sandbox() and have_history(args, tools=True):
+ tools = Config.from_json(json.loads(Path(".mkosi-private/history/tools.json").read_text()))
+ else:
+ tools = None
+
# One of the specifiers needs access to the directory, so make sure it is available.
context.config["directory"] = args.directory
return args, tools, (*subimages, Config.from_dict(config))
if config.get("tools_tree") == Path("default"):
- tools = finalize_default_tools(context, config, configdir=configdir, resources=resources)
- config["tools_tree"] = tools.output_dir_or_cwd() / tools.output
+ if in_sandbox():
+ config["tools_tree"] = os.environ["MKOSI_DEFAULT_TOOLS_TREE_PATH"]
+ else:
+ tools = finalize_default_tools(context, config, configdir=configdir, resources=resources)
+ config["tools_tree"] = tools.output_dir_or_cwd() / tools.output
images = []
the latest build to the `.mkosi-private` subdirectory in the
directory from which it was invoked. This information is then used
to restore the config of the latest build when running any verb that
- needs a build without specifying `--force`.
+ does not rebuild the image or when running any verb that may rebuild
+ the image without specifying `--force`.
Note that configure scripts will not be executed if we reuse the
history from a previous build.