Revert "nixos-container: Use machinectl shell (#18825)"

This reverts commit
c37e76b4d2. 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.
This commit is contained in:
Eelco Dolstra 2017-03-21 16:45:47 +01:00
parent 02129a8788
commit cb49c14324
No known key found for this signature in database
GPG Key ID: 8170B4726D7198DE
2 changed files with 23 additions and 2 deletions

View File

@ -6,6 +6,8 @@ substituteAll {
isExecutable = true; isExecutable = true;
src = ./nixos-container.pl; src = ./nixos-container.pl;
perl = "${perl}/bin/perl -I${perlPackages.FileSlurp}/lib/perl5/site_perl"; perl = "${perl}/bin/perl -I${perlPackages.FileSlurp}/lib/perl5/site_perl";
su = "${shadow.su}/bin/su";
inherit utillinux;
postInstall = '' postInstall = ''
t=$out/etc/bash_completion.d t=$out/etc/bash_completion.d

View File

@ -8,6 +8,9 @@ use Fcntl ':flock';
use Getopt::Long qw(:config gnu_getopt); use Getopt::Long qw(:config gnu_getopt);
use Cwd 'abs_path'; use Cwd 'abs_path';
my $nsenter = "@utillinux@/bin/nsenter";
my $su = "@su@";
# Ensure a consistent umask. # Ensure a consistent umask.
umask 0022; umask 0022;
@ -223,6 +226,22 @@ sub stopContainer {
or die "$0: failed to stop container\n"; 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 # Remove a directory while recursively unmounting all mounted filesystems within
# that directory and unmounting/removing that directory afterwards as well. # that directory and unmounting/removing that directory afterwards as well.
# #
@ -297,14 +316,14 @@ elsif ($action eq "login") {
} }
elsif ($action eq "root-login") { elsif ($action eq "root-login") {
exec("machinectl", "shell", $containerName, "/bin/sh", "-l"); runInContainer("@su@", "root", "-l");
} }
elsif ($action eq "run") { elsif ($action eq "run") {
shift @ARGV; shift @ARGV; shift @ARGV; shift @ARGV;
# Escape command. # Escape command.
my $s = join(' ', map { s/'/'\\''/g; "'$_'" } @ARGV); 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") { elsif ($action eq "show-ip") {