]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn: add ability to poweroff container cleanly with ^]^]p 36583/head
authorLennart Poettering <lennart@poettering.net>
Sun, 2 Mar 2025 20:43:12 +0000 (21:43 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 4 Mar 2025 22:02:31 +0000 (23:02 +0100)
It's sometimes very useful to be able to terminate a container quickly
but cleanly while talking to it. Introduce a hotkey for that: ^]^]p for
powering it off. In similar style add ^]^]r for rebooting it.

man/systemd-nspawn.xml
src/nspawn/nspawn.c
tools/command_ignorelist

index 4484e878317d185a3a9ab5f911ed94699cc60ed9..213f434fe77021b24e0181c341c473fe962cea78 100644 (file)
@@ -1847,6 +1847,35 @@ After=sys-subsystem-net-devices-ens1.device</programlisting>
    </refsect2>
   </refsect1>
 
+  <refsect1>
+    <title>Hotkeys</title>
+
+    <para>When invoked in interactive mode (i.e. the default <option>--console=interactive</option>), a few
+    special keyboard shortcuts are understood that control the container runtime. These shortcuts need to be
+    typed within 1s to have effect, otherwise they will be forwarded to the container as regular
+    keypresses.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term>Ctrl-] Ctrl-] Ctrl-]</term>
+        <listitem><para>Immediately terminate the container, killing all processes.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>Ctrl-] Ctrl-] r</term>
+        <listitem><para>Issue a reboot request to the container.</para>
+        <xi:include href="version-info.xml" xpointer="v258"/></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>Ctrl-] Ctrl-] p</term>
+        <listitem><para>Issue a shutdown request to the container.</para>
+        <xi:include href="version-info.xml" xpointer="v258"/></listitem>
+      </varlistentry>
+
+    </variablelist>
+  </refsect1>
+
   <xi:include href="common-variables.xml" />
 
   <refsect1>
index 1737d1ef0ae4c73c6f7ea2ef8ca46be43d84690d..952516bc78fc6b8a7279143fd01d2b1b42cd2d0e 100644 (file)
@@ -4692,6 +4692,37 @@ static void set_window_title(PTYForward *f) {
                 (void) pty_forward_set_title_prefix(f, dot);
 }
 
+static int ptyfwd_hotkey(PTYForward *f, char c, void *userdata) {
+        pid_t pid = PTR_TO_PID(userdata);
+        const char *word;
+        int sig = 0;
+
+        assert(f);
+
+        switch (c) {
+        case 'p':
+                sig = SIGRTMIN+4;
+                word = "power off";
+                break;
+
+        case 'r':
+                sig = SIGRTMIN+5;
+                word = "reboot";
+                break;
+
+        default:
+                log_info("Unknown hotkey sequence ^]^]%c, ignoring.", c);
+                return 0;
+        }
+
+        if (kill(pid, sig) < 0)
+                log_error_errno(errno, "Failed to send %s (%s request) to PID 1 of container: %m", signal_to_string(sig), word);
+        else
+                log_info("Sent %s (%s request) to PID 1 of container.", signal_to_string(sig), word);
+
+        return 0;
+}
+
 static int merge_settings(Settings *settings, const char *path) {
         int rl;
 
@@ -5687,6 +5718,8 @@ static int run_container(
                                 (void) pty_forward_set_background_color(forward, arg_background);
 
                         set_window_title(forward);
+
+                        pty_forward_set_hotkey_handler(forward, ptyfwd_hotkey, PID_TO_PTR(*pid));
                         break;
 
                 default:
@@ -6364,7 +6397,9 @@ static int run(int argc, char *argv[]) {
                          special_glyph(SPECIAL_GLYPH_LIGHT_SHADE), ansi_grey(), arg_machine, u ?: t, ansi_normal());
 
                 if (arg_console_mode == CONSOLE_INTERACTIVE)
-                        log_info("%s %sPress %sCtrl-]%s three times within 1s to kill container.%s",
+                        log_info("%s %sPress %sCtrl-]%s three times within 1s to kill container; two times followed by %sr%s\n"
+                                 "%s %sto reboot container; two times followed by %sp%s to poweroff container.%s",
+                                 special_glyph(SPECIAL_GLYPH_LIGHT_SHADE), ansi_grey(), ansi_highlight(), ansi_grey(), ansi_highlight(), ansi_normal(),
                                  special_glyph(SPECIAL_GLYPH_LIGHT_SHADE), ansi_grey(), ansi_highlight(), ansi_grey(), ansi_normal());
         }
 
index aca6b8c93bd19c48c78f0f873bc00f7d3d425e3d..65602aab8a754955fd9b5bdb90b726de510fac19 100644 (file)
@@ -576,3 +576,4 @@ file-hierarchy.xml /refsect1[title="Home Directory"]/variablelist/varlistentry[t
 file-hierarchy.xml /refsect1[title="Home Directory"]/variablelist/varlistentry[term="~/.local/share/"]
 file-hierarchy.xml /refsect1[title="Home Directory"]/variablelist/varlistentry[term="~/.local/state/"]
 systemd-measure.xml /refsect1[title="Options"]/variablelist/varlistentry[term="--linux=PATH"]
+systemd-nspawn.xml /refsect1[title="Hotkeys"]/variablelist/varlistentry[term="Ctrl-] Ctrl-] Ctrl-]"]