aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/manual/command-ref/env-common.xml34
-rw-r--r--doc/manual/command-ref/nix-instantiate.xml7
-rw-r--r--doc/manual/command-ref/opt-common.xml11
-rw-r--r--doc/manual/expressions/advanced-attributes.xml21
-rw-r--r--doc/manual/release-notes/rl-18.xml14
-rw-r--r--release.nix4
-rwxr-xr-xscripts/build-remote.pl.in11
-rw-r--r--scripts/download-from-binary-cache.pl.in2
-rwxr-xr-xscripts/download-using-manifests.pl.in1
-rwxr-xr-xscripts/nix-build.in2
-rwxr-xr-xscripts/nix-channel.in3
-rwxr-xr-xscripts/nix-copy-closure.in1
-rwxr-xr-xscripts/nix-install-package.in3
-rwxr-xr-xscripts/nix-prefetch-url.in4
-rwxr-xr-xscripts/nix-pull.in3
-rwxr-xr-xscripts/nix-push.in3
-rw-r--r--src/libexpr/eval.cc2
-rw-r--r--src/libexpr/local.mk6
-rw-r--r--src/libstore/build.cc40
-rw-r--r--src/libstore/local-store.hh3
-rw-r--r--src/libstore/optimise-store.cc16
-rw-r--r--src/libstore/remote-store.cc7
-rw-r--r--src/libstore/remote-store.hh4
-rw-r--r--src/libstore/store-api.hh4
-rw-r--r--src/libstore/worker-protocol.hh1
-rw-r--r--src/nix-daemon/nix-daemon.cc7
-rw-r--r--src/nix-store/nix-store.cc20
-rw-r--r--tests/check-refs.nix12
-rw-r--r--tests/check-refs.sh6
-rw-r--r--tests/check-reqs.nix57
-rw-r--r--tests/check-reqs.sh13
-rw-r--r--tests/local.mk3
-rw-r--r--tests/remote-builds.nix5
33 files changed, 260 insertions, 70 deletions
diff --git a/doc/manual/command-ref/env-common.xml b/doc/manual/command-ref/env-common.xml
index c501d1c01..b52e45030 100644
--- a/doc/manual/command-ref/env-common.xml
+++ b/doc/manual/command-ref/env-common.xml
@@ -11,8 +11,8 @@
<variablelist xml:id="env-common">
-
-<varlistentry><term><envar>NIX_PATH</envar></term>
+
+<varlistentry xml:id="env-NIX_PATH"><term><envar>NIX_PATH</envar></term>
<listitem>
@@ -28,7 +28,7 @@
<filename>/home/eelco/Dev</filename> and
<filename>/etc/nixos</filename>, in that order. It is also
possible to match paths against a prefix. For example, the value
-
+
<screen>
nixpkgs=/home/eelco/Dev/nixpkgs-branch:/etc/nixos</screen>
@@ -39,12 +39,12 @@ nixpkgs=/home/eelco/Dev/nixpkgs-branch:/etc/nixos</screen>
<filename>/etc/nixos/nixpkgs/<replaceable>path</replaceable></filename>.
</para>
- <para>The search path can be extended using the
- <option>-I</option> option, which takes precedence over
+ <para>The search path can be extended using the <option
+ linkend="opt-I">-I</option> option, which takes precedence over
<envar>NIX_PATH</envar>.</para></listitem>
</varlistentry>
-
+
<varlistentry><term><envar>NIX_IGNORE_SYMLINK_STORE</envar></term>
@@ -67,7 +67,7 @@ nixpkgs=/home/eelco/Dev/nixpkgs-branch:/etc/nixos</screen>
you’re better off using <literal>bind</literal> mount points, e.g.,
<screen>
-$ mkdir /nix
+$ mkdir /nix
$ mount -o bind /mnt/otherdisk/nix /nix</screen>
Consult the <citerefentry><refentrytitle>mount</refentrytitle>
@@ -82,7 +82,7 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
<listitem><para>Overrides the location of the Nix store (default
<filename><replaceable>prefix</replaceable>/store</filename>).</para></listitem>
-
+
</varlistentry>
@@ -91,7 +91,7 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
<listitem><para>Overrides the location of the Nix static data
directory (default
<filename><replaceable>prefix</replaceable>/share</filename>).</para></listitem>
-
+
</varlistentry>
@@ -99,7 +99,7 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
<listitem><para>Overrides the location of the Nix log directory
(default <filename><replaceable>prefix</replaceable>/log/nix</filename>).</para></listitem>
-
+
</varlistentry>
@@ -107,7 +107,7 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
<listitem><para>Overrides the location of the Nix state directory
(default <filename><replaceable>prefix</replaceable>/var/nix</filename>).</para></listitem>
-
+
</varlistentry>
@@ -116,7 +116,7 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
<listitem><para>Overrides the location of the Nix database (default
<filename><replaceable>$NIX_STATE_DIR</replaceable>/db</filename>, i.e.,
<filename><replaceable>prefix</replaceable>/var/nix/db</filename>).</para></listitem>
-
+
</varlistentry>
@@ -125,7 +125,7 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
<listitem><para>Overrides the location of the Nix configuration
directory (default
<filename><replaceable>prefix</replaceable>/etc/nix</filename>).</para></listitem>
-
+
</varlistentry>
@@ -135,7 +135,7 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
files. In particular, this includes temporary build directories;
these can take up substantial amounts of disk space. The default is
<filename>/tmp</filename>.</para></listitem>
-
+
</varlistentry>
@@ -233,7 +233,7 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
store derivation itself).</para></listitem>
</varlistentry>
-
+
<varlistentry><term><filename>outputs</filename></term>
<listitem><para>The set of store paths that are outputs of the
@@ -282,7 +282,7 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
</varlistentry>
-
+
<varlistentry xml:id="envar-other-stores"><term><envar>NIX_OTHER_STORES</envar></term>
<listitem><para>This variable contains the paths of remote Nix
@@ -333,7 +333,7 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
</varlistentry>
-
+
</variablelist>
diff --git a/doc/manual/command-ref/nix-instantiate.xml b/doc/manual/command-ref/nix-instantiate.xml
index a4e45cf97..8649cd58c 100644
--- a/doc/manual/command-ref/nix-instantiate.xml
+++ b/doc/manual/command-ref/nix-instantiate.xml
@@ -104,9 +104,10 @@ input.</para>
<varlistentry><term><option>--find-file</option></term>
<listitem><para>Look up the given files in Nix’s search path (as
- specified by the <envar>NIX_PATH</envar> environment variable).
- If found, print the corresponding absolute paths on standard
- output. For instance, if <envar>NIX_PATH</envar> is
+ specified by the <envar linkend="env-NIX_PATH">NIX_PATH</envar>
+ environment variable). If found, print the corresponding absolute
+ paths on standard output. For instance, if
+ <envar>NIX_PATH</envar> is
<literal>nixpkgs=/home/alice/nixpkgs</literal>, then
<literal>nix-instantiate --find-file nixpkgs/default.nix</literal>
will print
diff --git a/doc/manual/command-ref/opt-common.xml b/doc/manual/command-ref/opt-common.xml
index 3486c7e7d..c7e8ae1ed 100644
--- a/doc/manual/command-ref/opt-common.xml
+++ b/doc/manual/command-ref/opt-common.xml
@@ -351,13 +351,14 @@
</varlistentry>
-<varlistentry><term><option>-I</option> <replaceable>path</replaceable></term>
+<varlistentry xml:id="opt-I"><term><option>-I</option> <replaceable>path</replaceable></term>
<listitem><para>Add a path to the Nix expression search path. This
- option may be given multiple times. See the <envar>NIX_PATH</envar>
- environment variable for information on the semantics of the Nix
- search path. Paths added through <option>-I</option> take
- precedence over <envar>NIX_PATH</envar>.</para></listitem>
+ option may be given multiple times. See the <envar
+ linkend="env-NIX_PATH">NIX_PATH</envar> environment variable for
+ information on the semantics of the Nix search path. Paths added
+ through <option>-I</option> take precedence over
+ <envar>NIX_PATH</envar>.</para></listitem>
</varlistentry>
diff --git a/doc/manual/expressions/advanced-attributes.xml b/doc/manual/expressions/advanced-attributes.xml
index 40a5a80ac..f8b84b98c 100644
--- a/doc/manual/expressions/advanced-attributes.xml
+++ b/doc/manual/expressions/advanced-attributes.xml
@@ -32,6 +32,25 @@ allowedReferences = [];
</varlistentry>
+ <varlistentry><term><varname>allowedRequisites</varname></term>
+
+ <listitem><para>This attribute is similar to
+ <varname>allowedReferences</varname>, but it specifies the legal
+ requisites of the whole closure, so all the dependencies
+ recursively. For example,
+
+<programlisting>
+allowedReferences = [ foobar ];
+</programlisting>
+
+ enforces that the output of a derivation cannot have any other
+ runtime dependency than <varname>foobar</varname>, and in addition
+ it enforces that <varname>foobar</varname> itself doesn't
+ introduce any other dependency itself.</para></listitem>
+
+ </varlistentry>
+
+
<varlistentry><term><varname>exportReferencesGraph</varname></term>
<listitem><para>This attribute allows builders access to the
@@ -240,4 +259,4 @@ impureEnvVars = [ "http_proxy" "https_proxy" <replaceable>...</replaceable> ];
</variablelist>
-</section> \ No newline at end of file
+</section>
diff --git a/doc/manual/release-notes/rl-18.xml b/doc/manual/release-notes/rl-18.xml
index 0fe3c2de7..aace95210 100644
--- a/doc/manual/release-notes/rl-18.xml
+++ b/doc/manual/release-notes/rl-18.xml
@@ -6,6 +6,16 @@
<title>Release 1.8 (TBA)</title>
-<para>TODO</para>
+<itemizedlist>
-</chapter> \ No newline at end of file
+ <listitem><para>Derivations can specify the new special attribute
+ <varname>allowedRequisites</varname>, which has a similar meaning to
+ <varname>allowedReferences</varname>. But instead of only enforcing
+ to explicitly specify the immediate references, it requires the
+ derivation to specify all the dependencies recursively (hence the
+ name, requisites) that are used by the resulting
+ output.</para></listitem>
+
+</itemizedlist>
+
+</chapter>
diff --git a/release.nix b/release.nix
index bc4c06a0b..3e741660c 100644
--- a/release.nix
+++ b/release.nix
@@ -214,11 +214,11 @@ let
# System tests.
tests.remote_builds = (import ./tests/remote-builds.nix rec {
nix = build.x86_64-linux; system = "x86_64-linux";
- }).test;
+ });
tests.nix_copy_closure = (import ./tests/nix-copy-closure.nix rec {
nix = build.x86_64-linux; system = "x86_64-linux";
- }).test;
+ });
# Aggregate job containing the release-critical jobs.
diff --git a/scripts/build-remote.pl.in b/scripts/build-remote.pl.in
index 2eb339675..5f0c72b66 100755
--- a/scripts/build-remote.pl.in
+++ b/scripts/build-remote.pl.in
@@ -1,5 +1,6 @@
#! @perl@ -w @perlFlags@
+use utf8;
use Fcntl qw(:DEFAULT :flock);
use English '-no_match_vars';
use IO::Handle;
@@ -7,8 +8,14 @@ use Nix::Config;
use Nix::SSH;
use Nix::CopyClosure;
use Nix::Store;
+use Encode;
no warnings('once');
+STDERR->autoflush(1);
+binmode STDERR, ":encoding(utf8)";
+
+my $debug = defined $ENV{NIX_DEBUG_HOOK};
+
# General operation:
#
@@ -148,7 +155,7 @@ REQ: while (1) {
}
}
- if (defined $ENV{NIX_DEBUG_HOOK}) {
+ if ($debug) {
print STDERR "load on " . $_->{machine}->{hostName} . " = " . $_->{load} . "\n"
foreach @available;
}
@@ -258,7 +265,7 @@ writeInt($maxSilentTime, $to);
writeInt($buildTimeout, $to);
my $res = readInt($from);
if ($res != 0) {
- my $msg = readString($from);
+ my $msg = decode("utf-8", readString($from));
print STDERR "error: $msg on ‘$hostName’\n";
exit $res;
}
diff --git a/scripts/download-from-binary-cache.pl.in b/scripts/download-from-binary-cache.pl.in
index e09b051a4..cdce8eb74 100644
--- a/scripts/download-from-binary-cache.pl.in
+++ b/scripts/download-from-binary-cache.pl.in
@@ -1,5 +1,6 @@
#! @perl@ -w @perlFlags@
+use utf8;
use DBI;
use DBD::SQLite;
use File::Basename;
@@ -12,6 +13,7 @@ use WWW::Curl::Easy;
use WWW::Curl::Multi;
use strict;
+binmode STDERR, ":encoding(utf8)";
Nix::Config::readConfig;
diff --git a/scripts/download-using-manifests.pl.in b/scripts/download-using-manifests.pl.in
index e849a930e..591cd6b43 100755
--- a/scripts/download-using-manifests.pl.in
+++ b/scripts/download-using-manifests.pl.in
@@ -9,6 +9,7 @@ use Nix::Utils;
use POSIX qw(strftime);
STDOUT->autoflush(1);
+binmode STDERR, ":encoding(utf8)";
my $logFile = "$Nix::Config::logDir/downloads";
diff --git a/scripts/nix-build.in b/scripts/nix-build.in
index fb92a4909..f8cf318ff 100755
--- a/scripts/nix-build.in
+++ b/scripts/nix-build.in
@@ -1,10 +1,12 @@
#! @perl@ -w @perlFlags@
+use utf8;
use strict;
use Nix::Config;
use Nix::Store;
use Nix::Utils;
+binmode STDERR, ":encoding(utf8)";
my $dryRun = 0;
my $verbose = 0;
diff --git a/scripts/nix-channel.in b/scripts/nix-channel.in
index 407f27490..e45b91338 100755
--- a/scripts/nix-channel.in
+++ b/scripts/nix-channel.in
@@ -1,11 +1,14 @@
#! @perl@ -w @perlFlags@
+use utf8;
use strict;
use File::Basename;
use File::Path qw(mkpath);
use Nix::Config;
use Nix::Manifest;
+binmode STDERR, ":encoding(utf8)";
+
Nix::Config::readConfig;
my $manifestDir = $Nix::Config::manifestDir;
diff --git a/scripts/nix-copy-closure.in b/scripts/nix-copy-closure.in
index 10c2a9171..f4d186256 100755
--- a/scripts/nix-copy-closure.in
+++ b/scripts/nix-copy-closure.in
@@ -6,6 +6,7 @@ use Nix::Store;
use Nix::CopyClosure;
use List::Util qw(sum);
+binmode STDERR, ":encoding(utf8)";
if (scalar @ARGV < 1) {
print STDERR <<EOF
diff --git a/scripts/nix-install-package.in b/scripts/nix-install-package.in
index 9340f1b72..23f6efbcd 100755
--- a/scripts/nix-install-package.in
+++ b/scripts/nix-install-package.in
@@ -1,9 +1,12 @@
#! @perl@ -w @perlFlags@
+use utf8;
use strict;
use Nix::Config;
use Nix::Utils;
+binmode STDERR, ":encoding(utf8)";
+
# Parse the command line arguments.
my @args = @ARGV;
diff --git a/scripts/nix-prefetch-url.in b/scripts/nix-prefetch-url.in
index 869d29c39..6effbe208 100755
--- a/scripts/nix-prefetch-url.in
+++ b/scripts/nix-prefetch-url.in
@@ -1,5 +1,6 @@
#! @perl@ -w @perlFlags@
+use utf8;
use strict;
use File::Basename;
use File::stat;
@@ -7,6 +8,9 @@ use Nix::Store;
use Nix::Config;
use Nix::Utils;
+binmode STDERR, ":encoding(utf8)";
+
+
my $hashType = $ENV{'NIX_HASH_ALGO'} || "sha256"; # obsolete
my $cacheDir = $ENV{'NIX_DOWNLOAD_CACHE'};
diff --git a/scripts/nix-pull.in b/scripts/nix-pull.in
index f9785d8e5..995b50935 100755
--- a/scripts/nix-pull.in
+++ b/scripts/nix-pull.in
@@ -1,9 +1,12 @@
#! @perl@ -w @perlFlags@
+use utf8;
use strict;
use Nix::Config;
use Nix::Manifest;
+binmode STDERR, ":encoding(utf8)";
+
my $manifestDir = $Nix::Config::manifestDir;
diff --git a/scripts/nix-push.in b/scripts/nix-push.in
index b0cb6d0da..c6d187704 100755
--- a/scripts/nix-push.in
+++ b/scripts/nix-push.in
@@ -1,5 +1,6 @@
#! @perl@ -w @perlFlags@
+use utf8;
use strict;
use File::Basename;
use File::Path qw(mkpath);
@@ -11,6 +12,8 @@ use Nix::Manifest;
use Nix::Utils;
use Nix::Crypto;
+binmode STDERR, ":encoding(utf8)";
+
my $tmpDir = mkTempDir("nix-push");
my $nixExpr = "$tmpDir/create-nars.nix";
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 5cb6fc3cf..2af6a6787 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -1330,7 +1330,7 @@ Path EvalState::coerceToPath(const Pos & pos, Value & v, PathSet & context)
{
string path = coerceToString(pos, v, context, false, false);
if (path == "" || path[0] != '/')
- throwEvalError("string ‘%1%’ doesn't represent an absolute path, at %1%", path, pos);
+ throwEvalError("string ‘%1%’ doesn't represent an absolute path, at %2%", path, pos);
return path;
}
diff --git a/src/libexpr/local.mk b/src/libexpr/local.mk
index 75a0e185e..620a03538 100644
--- a/src/libexpr/local.mk
+++ b/src/libexpr/local.mk
@@ -15,16 +15,14 @@ libexpr_LDFLAGS = -ldl
# because inline functions in libexpr's header files call libgc.
libexpr_LDFLAGS_PROPAGATED = $(BDW_GC_LIBS)
+libexpr_ORDER_AFTER := $(d)/parser-tab.cc $(d)/parser-tab.hh $(d)/lexer-tab.cc $(d)/lexer-tab.hh
+
$(d)/parser-tab.cc $(d)/parser-tab.hh: $(d)/parser.y
$(trace-gen) bison -v -o $(libexpr_DIR)/parser-tab.cc $< -d
$(d)/lexer-tab.cc $(d)/lexer-tab.hh: $(d)/lexer.l
$(trace-gen) flex --outfile $(libexpr_DIR)/lexer-tab.cc --header-file=$(libexpr_DIR)/lexer-tab.hh $<
-$(d)/lexer-tab.o: $(d)/lexer-tab.hh $(d)/parser-tab.hh
-
-$(d)/parser-tab.o: $(d)/lexer-tab.hh $(d)/parser-tab.hh
-
clean-files += $(d)/parser-tab.cc $(d)/parser-tab.hh $(d)/lexer-tab.cc $(d)/lexer-tab.hh
dist-files += $(d)/parser-tab.cc $(d)/parser-tab.hh $(d)/lexer-tab.cc $(d)/lexer-tab.hh
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index c547a5cbf..0d290d787 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -2318,16 +2318,36 @@ void DerivationGoal::registerOutputs()
debug(format("referenced input: ‘%1%’") % *i);
}
- /* If the derivation specifies an `allowedReferences'
- attribute (containing a list of paths that the output may
- refer to), check that all references are in that list. !!!
- allowedReferences should really be per-output. */
- if (drv.env.find("allowedReferences") != drv.env.end()) {
- PathSet allowed = parseReferenceSpecifiers(drv, get(drv.env, "allowedReferences"));
- foreach (PathSet::iterator, i, references)
- if (allowed.find(*i) == allowed.end())
- throw BuildError(format("output is not allowed to refer to path ‘%1%’") % *i);
- }
+ /* Enforce `allowedReferences' and friends. */
+ auto checkRefs = [&](const string & attrName, bool allowed, bool recursive) {
+ if (drv.env.find(attrName) == drv.env.end()) return;
+
+ PathSet spec = parseReferenceSpecifiers(drv, get(drv.env, attrName));
+
+ PathSet used;
+ if (recursive) {
+ /* Our requisites are the union of the closures of our references. */
+ for (auto & i : references)
+ /* Don't call computeFSClosure on ourselves. */
+ if (actualPath != i)
+ computeFSClosure(worker.store, i, used);
+ } else
+ used = references;
+
+ for (auto & i : used)
+ if (allowed) {
+ if (spec.find(i) == spec.end())
+ throw BuildError(format("output (‘%1%’) is not allowed to refer to path ‘%2%’") % actualPath % i);
+ } else {
+ if (spec.find(i) != spec.end())
+ throw BuildError(format("output (‘%1%’) is not allowed to refer to path ‘%2%’") % actualPath % i);
+ }
+ };
+
+ checkRefs("allowedReferences", true, false);
+ checkRefs("allowedRequisites", true, true);
+ checkRefs("disallowedReferences", false, false);
+ checkRefs("disallowedRequisites", false, true);
worker.store.optimisePath(path); // FIXME: combine with scanForReferences()
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index e58e6563f..dccdba533 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -167,6 +167,9 @@ public:
files with the same contents. */
void optimiseStore(OptimiseStats & stats);
+ /* Generic variant of the above method. */
+ void optimiseStore();
+
/* Optimise a single store path. */
void optimisePath(const Path & path);
diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc
index 208d9688e..dd18d66fa 100644
--- a/src/libstore/optimise-store.cc
+++ b/src/libstore/optimise-store.cc
@@ -225,6 +225,22 @@ void LocalStore::optimiseStore(OptimiseStats & stats)
}
}
+static string showBytes(unsigned long long bytes)
+{
+ return (format("%.2f MiB") % (bytes / (1024.0 * 1024.0))).str();
+}
+
+void LocalStore::optimiseStore()
+{
+ OptimiseStats stats;
+
+ optimiseStore(stats);
+
+ printMsg(lvlError,
+ format("%1% freed by hard-linking %2% files")
+ % showBytes(stats.bytesFreed)
+ % stats.filesLinked);
+}
void LocalStore::optimisePath(const Path & path)
{
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index 8ef673783..a0e9f2241 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -579,6 +579,13 @@ void RemoteStore::clearFailedPaths(const PathSet & paths)
readInt(from);
}
+void RemoteStore::optimiseStore()
+{
+ openConnection();
+ writeInt(wopOptimiseStore, to);
+ processStderr();
+ readInt(from);
+}
void RemoteStore::processStderr(Sink * sink, Source * source)
{
diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh
index b01014764..98774c10b 100644
--- a/src/libstore/remote-store.hh
+++ b/src/libstore/remote-store.hh
@@ -82,7 +82,9 @@ public:
PathSet queryFailedPaths();
void clearFailedPaths(const PathSet & paths);
-
+
+ void optimiseStore();
+
private:
AutoCloseFD fdSocket;
FdSink to;
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index b635fee2c..3109f100e 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -250,6 +250,10 @@ public:
`nix-store --register-validity'. */
string makeValidityRegistration(const PathSet & paths,
bool showDerivers, bool showHash);
+
+ /* Optimise the disk space usage of the Nix store by hard-linking files
+ with the same contents. */
+ virtual void optimiseStore() = 0;
};
diff --git a/src/libstore/worker-protocol.hh b/src/libstore/worker-protocol.hh
index c7d3a726a..4b040b77c 100644
--- a/src/libstore/worker-protocol.hh
+++ b/src/libstore/worker-protocol.hh
@@ -42,6 +42,7 @@ typedef enum {
wopQueryValidPaths = 31,
wopQuerySubstitutablePaths = 32,
wopQueryValidDerivers = 33,
+ wopOptimiseStore = 34
} WorkerOp;
diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc
index ced356c34..0f3235d76 100644
--- a/src/nix-daemon/nix-daemon.cc
+++ b/src/nix-daemon/nix-daemon.cc
@@ -508,6 +508,13 @@ static void performOp(bool trusted, unsigned int clientVersion,
break;
}
+ case wopOptimiseStore:
+ startWork();
+ store->optimiseStore();
+ stopWork();
+ writeInt(1, to);
+ break;
+
default:
throw Error(format("invalid operation %1%") % op);
}
diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc
index 8c3744824..51839fac1 100644
--- a/src/nix-store/nix-store.cc
+++ b/src/nix-store/nix-store.cc
@@ -823,16 +823,6 @@ static void opRepairPath(Strings opFlags, Strings opArgs)
}
}
-
-static void showOptimiseStats(OptimiseStats & stats)
-{
- printMsg(lvlError,
- format("%1% freed by hard-linking %2% files")
- % showBytes(stats.bytesFreed)
- % stats.filesLinked);
-}
-
-
/* Optimise the disk space usage of the Nix store by hard-linking
files with the same contents. */
static void opOptimise(Strings opFlags, Strings opArgs)
@@ -840,17 +830,9 @@ static void opOptimise(Strings opFlags, Strings opArgs)
if (!opArgs.empty() || !opFlags.empty())
throw UsageError("no arguments expected");
- OptimiseStats stats;
- try {
- ensureLocalStore().optimiseStore(stats);
- } catch (...) {
- showOptimiseStats(stats);
- throw;
- }
- showOptimiseStats(stats);
+ store->optimiseStore();
}
-
static void opQueryFailedPaths(Strings opFlags, Strings opArgs)
{
if (!opArgs.empty() || !opFlags.empty())
diff --git a/tests/check-refs.nix b/tests/check-refs.nix
index 63791fe16..9d90b0920 100644
--- a/tests/check-refs.nix
+++ b/tests/check-refs.nix
@@ -55,4 +55,16 @@ rec {
inherit dep;
};
+ test9 = makeTest 9 {
+ builder = builtins.toFile "builder.sh" "mkdir $out; ln -s $dep $out/link";
+ inherit dep;
+ disallowedReferences = [dep];
+ };
+
+ test10 = makeTest 10 {
+ builder = builtins.toFile "builder.sh" "mkdir $out; echo $test5; ln -s $dep $out/link";
+ inherit dep test5;
+ disallowedReferences = [test5];
+ };
+
}
diff --git a/tests/check-refs.sh b/tests/check-refs.sh
index 9e103664a..34ee22cfc 100644
--- a/tests/check-refs.sh
+++ b/tests/check-refs.sh
@@ -32,3 +32,9 @@ nix-build -o $RESULT check-refs.nix -A test7
# test8 should fail (toFile depending on derivation output).
(! nix-build -o $RESULT check-refs.nix -A test8)
+
+# test9 should fail (disallowed reference).
+(! nix-build -o $RESULT check-refs.nix -A test9)
+
+# test10 should succeed (no disallowed references).
+nix-build -o $RESULT check-refs.nix -A test10
diff --git a/tests/check-reqs.nix b/tests/check-reqs.nix
new file mode 100644
index 000000000..41436cb48
--- /dev/null
+++ b/tests/check-reqs.nix
@@ -0,0 +1,57 @@
+with import ./config.nix;
+
+rec {
+ dep1 = mkDerivation {
+ name = "check-reqs-dep1";
+ builder = builtins.toFile "builder.sh" "mkdir $out; touch $out/file1";
+ };
+
+ dep2 = mkDerivation {
+ name = "check-reqs-dep2";
+ builder = builtins.toFile "builder.sh" "mkdir $out; touch $out/file2";
+ };
+
+ deps = mkDerivation {
+ name = "check-reqs-deps";
+ dep1 = dep1;
+ dep2 = dep2;
+ builder = builtins.toFile "builder.sh" ''
+ mkdir $out
+ ln -s $dep1/file1 $out/file1
+ ln -s $dep2/file2 $out/file2
+ '';
+ };
+
+ makeTest = nr: allowreqs: mkDerivation {
+ name = "check-reqs-" + toString nr;
+ inherit deps;
+ builder = builtins.toFile "builder.sh" ''
+ mkdir $out
+ ln -s $deps $out/depdir1
+ '';
+ allowedRequisites = allowreqs;
+ };
+
+ # When specifying all the requisites, the build succeeds.
+ test1 = makeTest 1 [ dep1 dep2 deps ];
+
+ # But missing anything it fails.
+ test2 = makeTest 2 [ dep2 deps ];
+ test3 = makeTest 3 [ dep1 deps ];
+ test4 = makeTest 4 [ deps ];
+ test5 = makeTest 5 [];
+
+ test6 = mkDerivation {
+ name = "check-reqs";
+ inherit deps;
+ builder = builtins.toFile "builder.sh" "mkdir $out; ln -s $deps $out/depdir1";
+ disallowedRequisites = [dep1];
+ };
+
+ test7 = mkDerivation {
+ name = "check-reqs";
+ inherit deps;
+ builder = builtins.toFile "builder.sh" "mkdir $out; ln -s $deps $out/depdir1";
+ disallowedRequisites = [test1];
+ };
+}
diff --git a/tests/check-reqs.sh b/tests/check-reqs.sh
new file mode 100644
index 000000000..8b2454915
--- /dev/null
+++ b/tests/check-reqs.sh
@@ -0,0 +1,13 @@
+source common.sh
+
+RESULT=$TEST_ROOT/result
+
+nix-build -o $RESULT check-reqs.nix -A test1
+
+(! nix-build -o $RESULT check-reqs.nix -A test2)
+(! nix-build -o $RESULT check-reqs.nix -A test3)
+(! nix-build -o $RESULT check-reqs.nix -A test4)
+(! nix-build -o $RESULT check-reqs.nix -A test5)
+(! nix-build -o $RESULT check-reqs.nix -A test6)
+
+nix-build -o $RESULT check-reqs.nix -A test7
diff --git a/tests/local.mk b/tests/local.mk
index 65aa12637..69a227495 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -10,7 +10,8 @@ nix_tests = \
remote-store.sh export.sh export-graph.sh negative-caching.sh \
binary-patching.sh timeout.sh secure-drv-outputs.sh nix-channel.sh \
multiple-outputs.sh import-derivation.sh fetchurl.sh optimise-store.sh \
- binary-cache.sh nix-profile.sh repair.sh dump-db.sh case-hack.sh
+ binary-cache.sh nix-profile.sh repair.sh dump-db.sh case-hack.sh \
+ check-reqs.sh
# parallel.sh
install-tests += $(foreach x, $(nix_tests), tests/$(x))
diff --git a/tests/remote-builds.nix b/tests/remote-builds.nix
index 81b81b87c..5e2688d1a 100644
--- a/tests/remote-builds.nix
+++ b/tests/remote-builds.nix
@@ -60,6 +60,7 @@ in
virtualisation.pathsInNixDB = [ config.system.build.extraUtils ];
nix.package = nix;
nix.binaryCaches = [ ];
+ programs.ssh.extraConfig = "ConnectTimeout 30";
};
};
@@ -69,14 +70,14 @@ in
# Create an SSH key on the client.
my $key = `${pkgs.openssh}/bin/ssh-keygen -t dsa -f key -N ""`;
- $client->succeed("mkdir -m 700 /root/.ssh");
+ $client->succeed("mkdir -p -m 700 /root/.ssh");
$client->copyFileFromHost("key", "/root/.ssh/id_dsa");
$client->succeed("chmod 600 /root/.ssh/id_dsa");
# Install the SSH key on the slaves.
$client->waitForUnit("network.target");
foreach my $slave ($slave1, $slave2) {
- $slave->succeed("mkdir -m 700 /root/.ssh");
+ $slave->succeed("mkdir -p -m 700 /root/.ssh");
$slave->copyFileFromHost("key.pub", "/root/.ssh/authorized_keys");
$slave->waitForUnit("sshd");
$client->succeed("ssh -o StrictHostKeyChecking=no " . $slave->name() . " 'echo hello world'");