diff options
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'"); |