forked from lix-project/lix
d645633643
We're already printing progress on stderr, so printing them on stdout afterwards is kind of useless.
112 lines
2.8 KiB
Plaintext
Executable file
112 lines
2.8 KiB
Plaintext
Executable file
#! @perl@ -w @perlFlags@
|
||
|
||
use Nix::SSH;
|
||
use Nix::Config;
|
||
use Nix::Store;
|
||
use Nix::CopyClosure;
|
||
|
||
|
||
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 $compressor = "";
|
||
my $decompressor = "";
|
||
|
||
my $toMode = 1;
|
||
|
||
my $includeOutputs = 0;
|
||
|
||
my $dryRun = 0;
|
||
|
||
|
||
# !!! Copied from nix-pack-closure, should put this in a module.
|
||
my @storePaths = ();
|
||
|
||
while (@ARGV) {
|
||
my $arg = shift @ARGV;
|
||
|
||
if ($arg eq "--sign") {
|
||
$sign = 1;
|
||
}
|
||
elsif ($arg eq "--gzip") {
|
||
$compressor = "gzip";
|
||
$decompressor = "gunzip";
|
||
}
|
||
elsif ($arg eq "--bzip2") {
|
||
$compressor = "bzip2";
|
||
$decompressor = "bunzip2";
|
||
}
|
||
elsif ($arg eq "--xz") {
|
||
$compressor = "xz";
|
||
$decompressor = "xz -d";
|
||
}
|
||
elsif ($arg eq "--from") {
|
||
$toMode = 0;
|
||
}
|
||
elsif ($arg eq "--to") {
|
||
$toMode = 1;
|
||
}
|
||
elsif ($arg eq "--include-outputs") {
|
||
$includeOutputs = 1;
|
||
}
|
||
elsif ($arg eq "--dry-run") {
|
||
$dryRun = 1;
|
||
}
|
||
elsif (!defined $sshHost) {
|
||
$sshHost = $arg;
|
||
}
|
||
else {
|
||
push @storePaths, $arg;
|
||
}
|
||
}
|
||
|
||
|
||
openSSHConnection $sshHost or die "$0: unable to start SSH\n";
|
||
|
||
|
||
if ($toMode) { # Copy TO the remote machine.
|
||
Nix::CopyClosure::copyTo($sshHost, [ @sshOpts ], [ @storePaths ], $compressor, $decompressor, $includeOutputs, $dryRun, $sign);
|
||
}
|
||
|
||
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 $extraOpts = $includeOutputs ? "--include-outputs" : "";
|
||
my $pid = open(READ,
|
||
"set -f; ssh @sshOpts $sshHost nix-store --query --requisites $extraOpts @storePaths|") or die;
|
||
|
||
while (<READ>) {
|
||
chomp;
|
||
die "bad: $_" unless /^\//;
|
||
push @missing, $_ unless isValidPath($_);
|
||
}
|
||
|
||
close READ or die "nix-store on remote machine `$sshHost' failed: $?";
|
||
|
||
# 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";
|
||
$compressor = "| $compressor" if $compressor ne "";
|
||
$decompressor = "$decompressor |" if $decompressor ne "";
|
||
unless ($dryRun) {
|
||
my $extraOpts = $sign ? "--sign" : "";
|
||
system("set -f; ssh $sshHost @sshOpts 'nix-store --export $extraOpts @missing $compressor' | $decompressor $Nix::Config::binDir/nix-store --import > /dev/null") == 0
|
||
or die "copying store paths from remote machine `$sshHost' failed: $?";
|
||
}
|
||
}
|
||
|
||
}
|