diff options
Diffstat (limited to 'scripts/nix-copy-closure.in')
-rwxr-xr-x | scripts/nix-copy-closure.in | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/scripts/nix-copy-closure.in b/scripts/nix-copy-closure.in new file mode 100755 index 000000000000..d7a2c973948b --- /dev/null +++ b/scripts/nix-copy-closure.in @@ -0,0 +1,101 @@ +#! @perl@ -w @perlFlags@ + +use strict; +use Nix::SSH; +use Nix::Config; +use Nix::Store; +use Nix::CopyClosure; +use List::Util qw(sum); + +binmode STDERR, ":encoding(utf8)"; + +if (scalar @ARGV < 1) { + print STDERR <<EOF +Usage: nix-copy-closure [--from | --to] HOSTNAME [--sign] [--gzip] [--bzip2] [--xz] PATHS... +EOF + ; + exit 1; +} + + +# Get the target host. +my $sshHost; +my $sign = 0; +my $toMode = 1; +my $includeOutputs = 0; +my $dryRun = 0; +my $useSubstitutes = 0; + + +# !!! Copied from nix-pack-closure, should put this in a module. +my @storePaths = (); + +while (@ARGV) { + my $arg = shift @ARGV; + + if ($arg eq "--help") { + exec "man nix-copy-closure" or die; + } + elsif ($arg eq "--sign") { + $sign = 1; + } + elsif ($arg eq "--gzip" || $arg eq "--bzip2" || $arg eq "--xz") { + warn "$0: ‘$arg’ is not implemented\n" if $arg ne "--gzip"; + push @globalSshOpts, "-C"; + } + elsif ($arg eq "--from") { + $toMode = 0; + } + elsif ($arg eq "--to") { + $toMode = 1; + } + elsif ($arg eq "--include-outputs") { + $includeOutputs = 1; + } + elsif ($arg eq "--show-progress") { + warn "$0: ‘$arg’ is not implemented\n"; + } + elsif ($arg eq "--dry-run") { + $dryRun = 1; + } + elsif ($arg eq "--use-substitutes" || $arg eq "-s") { + $useSubstitutes = 1; + } + elsif (!defined $sshHost) { + $sshHost = $arg; + } + else { + push @storePaths, $arg; + } +} + +die "$0: you did not specify a host name\n" unless defined $sshHost; + + +if ($toMode) { # Copy TO the remote machine. + Nix::CopyClosure::copyTo( + $sshHost, [ @storePaths ], + $includeOutputs, $dryRun, $sign, $useSubstitutes); +} + +else { # Copy FROM the remote machine. + + my ($from, $to) = connectToRemoteNix($sshHost, []); + + # 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). + syswrite($to, pack("L<x4L<x4", 7, $includeOutputs ? 1 : 0)) or die; + writeStrings(\@storePaths, $to); + my @missing = grep { !isValidPath($_) } readStrings($from); + + # Export the store paths on the remote machine and import them locally. + if (scalar @missing > 0) { + print STDERR "copying ", scalar @missing, " missing paths from ‘$sshHost’...\n"; + writeInt(5, $to); # == cmdExportPaths + writeInt($sign ? 1 : 0, $to); + writeStrings(\@missing, $to); + importPaths(fileno($from)); + } + +} |