print_output_size(context.config.output_dir_or_cwd() / context.config.output_with_compression)
+def run_sandbox(args: Args, config: Config) -> None:
+ cmdline = args.cmdline or [os.getenv("SHELL", "bash")]
+ options: list[PathString] = ["--same-dir"]
+
+ # If we're not using tools tree certificates we don't have to do anything since the relaxed sandbox will
+ # already have /etc and /var from the host so we don't need to do anything extra.
+ if config.tools_tree_certificates:
+ options += finalize_crypto_mounts(config)
+
+ run(
+ cmdline,
+ stdin=sys.stdin,
+ stdout=sys.stdout,
+ env=os.environ | {"MKOSI_IN_SANDBOX": "1"},
+ log=False,
+ sandbox=config.sandbox(
+ binary=cmdline[0],
+ devices=True,
+ network=True,
+ relaxed=True,
+ options=options,
+ ),
+ )
+
+
def run_shell(args: Args, config: Config) -> None:
opname = "acquire shell in" if args.verb == Verb.shell else "boot"
if config.output_format in (OutputFormat.tar, OutputFormat.cpio):
logging.info(f"Output path {output} exists already. (Use --force to rebuild.)")
return
- if args.verb != Verb.build and not args.force and not output.exists():
+ if args.verb not in (Verb.build, Verb.sandbox) 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'",
check_workspace_directory(last)
- if last.incremental == Incremental.strict:
+ if args.verb != Verb.sandbox and last.incremental == Incremental.strict:
if args.force > 1:
die(
"Cannot remove incremental caches when building with Incremental=strict",
# 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 needs_build(args, last) or args.wipe_build_dir:
+ if args.verb != Verb.sandbox and (needs_build(args, last) or args.wipe_build_dir):
for config in images:
run_clean(args, config, resources=resources)
sync_repository_metadata(args, [tools], resources=resources, dst=Path(metadata_dir))
fork_and_wait(run_build, args, tools, resources=resources, metadata_dir=Path(metadata_dir))
+ if args.verb == Verb.sandbox:
+ return run_sandbox(args, last)
+
for i, config in enumerate(images):
with prepend_to_environ_path(config):
check_tools(config, args.verb)
dependencies = enum.auto()
completion = enum.auto()
sysupdate = enum.auto()
+ sandbox = enum.auto()
def supports_cmdline(self) -> bool:
return self in (
Verb.completion,
Verb.documentation,
Verb.sysupdate,
+ Verb.sandbox,
)
def needs_build(self) -> bool:
Verb.serve,
Verb.burn,
Verb.sysupdate,
+ Verb.sandbox,
)
def needs_config(self) -> bool:
dest="tools_tree",
metavar="PATH",
section="Build",
- parse=config_make_path_parser(constants=("default",)),
+ parse=(
+ # If we're running inside of mkosi sandbox, the tools tree is already in place so don't pick it
+ # up again.
+ config_make_path_parser(constants=("default",))
+ if not os.getenv("MKOSI_IN_SANDBOX")
+ else lambda value, old: None
+ ),
paths=("mkosi.tools",),
help="Look up programs to execute inside the given tree",
nargs="?",
mkosi [options…] {b}journalctl{e} [command line…]
mkosi [options…] {b}coredumpctl{e} [command line…]
mkosi [options…] {b}sysupdate{e} [command line…]
+ mkosi [options…] {b}sandbox{e} [command line…]
mkosi [options…] {b}clean{e}
mkosi [options…] {b}serve{e}
mkosi [options…] {b}burn{e} [device]
`mkosi [options…] sysupdate [command line…]`
+`mkosi [options…] sandbox [command line …]`
+
`mkosi [options…] clean`
`mkosi [options…] serve`
specified after the `sysupdate` verb are passed directly to
`systemd-sysupdate` invocation.
+`sandbox`
+: Run arbitrary commands inside of the same sandbox used to execute
+ other verbs such as `boot`, `shell`, `qemu` and more. This means
+ `/usr` will be replaced by `/usr` from the tools tree if one is used
+ while everything else will remain in place. If no command is provided,
+ `$SHELL` will be executed or `bash` if `$SHELL` is not set.
+
`clean`
: Remove build artifacts generated on a previous build. If combined
with `-f`, also removes incremental build cache images. If `-f` is