about summary refs log tree commit diff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/nix-copy-closure.in74
1 files changed, 62 insertions, 12 deletions
diff --git a/scripts/nix-copy-closure.in b/scripts/nix-copy-closure.in
index d5af65bfe5c8..511f207f1b26 100644
--- a/scripts/nix-copy-closure.in
+++ b/scripts/nix-copy-closure.in
@@ -6,7 +6,7 @@ $binDir = "@bindir@" unless defined $binDir;
 
 if (scalar @ARGV < 1) {
     print STDERR <<EOF
-Usage: nix-copy-closure HOSTNAME [--sign] PATHS...
+Usage: nix-copy-closure [--from | --to] HOSTNAME [--sign] PATHS...
 EOF
     ;
     exit 1;
@@ -30,22 +30,26 @@ my @storePaths = ();
 
 while (@ARGV) {
     my $arg = shift @ARGV;
+    
     if ($arg eq "--sign") {
         $sign = 1;
-        next;
     }
-    if ($arg eq "--gzip") {
+    elsif ($arg eq "--gzip") {
         $compressor = "gzip";
         $decompressor = "gunzip";
-        next;
     }
-
-    if (!defined $sshHost) {
+    elsif ($arg eq "--from") {
+        $toMode = 0;
+    }
+    elsif ($arg eq "--to") {
+        $toMode = 1;
+    }
+    elsif (!defined $sshHost) {
         $sshHost = $arg;
-        next;
     }
-
-    push @storePaths, $arg;
+    else {
+        push @storePaths, $arg;
+    }
 }
 
 
@@ -69,7 +73,7 @@ if ($toMode) { # Copy TO the remote machine.
             die "bad: $_" unless /^\//;
             if (!defined $storePathsSeen{$_}) {
                 push @allStorePaths, $_;
-                $storePathsSeen{$_} = 1
+                $storePathsSeen{$_} = 1;
             }
         }
 
@@ -82,7 +86,7 @@ if ($toMode) { # Copy TO the remote machine.
     my @missing = ();
     while (<READ>) {
         chomp;
-        print STDERR "target needs $_\n";
+        print STDERR "target machine needs $_\n";
         push @missing, $_;
     }
     close READ or die;
@@ -93,7 +97,53 @@ if ($toMode) { # Copy TO the remote machine.
         my $extraOpts = "";
         $extraOpts .= "--sign" if $sign == 1;
         system("nix-store --export $extraOpts @missing | $compressor | ssh @sshOpts $sshHost '$decompressor | nix-store --import'") == 0
-            or die "copying store paths to remote machine failed: $?";
+            or die "copying store paths to remote machine `$sshHost' failed: $?";
+    }
+
+}
+
+
+else { # Copy FROM the remote machine.
+
+    # Query the closure of the given store paths on the remote
+    # machine.  Paths are assumed to be store paths; there is no
+    # resolution (following of symlinks).
+    my $pid = open(READ,
+        "ssh @sshOpts $sshHost nix-store --query --requisites @storePaths|") or die;
+    
+    my @allStorePaths;
+    my %storePathsSeen;
+
+    while (<READ>) {
+        chomp;
+        die "bad: $_" unless /^\//;
+        if (!defined $storePathsSeen{$_}) {
+            push @allStorePaths, $_;
+            $storePathsSeen{$_} = 1;
+            print "GOT $_\n";
+        }
+    }
+
+    close READ or die "nix-store on remote machine `$sshHost' failed: $?";
+
+
+    # What paths are already valid locally?
+    open(READ, "@bindir@/nix-store --check-validity --print-invalid @allStorePaths|");
+    my @missing = ();
+    while (<READ>) {
+        chomp;
+        print STDERR "local machine needs $_\n";
+        push @missing, $_;
+    }
+    close READ or die;
+    
+
+    # Export the store paths on the remote machine and import them on locally.
+    if (scalar @missing > 0) {
+        my $extraOpts = "";
+        $extraOpts .= "--sign" if $sign == 1;
+        system("ssh @sshOpts $sshHost 'nix-store --export $extraOpts @missing | $compressor' | $decompressor | nix-store --import") == 0
+            or die "copying store paths to remote machine `$sshHost' failed: $?";
     }
 
 }