]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Add journalctl and coredumpctl verbs
authorSam Leonard <sam.leonard@codethink.co.uk>
Mon, 30 Oct 2023 17:11:35 +0000 (17:11 +0000)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Thu, 2 Nov 2023 16:14:39 +0000 (17:14 +0100)
mkosi/__init__.py
mkosi/config.py
mkosi/resources/mkosi.md
tests/test_config.py

index 416425c2e2d36bd646bd117fbaeadc1984e657f8..982116eb694f1c59820f272501bf2d359ad6f9f2 100644 (file)
@@ -2333,6 +2333,35 @@ def run_shell(args: MkosiArgs, config: MkosiConfig) -> None:
         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"""
 
@@ -2600,6 +2629,13 @@ def run_verb(args: MkosiArgs, images: Sequence[MkosiConfig]) -> None:
         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)
@@ -2701,3 +2737,9 @@ def run_verb(args: MkosiArgs, images: Sequence[MkosiConfig]) -> None:
 
             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)
index b9154f4ef0b4d1fb28c789abe98a279030dc9c1e..b1612dbc74c1390cb63aa8c430b787c0a7ebf7ef 100644 (file)
@@ -56,12 +56,14 @@ class Verb(StrEnum):
     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)
@@ -1943,11 +1945,13 @@ def create_argument_parser(action: type[argparse.Action]) -> argparse.ArgumentPa
         # 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}
index b289971ae2079616d9a82274cbf6bcb249393e9a..670972bae53a9b4d49fb4475e5fb4540c46ae8ba 100644 (file)
@@ -20,6 +20,10 @@ mkosi — Build Bespoke OS Images
 
 `mkosi [options…] ssh [command line…]`
 
+`mkosi [options…] journalctl [command line…]`
+
+`mkosi [options…] coredumpctl [command line…]`
+
 `mkosi [options…] clean`
 
 `mkosi [options…] serve`
@@ -93,6 +97,18 @@ The following command line verbs are known:
   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
index bc33912d380b987b8edb5e03b961056a6788185a..f2bfa13d0d0f9da8098ac55415f8e62116b3aa04 100644 (file)
@@ -311,6 +311,8 @@ def test_parse_load_verb(tmp_path: Path) -> None:
         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"])