Containers: Use nsenter to execute commands in containers
Also remove ‘nixos-container set-root-password’, which is kind of pointless now.
This commit is contained in:
parent
9c7a598713
commit
6773babd5b
@ -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;
|
||||
|
||||
};
|
||||
|
@ -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";
|
||||
|
@ -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") {
|
||||
|
Loading…
Reference in New Issue
Block a user