diff options
author | Vincent Ambo <tazjin@google.com> | 2020-05-17T14·52+0100 |
---|---|---|
committer | Vincent Ambo <tazjin@google.com> | 2020-05-17T14·52+0100 |
commit | 7994fd1d545cc5c876d6f21db7ddf9185d23dad6 (patch) | |
tree | 32dd695785378c5b9c8be97fc583e9dfc62cb105 /third_party/nix/perl/lib/Nix/CopyClosure.pm | |
parent | cf8cd640c1adf74a3706efbcb0ea4625da106fb2 (diff) | |
parent | 90b3b31dc27f31e9b11653a636025d29ddb087a3 (diff) |
Add 'third_party/nix/' from commit 'be66c7a6b24e3c3c6157fd37b86c7203d14acf10' r/724
git-subtree-dir: third_party/nix git-subtree-mainline: cf8cd640c1adf74a3706efbcb0ea4625da106fb2 git-subtree-split: be66c7a6b24e3c3c6157fd37b86c7203d14acf10
Diffstat (limited to 'third_party/nix/perl/lib/Nix/CopyClosure.pm')
-rw-r--r-- | third_party/nix/perl/lib/Nix/CopyClosure.pm | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/third_party/nix/perl/lib/Nix/CopyClosure.pm b/third_party/nix/perl/lib/Nix/CopyClosure.pm new file mode 100644 index 000000000000..902ee1a1bc9f --- /dev/null +++ b/third_party/nix/perl/lib/Nix/CopyClosure.pm @@ -0,0 +1,61 @@ +package Nix::CopyClosure; + +use utf8; +use strict; +use Nix::Config; +use Nix::Store; +use Nix::SSH; +use List::Util qw(sum); +use IPC::Open2; + + +sub copyToOpen { + my ($from, $to, $sshHost, $storePaths, $includeOutputs, $dryRun, $useSubstitutes) = @_; + + $useSubstitutes = 0 if $dryRun || !defined $useSubstitutes; + + # Get the closure of this path. + my @closure = reverse(topoSortPaths(computeFSClosure(0, $includeOutputs, + map { followLinksToStorePath $_ } @{$storePaths}))); + + # Send the "query valid paths" command with the "lock" option + # enabled. This prevents a race where the remote host + # garbage-collect paths that are already there. Optionally, ask + # the remote host to substitute missing paths. + syswrite($to, pack("L<x4L<x4L<x4", 1, 1, $useSubstitutes)) or die; + writeStrings(\@closure, $to); + + # Get back the set of paths that are already valid on the remote host. + my %present; + $present{$_} = 1 foreach readStrings($from); + + my @missing = grep { !$present{$_} } @closure; + return if !@missing; + + my $missingSize = 0; + $missingSize += (queryPathInfo($_, 1))[3] foreach @missing; + + printf STDERR "copying %d missing paths (%.2f MiB) to '$sshHost'...\n", + scalar(@missing), $missingSize / (1024**2); + return if $dryRun; + + # Send the "import paths" command. + syswrite($to, pack("L<x4", 4)) or die; + exportPaths(fileno($to), @missing); + readInt($from) == 1 or die "remote machine '$sshHost' failed to import closure\n"; +} + + +sub copyTo { + my ($sshHost, $storePaths, $includeOutputs, $dryRun, $useSubstitutes) = @_; + + # Connect to the remote host. + my ($from, $to) = connectToRemoteNix($sshHost, []); + + copyToOpen($from, $to, $sshHost, $storePaths, $includeOutputs, $dryRun, $useSubstitutes); + + close $to; +} + + +1; |