[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
45/118: nix-copy-closure -s: Do substitutions via ‘nix-store --serve’
From: |
Ludovic Courtès |
Subject: |
45/118: nix-copy-closure -s: Do substitutions via ‘nix-store --serve’ |
Date: |
Tue, 19 May 2015 14:45:33 +0000 |
civodul pushed a commit to branch nix
in repository guix.
commit 7bb632b02464febd8806ef4bd3fa0ac107f52650
Author: Eelco Dolstra <address@hidden>
Date: Thu Jul 10 20:43:04 2014 +0200
nix-copy-closure -s: Do substitutions via ‘nix-store --serve’
This means we no longer need an SSH master connection, since we only
execute a single command on the remote host.
---
perl/lib/Nix/CopyClosure.pm | 19 +++++++++++--------
scripts/nix-copy-closure.in | 5 ++---
src/download-via-ssh/download-via-ssh.cc | 1 +
src/nix-store/nix-store.cc | 29 +++++++++++++++++++++++++++++
4 files changed, 43 insertions(+), 11 deletions(-)
diff --git a/perl/lib/Nix/CopyClosure.pm b/perl/lib/Nix/CopyClosure.pm
index 53da720..779d743 100644
--- a/perl/lib/Nix/CopyClosure.pm
+++ b/perl/lib/Nix/CopyClosure.pm
@@ -29,16 +29,12 @@ sub copyTo {
my ($sshHost, $sshOpts, $storePaths, $compressor, $decompressor,
$includeOutputs, $dryRun, $sign, $progressViewer, $useSubstitutes) =
@_;
+ $useSubstitutes = 0 if $dryRun;
+
# Get the closure of this path.
my @closure = reverse(topoSortPaths(computeFSClosure(0, $includeOutputs,
map { followLinksToStorePath $_ } @{$storePaths})));
- # Optionally use substitutes on the remote host.
- if (!$dryRun && $useSubstitutes) {
- system "ssh $sshHost @{$sshOpts} nix-store -r --ignore-unknown
@closure";
- # Ignore exit status because this is just an optimisation.
- }
-
# Start ‘nix-store --serve’ on the remote host.
my ($from, $to);
my $pid = open2($from, $to, "ssh $sshHost @{$sshOpts} nix-store --serve
--write");
@@ -60,8 +56,9 @@ sub copyTo {
# 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.
- syswrite($to, pack("L<x4L<x4L<x4", 1, 1, scalar @closure)) or die;
+ # garbage-collect paths that are already there. Optionally, ask
+ # the remote host to substitute missing paths.
+ syswrite($to, pack("L<x4L<x4L<x4L<x4", 1, 1, $useSubstitutes, scalar
@closure)) or die;
writeString($_, $to) foreach @closure;
# Get back the set of paths that are already valid on the remote host.
@@ -119,6 +116,12 @@ sub oldCopyTo {
my ($closure, $sshHost, $sshOpts, $storePaths, $compressor, $decompressor,
$includeOutputs, $dryRun, $sign, $progressViewer, $useSubstitutes) =
@_;
+ # Optionally use substitutes on the remote host.
+ if (!$dryRun && $useSubstitutes) {
+ system "ssh $sshHost @{$sshOpts} nix-store -r --ignore-unknown
@$closure";
+ # Ignore exit status because this is just an optimisation.
+ }
+
# Ask the remote host which paths are invalid. Because of limits
# to the command line length, do this in chunks. Eventually,
# we'll want to use ‘--from-stdin’, but we can't rely on the
diff --git a/scripts/nix-copy-closure.in b/scripts/nix-copy-closure.in
index abd3760..05faa63 100755
--- a/scripts/nix-copy-closure.in
+++ b/scripts/nix-copy-closure.in
@@ -81,9 +81,6 @@ while (@ARGV) {
die "$0: you did not specify a host name\n" unless defined $sshHost;
-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,
@@ -92,6 +89,8 @@ if ($toMode) { # Copy TO the remote machine.
else { # Copy FROM the remote machine.
+ openSSHConnection $sshHost or die "$0: unable to start SSH\n";
+
# 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).
diff --git a/src/download-via-ssh/download-via-ssh.cc
b/src/download-via-ssh/download-via-ssh.cc
index 6834634..0fa0897 100644
--- a/src/download-via-ssh/download-via-ssh.cc
+++ b/src/download-via-ssh/download-via-ssh.cc
@@ -59,6 +59,7 @@ static void query(std::pair<FdSink, FdSource> & pipes)
if (cmd == "have") {
writeInt(cmdQueryValidPaths, pipes.first);
writeInt(0, pipes.first); // don't lock
+ writeInt(0, pipes.first); // don't substitute
writeStrings(tokenized, pipes.first);
pipes.first.flush();
PathSet paths = readStrings<PathSet>(pipes.second);
diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc
index 28b205b..f31eb0e 100644
--- a/src/nix-store/nix-store.cc
+++ b/src/nix-store/nix-store.cc
@@ -896,16 +896,42 @@ static void opServe(Strings opFlags, Strings opArgs)
}
switch (cmd) {
+
case cmdQueryValidPaths: {
bool lock = readInt(in);
+ bool substitute = readInt(in);
PathSet paths = readStorePaths<PathSet>(in);
if (lock && writeAllowed)
for (auto & path : paths)
store->addTempRoot(path);
+
+ /* If requested, substitute missing paths. This
+ implements nix-copy-closure's --use-substitutes
+ flag. */
+ if (substitute && writeAllowed) {
+ /* Filter out .drv files (we don't want to build
anything). */
+ PathSet paths2;
+ for (auto & path : paths)
+ if (!isDerivation(path)) paths2.insert(path);
+ unsigned long long downloadSize, narSize;
+ PathSet willBuild, willSubstitute, unknown;
+ queryMissing(*store, PathSet(paths2.begin(), paths2.end()),
+ willBuild, willSubstitute, unknown, downloadSize,
narSize);
+ /* FIXME: should use ensurePath(), but it only
+ does one path at a time. */
+ if (!willSubstitute.empty())
+ try {
+ store->buildPaths(willSubstitute);
+ } catch (Error & e) {
+ printMsg(lvlError, format("warning: %1%") %
e.msg());
+ }
+ }
+
writeStrings(store->queryValidPaths(paths), out);
out.flush();
break;
}
+
case cmdQueryPathInfos: {
PathSet paths = readStorePaths<PathSet>(in);
// !!! Maybe we want a queryPathInfos?
@@ -924,10 +950,12 @@ static void opServe(Strings opFlags, Strings opArgs)
out.flush();
break;
}
+
case cmdDumpStorePath:
dumpPath(readStorePath(in), out);
out.flush();
break;
+
case cmdImportPaths: {
if (!writeAllowed) throw Error("importing paths not allowed");
string compression = readString(in);
@@ -966,6 +994,7 @@ static void opServe(Strings opFlags, Strings opArgs)
break;
}
+
default:
throw Error(format("unknown serve command %1%") % cmd);
}
- 18/118: Print a warning when loading a large path into memory, (continued)
- 18/118: Print a warning when loading a large path into memory, Ludovic Courtès, 2015/05/19
- 27/118: Add importNative primop, Ludovic Courtès, 2015/05/19
- 24/118: Drop ImportError and FindError, Ludovic Courtès, 2015/05/19
- 28/118: Only add the importNative primop if the allow-arbitrary-code-during-evaluation option is true (default false), Ludovic Courtès, 2015/05/19
- 30/118: allow-arbitrary-code-during-evaluation -> allow-unsafe-native-code-during-evaluation, Ludovic Courtès, 2015/05/19
- 34/118: Add builtin function ‘fromJSON’, Ludovic Courtès, 2015/05/19
- 36/118: Fix compilation error on some versions of GCC, Ludovic Courtès, 2015/05/19
- 32/118: Style fix, Ludovic Courtès, 2015/05/19
- 46/118: Fix use of sysread, Ludovic Courtès, 2015/05/19
- 33/118: Manual: html -> xhtml, Ludovic Courtès, 2015/05/19
- 45/118: nix-copy-closure -s: Do substitutions via ‘nix-store --serve’,
Ludovic Courtès <=
- 40/118: Remove maybeVfork, Ludovic Courtès, 2015/05/19
- 50/118: Fix closure size display, Ludovic Courtès, 2015/05/19
- 38/118: Fix security hole in ‘nix-store --serve’, Ludovic Courtès, 2015/05/19
- 43/118: Remove tabs, Ludovic Courtès, 2015/05/19
- 35/118: Don't build on Ubuntu 10.10, Ludovic Courtès, 2015/05/19
- 44/118: nix-copy-closure: Fix --dry-run, Ludovic Courtès, 2015/05/19
- 47/118: Replace message "importing path <...>" with "exporting path <...>", Ludovic Courtès, 2015/05/19
- 37/118: Add a test for the SSH substituter, Ludovic Courtès, 2015/05/19
- 39/118: nix-copy-closure: Fix race condition, Ludovic Courtès, 2015/05/19
- 49/118: Allow $NIX_BUILD_HOOK to be relative to Nix libexec directory, Ludovic Courtès, 2015/05/19