summary refs log tree commit diff
path: root/pkgs/tools/virtualization/nixos-container/nixos-container.pl
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-03-21 16:45:47 +0100
committerEelco Dolstra <edolstra@gmail.com>2017-03-21 16:51:08 +0100
commitcb49c1432417f9576ed12613f0374b3bc23587c2 (patch)
tree04207d60d54b794a18549fe82a2fbcff1bbfda3b /pkgs/tools/virtualization/nixos-container/nixos-container.pl
parent02129a8788423cb0b3dd4248c1ae342866d0d7ad (diff)
downloadnixpkgs-cb49c1432417f9576ed12613f0374b3bc23587c2.tar
nixpkgs-cb49c1432417f9576ed12613f0374b3bc23587c2.tar.gz
nixpkgs-cb49c1432417f9576ed12613f0374b3bc23587c2.tar.bz2
nixpkgs-cb49c1432417f9576ed12613f0374b3bc23587c2.tar.lz
nixpkgs-cb49c1432417f9576ed12613f0374b3bc23587c2.tar.xz
nixpkgs-cb49c1432417f9576ed12613f0374b3bc23587c2.tar.zst
nixpkgs-cb49c1432417f9576ed12613f0374b3bc23587c2.zip
Revert "nixos-container: Use machinectl shell (#18825)"
This reverts commit
c37e76b4d2ac59139df8956cc2b1ec6921bea11d. Unfortunately, using
"machinectl shell" has two bad side effects:

* It sends the command's stderr to stdout.

* It doesn't propagate the command's exit status.

This broke NixOps.

PR #18825.
Diffstat (limited to 'pkgs/tools/virtualization/nixos-container/nixos-container.pl')
-rwxr-xr-xpkgs/tools/virtualization/nixos-container/nixos-container.pl23
1 files changed, 21 insertions, 2 deletions
diff --git a/pkgs/tools/virtualization/nixos-container/nixos-container.pl b/pkgs/tools/virtualization/nixos-container/nixos-container.pl
index 65a9c3f5814..754715cddd0 100755
--- a/pkgs/tools/virtualization/nixos-container/nixos-container.pl
+++ b/pkgs/tools/virtualization/nixos-container/nixos-container.pl
@@ -8,6 +8,9 @@ use Fcntl ':flock';
 use Getopt::Long qw(:config gnu_getopt);
 use Cwd 'abs_path';
 
+my $nsenter = "@utillinux@/bin/nsenter";
+my $su = "@su@";
+
 # Ensure a consistent umask.
 umask 0022;
 
@@ -223,6 +226,22 @@ 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;
+    exec($nsenter, "-t", $leader, "-m", "-u", "-i", "-n", "-p", "--", @args);
+    die "cannot run ‘nsenter’: $!\n";
+}
+
 # Remove a directory while recursively unmounting all mounted filesystems within
 # that directory and unmounting/removing that directory afterwards as well.
 #
@@ -297,14 +316,14 @@ elsif ($action eq "login") {
 }
 
 elsif ($action eq "root-login") {
-    exec("machinectl", "shell", $containerName, "/bin/sh", "-l");
+    runInContainer("@su@", "root", "-l");
 }
 
 elsif ($action eq "run") {
     shift @ARGV; shift @ARGV;
     # Escape command.
     my $s = join(' ', map { s/'/'\\''/g; "'$_'" } @ARGV);
-    exec("machinectl", "--quiet", "shell", $containerName, "/bin/sh", "-l", "-c", $s);
+    runInContainer("@su@", "root", "-l", "-c", "exec " . $s);
 }
 
 elsif ($action eq "show-ip") {