about summary refs log tree commit diff
path: root/scripts/build-remote.pl.in
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/build-remote.pl.in')
-rwxr-xr-xscripts/build-remote.pl.in68
1 files changed, 22 insertions, 46 deletions
diff --git a/scripts/build-remote.pl.in b/scripts/build-remote.pl.in
index 6dfa16d5cbda..687b0e131066 100755
--- a/scripts/build-remote.pl.in
+++ b/scripts/build-remote.pl.in
@@ -4,7 +4,7 @@ use Fcntl qw(:DEFAULT :flock);
 use English '-no_match_vars';
 use IO::Handle;
 use Nix::Config;
-use Nix::SSH qw/sshOpts openSSHConnection/;
+use Nix::SSH;
 use Nix::CopyClosure;
 use Nix::Store;
 no warnings('once');
@@ -90,6 +90,7 @@ if (defined $conf && -e $conf) {
 
 # Wait for the calling process to ask us whether we can build some derivation.
 my ($drvPath, $hostName, $slotLock);
+my ($from, $to);
 
 REQ: while (1) {
     $_ = <STDIN> || exit 0;
@@ -195,13 +196,15 @@ REQ: while (1) {
         # Connect to the selected machine.
         @sshOpts = ("-i", $machine->{sshKeys}, "-x");
         $hostName = $machine->{hostName};
-        if (openSSHConnection($hostName)) {
-            last REQ if system("ssh $hostName @sshOpts nix-builds-inhibited < /dev/null > /dev/null 2>&1") != 0;
-            warn "machine `$hostName' is refusing builds, trying other available machines...\n";
-            closeSSHConnection;
-        } else {
-            warn "unable to open SSH connection to `$hostName', trying other available machines...\n";
-        }
+        eval {
+            ($from, $to) = connectToRemoteNix($hostName, \@sshOpts);
+            # FIXME: check if builds are inhibited.
+        };
+        last REQ unless $@;
+        print STDERR "$@";
+        warn "unable to open SSH connection to `$hostName', trying other available machines...\n";
+        $from = undef;
+        $to = undef;
         $machine->{enabled} = 0;
     }
 }
@@ -220,18 +223,6 @@ my $maybeSign = "";
 $maybeSign = "--sign" if -e "$Nix::Config::confDir/signing-key.sec";
 
 
-# Register the derivation as a temporary GC root.  Note that $PPID is
-# the PID of the remote SSH process, which, due to the use of a
-# persistant SSH connection, should be the same across all remote
-# command invocations for this session.
-my $rootsDir = "@localstatedir@/nix/gcroots/tmp";
-system("ssh $hostName @sshOpts 'mkdir -m 1777 -p $rootsDir; ln -sfn $drvPath $rootsDir/\$PPID.drv'");
-
-sub removeRoots {
-    system("ssh $hostName @sshOpts 'rm -f $rootsDir/\$PPID.drv $rootsDir/\$PPID.out'");
-}
-
-
 # Copy the derivation and its dependencies to the build machine.  This
 # is guarded by an exclusive lock per machine to prevent multiple
 # build-remote instances from copying to a machine simultaneously.
@@ -255,48 +246,33 @@ if ($@) {
     print STDERR "somebody is hogging $uploadLock, continuing...\n";
     unlink $uploadLock;
 }
-Nix::CopyClosure::copyTo($hostName, [ @sshOpts ], [ $drvPath, @inputs ], "", "", 0, 0, $maybeSign ne "", "");
+Nix::CopyClosure::copyToOpen($from, $to, $hostName, [ $drvPath, @inputs ], "", "", 0, 0, $maybeSign ne "", "");
 close UPLOADLOCK;
 
 
 # Perform the build.
-my $buildFlags =
-    "--max-silent-time $maxSilentTime --option build-timeout $buildTimeout"
-    . " --fallback --add-root $rootsDir/\$PPID.out --quiet"
-    . " --option build-keep-log false --option build-use-substitutes false";
-
-# We let the remote side kill its process group when the connection is
-# closed unexpectedly.  This is necessary to ensure that no processes
-# are left running on the remote system if the local Nix process is
-# killed.  (SSH itself doesn't kill child processes if the connection
-# is interrupted unless the `-tt' flag is used to force a pseudo-tty,
-# in which case every child receives SIGHUP; however, `-tt' doesn't
-# work on some platforms when connection sharing is used.)
 print STDERR "building `$drvPath' on `$hostName'\n";
-pipe STDIN, DUMMY; # make sure we have a readable STDIN
-if (system("exec ssh $hostName @sshOpts '(read; kill -INT -\$\$) <&0 & exec nix-store -r $drvPath $buildFlags > /dev/null' 2>&4") != 0) {
+writeInt(6, $to) or die; # == cmdBuildPaths
+writeStrings([$drvPath], $to);
+writeInt($maxSilentTime, $to);
+writeInt($buildTimeout, $to);
+my $res = readInt($from);
+if ($res != 0) {
     # Note that if we get exit code 100 from `nix-store -r', it
     # denotes a permanent build failure (as opposed to an SSH problem
     # or a temporary Nix problem).  We propagate this to the caller to
     # allow it to distinguish between transient and permanent
     # failures.
-    my $res = $? >> 8;
     print STDERR "build of `$drvPath' on `$hostName' failed with exit code $res\n";
-    removeRoots;
     exit $res;
 }
 
-#print "build of `$drvPath' on `$hostName' succeeded\n";
-
 
 # Copy the output from the build machine.
 my @outputs2 = grep { !isValidPath($_) } @outputs;
 if (scalar @outputs2 > 0) {
-    system("exec ssh $hostName @sshOpts 'nix-store --export @outputs2'" .
-           "| NIX_HELD_LOCKS='@outputs2' @bindir@/nix-store --import > /dev/null") == 0
-        or die("cannot copy paths " . join(", ", @outputs) . " from `$hostName': $?");
+    writeInt(5, $to) or die; # == cmdExportPaths
+    writeStrings(\@outputs2, $to);
+    $ENV{'NIX_HELD_LOCKS'} = "@outputs2"; # FIXME: ugly
+    importPaths(fileno($from));
 }
-
-
-# Get rid of the temporary GC roots.
-removeRoots;