summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2014-08-27 19:31:22 +0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2014-08-28 02:20:23 +0200
commit6773babd5b75d34afa850351fd292310e3dd3fc8 (patch)
treeaa456e10773785da75cee4b8dc24deb3f6725945 /nixos
parent9c7a598713ebb55df74801ce1e24e0e5ea064739 (diff)
downloadnixlib-6773babd5b75d34afa850351fd292310e3dd3fc8.tar
nixlib-6773babd5b75d34afa850351fd292310e3dd3fc8.tar.gz
nixlib-6773babd5b75d34afa850351fd292310e3dd3fc8.tar.bz2
nixlib-6773babd5b75d34afa850351fd292310e3dd3fc8.tar.lz
nixlib-6773babd5b75d34afa850351fd292310e3dd3fc8.tar.xz
nixlib-6773babd5b75d34afa850351fd292310e3dd3fc8.tar.zst
nixlib-6773babd5b75d34afa850351fd292310e3dd3fc8.zip
Containers: Use nsenter to execute commands in containers
Also remove ‘nixos-container set-root-password’, which is kind of
pointless now.
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/virtualisation/container-config.nix71
-rw-r--r--nixos/modules/virtualisation/containers.nix7
-rw-r--r--nixos/modules/virtualisation/nixos-container.pl40
3 files changed, 23 insertions, 95 deletions
diff --git a/nixos/modules/virtualisation/container-config.nix b/nixos/modules/virtualisation/container-config.nix
index 84e3aa283520..a7e8953827a6 100644
--- a/nixos/modules/virtualisation/container-config.nix
+++ b/nixos/modules/virtualisation/container-config.nix
@@ -18,77 +18,6 @@ with lib;
     # Shut up warnings about not having a boot loader.
     system.build.installBootLoader = "${pkgs.coreutils}/bin/true";
 
-    # 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-login.socket";
-            SocketMode = "0600";
-            Accept = true;
-          };
-      };
-
-    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
-          };
-        restartIfChanged = false;
-      };
-
-    # 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";
-            TimeoutStopSec = 1; # FIXME
-          };
-        script =
-          ''
-            #! ${pkgs.stdenv.shell} -e
-            source /etc/bashrc
-            read c
-            eval "command=($c)"
-            exec "''${command[@]}"
-          '';
-        restartIfChanged = false;
-      };
-
-    systemd.services.container-startup-done =
-      { description = "Container Startup Notification";
-        wantedBy = [ "multi-user.target" ];
-        after = [ "multi-user.target" ];
-        script =
-          ''
-            if [ -p /var/lib/startup-done ]; then
-              echo done > /var/lib/startup-done
-            fi
-          '';
-        serviceConfig.Type = "oneshot";
-        serviceConfig.RemainAfterExit = true;
-        restartIfChanged = false;
-      };
-
     systemd.services.systemd-remount-fs.enable = false;
 
   };
diff --git a/nixos/modules/virtualisation/containers.nix b/nixos/modules/virtualisation/containers.nix
index 292b96e6eb24..d62340f2c798 100644
--- a/nixos/modules/virtualisation/containers.nix
+++ b/nixos/modules/virtualisation/containers.nix
@@ -10,7 +10,7 @@ let
     isExecutable = true;
     src = ./nixos-container.pl;
     perl = "${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl";
-    inherit (pkgs) socat;
+    inherit (pkgs) utillinux;
   };
 
   # The container's init script, a small wrapper around the regular
@@ -254,9 +254,8 @@ in
           ExecReload = pkgs.writeScript "reload-container"
             ''
               #! ${pkgs.stdenv.shell} -e
-              SYSTEM_PATH=/nix/var/nix/profiles/system
-              echo $SYSTEM_PATH/bin/switch-to-configuration test | \
-                ${pkgs.socat}/bin/socat unix:$root/var/lib/run-command.socket -
+              ${nixos-container}/bin/nixos-container run "$INSTANCE" -- \
+                bash --login -c "/nix/var/nix/profiles/system/bin/switch-to-configuration test"
             '';
 
           SyslogIdentifier = "container %i";
diff --git a/nixos/modules/virtualisation/nixos-container.pl b/nixos/modules/virtualisation/nixos-container.pl
index bf6f16fc6c77..b829eeb05790 100644
--- a/nixos/modules/virtualisation/nixos-container.pl
+++ b/nixos/modules/virtualisation/nixos-container.pl
@@ -7,7 +7,7 @@ use File::Slurp;
 use Fcntl ':flock';
 use Getopt::Long qw(:config gnu_getopt);
 
-my $socat = '@socat@/bin/socat';
+my $nsenter = "@utillinux@/bin/nsenter";
 
 # Ensure a consistent umask.
 umask 0022;
@@ -25,7 +25,6 @@ Usage: nixos-container list
        nixos-container login <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>
        nixos-container show-host-key <container-name>
 EOF
@@ -186,6 +185,23 @@ sub stopContainer {
         or die "$0: failed to stop container\n";
 }
 
+# Return the PID of the init process of the container.
+sub getLeader {
+    my $s = `machinectl show "$containerName" -p Leader`;
+    chomp $s;
+    $s =~ /^Leader=(\d+)$/ or die "unable to get container's main PID\n";
+    return int($1);
+}
+
+# Run a command in the container.
+sub runInContainer {
+    my @args = @_;
+    my $leader = getLeader;
+    # FIXME: initialise the environment properly.
+    exec($nsenter, "-t", $leader, "-m", "-u", "-i", "-n", "-p", "--", "env", "-i", "--", @args);
+    die "cannot run ‘nsenter’: $!\n";
+}
+
 if ($action eq "destroy") {
     die "$0: cannot destroy declarative container (remove it from your configuration.nix instead)\n"
         unless POSIX::access($confFile, &POSIX::W_OK);
@@ -235,28 +251,12 @@ elsif ($action eq "login") {
 }
 
 elsif ($action eq "root-login") {
-    exec($socat, "unix:$root/var/lib/root-login.socket", "-,echo=0,raw");
+    runInContainer("bash", "--login");
 }
 
 elsif ($action eq "run") {
     shift @ARGV; shift @ARGV;
-    my $pid = open(SOCAT, "|-", $socat, "-t0", "-", "unix:$root/var/lib/run-command.socket") or die "$0: cannot start $socat: $!\n";
-    print SOCAT join(' ', map { "'$_'" } @ARGV), "\n";
-    flush SOCAT;
-    waitpid($pid, 0);
-    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";
-    my $pid = open(SOCAT, "|-", $socat, "-t0", "-", "unix:$root/var/lib/run-command.socket") or die "$0: cannot start $socat: $!\n";
-    print SOCAT "passwd\n";
-    print SOCAT "$password\n";
-    print SOCAT "$password\n";
-    flush SOCAT;
-    waitpid($pid, 0);
-    close(SOCAT);
+    runInContainer(@ARGV);
 }
 
 elsif ($action eq "show-ip") {