summary refs log tree commit diff
path: root/nixos/modules/virtualisation
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2014-04-10 13:12:34 +0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2014-04-10 15:07:29 +0200
commitac8c924c0931237461266c2780e744c63880180c (patch)
treed342b90c8ea0507bee683cdc8b4f4c0b09168344 /nixos/modules/virtualisation
parentda4f180252e9a8f539a019569efc82000ffe5440 (diff)
downloadnixlib-ac8c924c0931237461266c2780e744c63880180c.tar
nixlib-ac8c924c0931237461266c2780e744c63880180c.tar.gz
nixlib-ac8c924c0931237461266c2780e744c63880180c.tar.bz2
nixlib-ac8c924c0931237461266c2780e744c63880180c.tar.lz
nixlib-ac8c924c0931237461266c2780e744c63880180c.tar.xz
nixlib-ac8c924c0931237461266c2780e744c63880180c.tar.zst
nixlib-ac8c924c0931237461266c2780e744c63880180c.zip
nixos-container: Add ‘run’ and ‘root-login’ commands
And remove ‘root-shell’.
Diffstat (limited to 'nixos/modules/virtualisation')
-rw-r--r--nixos/modules/virtualisation/container-config.nix51
-rw-r--r--nixos/modules/virtualisation/containers.nix2
-rw-r--r--nixos/modules/virtualisation/nixos-container.pl16
3 files changed, 54 insertions, 15 deletions
diff --git a/nixos/modules/virtualisation/container-config.nix b/nixos/modules/virtualisation/container-config.nix
index 3d107899e4fe..21e64c8c0957 100644
--- a/nixos/modules/virtualisation/container-config.nix
+++ b/nixos/modules/virtualisation/container-config.nix
@@ -30,27 +30,58 @@ with lib;
           };
       };
 
-    # Provide a non-interactive login root shell on
-    # /var/lib/root-shell.socket.  On the host, you can connect to it
-    # by running ‘socat unix:<path-to-container>/var/lib/root-shell.socket -’.
-    systemd.sockets.root-shell =
-      { description = "Root Shell Socket";
+    # Also provide a root login prompt on /var/lib/root-login.socket
+    # that doesn't ask for a password. This socket can only be used by
+    # root on the host.
+    systemd.sockets.root-login =
+      { description = "Root Login Socket";
         wantedBy = [ "sockets.target" ];
         socketConfig =
-          { ListenStream = "/var/lib/root-shell.socket";
-            SocketMode = "0600"; # only root can connect, obviously
+          { ListenStream = "/var/lib/root-login.socket";
+            SocketMode = "0600";
             Accept = true;
           };
       };
 
-    systemd.services."root-shell@" =
-      { description = "Root Shell %i";
+    systemd.services."root-login@" =
+      { description = "Root Login %i";
+        environment.TERM = "linux";
+        serviceConfig =
+          { Type = "simple";
+            StandardInput = "socket";
+            ExecStart = "${pkgs.socat}/bin/socat -t0 - \"exec:${pkgs.shadow}/bin/login -f root,pty,setsid,setpgid,stderr,ctty\"";
+            TimeoutStopSec = 1; # FIXME
+          };
+      };
+
+    # Provide a daemon on /var/lib/run-command.socket that reads a
+    # command from stdin and executes it.
+    systemd.sockets.run-command =
+      { description = "Run Command Socket";
+        wantedBy = [ "sockets.target" ];
+        socketConfig =
+          { ListenStream = "/var/lib/run-command.socket";
+            SocketMode = "0600";  # only root can connect
+            Accept = true;
+          };
+      };
+
+    systemd.services."run-command@" =
+      { description = "Run Command %i";
+        environment.TERM = "linux";
         serviceConfig =
           { Type = "simple";
             StandardInput = "socket";
-            ExecStart = "${pkgs.bash}/bin/bash --login";
             TimeoutStopSec = 1; # FIXME
           };
+        script =
+          ''
+            #! ${pkgs.stdenv.shell} -e
+            source /etc/bashrc
+            read c
+            eval "command=($c)"
+            exec "''${command[@]}"
+          '';
       };
 
     systemd.services.container-startup-done =
diff --git a/nixos/modules/virtualisation/containers.nix b/nixos/modules/virtualisation/containers.nix
index 9d54ddb9948e..fbdd3f9034c6 100644
--- a/nixos/modules/virtualisation/containers.nix
+++ b/nixos/modules/virtualisation/containers.nix
@@ -256,7 +256,7 @@ in
               . "/etc/containers/$INSTANCE.conf"
             fi
             echo $SYSTEM_PATH/bin/switch-to-configuration test | \
-              ${pkgs.socat}/bin/socat unix:$root/var/lib/root-shell.socket -
+              ${pkgs.socat}/bin/socat unix:$root/var/lib/run-command.socket -
           '';
 
         serviceConfig.SyslogIdentifier = "container %i";
diff --git a/nixos/modules/virtualisation/nixos-container.pl b/nixos/modules/virtualisation/nixos-container.pl
index b6919852b285..d7e8c7339b6d 100644
--- a/nixos/modules/virtualisation/nixos-container.pl
+++ b/nixos/modules/virtualisation/nixos-container.pl
@@ -19,7 +19,8 @@ Usage: nixos-container list
        nixos-container start <container-name>
        nixos-container stop <container-name>
        nixos-container login <container-name>
-       nixos-container root-shell <container-name>
+       nixos-container root-login <container-name>
+       nixos-container run <container-name> -- args...
        nixos-container set-root-password <container-name> <password>
        nixos-container show-ip <container-name>
 EOF
@@ -205,14 +206,21 @@ elsif ($action eq "login") {
     exec($socat, "unix:$root/var/lib/login.socket", "-,echo=0,raw");
 }
 
-elsif ($action eq "root-shell") {
-    exec($socat, "unix:$root/var/lib/root-shell.socket", "-");
+elsif ($action eq "root-login") {
+    exec($socat, "unix:$root/var/lib/root-login.socket", "-,echo=0,raw");
+}
+
+elsif ($action eq "run") {
+    shift @ARGV; shift @ARGV;
+    open(SOCAT, "|-", $socat, "unix:$root/var/lib/run-command.socket", "-");
+    print SOCAT join(' ', map { "'$_'" } @ARGV), "\n";
+    close(SOCAT);
 }
 
 elsif ($action eq "set-root-password") {
     # FIXME: don't get password from the command line.
     my $password = $ARGV[2] or die "$0: no password given\n";
-    open(SOCAT, "|-", $socat, "unix:$root/var/lib/root-shell.socket", "-");
+    open(SOCAT, "|-", $socat, "unix:$root/var/lib/run-command.socket", "-");
     print SOCAT "passwd\n";
     print SOCAT "$password\n";
     print SOCAT "$password\n";