run(cmdline, stdin=sys.stdin, stdout=sys.stdout, env=os.environ, log=False)
+def run_systemd_tool(tool: str, args: MkosiArgs, config: MkosiConfig) -> None:
+ if config.output_format not in (OutputFormat.disk, OutputFormat.directory):
+ die(f"{config.output_format} images cannot be inspected with {tool}")
+
+ if (tool_path := find_binary(tool)) is None:
+ die(f"Failed to find {tool}")
+
+ image_arg_name = "root" if config.output_format == OutputFormat.directory else "image"
+ run(
+ [
+ tool_path,
+ f"--{image_arg_name}={config.output_dir_or_cwd() / config.output}",
+ *args.cmdline
+ ],
+ stdin=sys.stdin,
+ stdout=sys.stdout,
+ env=os.environ,
+ log=False
+ )
+
+
+def run_journalctl(args: MkosiArgs, config: MkosiConfig) -> None:
+ run_systemd_tool("journalctl", args, config)
+
+
+def run_coredumpctl(args: MkosiArgs, config: MkosiConfig) -> None:
+ run_systemd_tool("coredumpctl", args, config)
+
+
def run_serve(config: MkosiConfig) -> None:
"""Serve the output directory via a tiny HTTP server"""
if last.compress_output:
die(f"Sorry, can't {opname} a compressed image.")
+ if (
+ args.verb in (Verb.journalctl, Verb.coredumpctl)
+ and last.output_format == OutputFormat.disk
+ and os.getuid() != 0
+ ):
+ die(f"Must be root to run the {args.verb} command")
+
for config in images:
if args.verb == Verb.build and not args.force:
check_outputs(config)
if args.verb == Verb.serve:
run_serve(last)
+
+ if args.verb == Verb.journalctl:
+ run_journalctl(args, last)
+
+ if args.verb == Verb.coredumpctl:
+ run_coredumpctl(args, last)
help = enum.auto()
genkey = enum.auto()
documentation = enum.auto()
+ journalctl = enum.auto()
+ coredumpctl = enum.auto()
def supports_cmdline(self) -> bool:
- return self in (Verb.build, Verb.shell, Verb.boot, Verb.qemu, Verb.ssh)
+ return self in (Verb.build, Verb.shell, Verb.boot, Verb.qemu, Verb.ssh, Verb.journalctl, Verb.coredumpctl)
def needs_build(self) -> bool:
- return self in (Verb.build, Verb.shell, Verb.boot, Verb.qemu, Verb.serve)
+ return self in (Verb.build, Verb.shell, Verb.boot, Verb.qemu, Verb.serve, Verb.journalctl, Verb.coredumpctl)
def needs_root(self) -> bool:
return self in (Verb.shell, Verb.boot)
# the synopsis below is supposed to be indented by two spaces
usage="\n " + textwrap.dedent("""\
mkosi [options...] {b}summary{e}
- mkosi [options...] {b}build{e} [command line...]
- mkosi [options...] {b}shell{e} [command line...]
- mkosi [options...] {b}boot{e} [nspawn settings...]
- mkosi [options...] {b}qemu{e} [qemu parameters...]
- mkosi [options...] {b}ssh{e} [command line...]
+ mkosi [options...] {b}build{e} [command line...]
+ mkosi [options...] {b}shell{e} [command line...]
+ mkosi [options...] {b}boot{e} [nspawn settings...]
+ mkosi [options...] {b}qemu{e} [qemu parameters...]
+ mkosi [options...] {b}ssh{e} [command line...]
+ mkosi [options...] {b}journalctl{e} [command line...]
+ mkosi [options...] {b}coredumpctl{e} [command line...]
mkosi [options...] {b}clean{e}
mkosi [options...] {b}serve{e}
mkosi [options...] {b}bump{e}
`mkosi [options…] ssh [command line…]`
+`mkosi [options…] journalctl [command line…]`
+
+`mkosi [options…] coredumpctl [command line…]`
+
`mkosi [options…] clean`
`mkosi [options…] serve`
verb are passed as arguments to the `ssh` invocation. To connect to a
container, use `machinectl login` or `machinectl shell`.
+`journalctl`
+
+: Uses `journalctl` to inspect the journal inside the image.
+ Any arguments specified after the `journalctl` verb are appended to the
+ `journalctl` invocation.
+
+`coredumpctl`
+
+: Uses `coredumpctl` to look for coredumps inside the image.
+ Any arguments specified after the `coredumpctl` verb are appended to the
+ `coredumpctl` invocation.
+
`clean`
: Remove build artifacts generated on a previous build. If combined
assert parse_config(["shell"])[0].verb == Verb.shell
assert parse_config(["boot"])[0].verb == Verb.boot
assert parse_config(["qemu"])[0].verb == Verb.qemu
+ assert parse_config(["journalctl"])[0].verb == Verb.journalctl
+ assert parse_config(["coredumpctl"])[0].verb == Verb.coredumpctl
with pytest.raises(SystemExit):
parse_config(["invalid"])