[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
162/376: Introduce allowedRequisites feature
From: |
Ludovic Courtès |
Subject: |
162/376: Introduce allowedRequisites feature |
Date: |
Wed, 28 Jan 2015 22:04:45 +0000 |
civodul pushed a commit to tag 1.8
in repository guix.
commit fd61069a42289da195532bf68d15dc695cca7236
Author: Gergely Risko <address@hidden>
Date: Wed Aug 27 16:46:02 2014 +0200
Introduce allowedRequisites feature
---
doc/manual/release-notes.xml | 14 ++++++++++
doc/manual/writing-nix-expressions.xml | 19 ++++++++++++++
src/libstore/build.cc | 19 +++++++++++++-
tests/check-reqs.nix | 43 ++++++++++++++++++++++++++++++++
tests/check-reqs.sh | 12 +++++++++
tests/local.mk | 3 +-
6 files changed, 108 insertions(+), 2 deletions(-)
diff --git a/doc/manual/release-notes.xml b/doc/manual/release-notes.xml
index 426078b..36e345e 100644
--- a/doc/manual/release-notes.xml
+++ b/doc/manual/release-notes.xml
@@ -11,6 +11,20 @@
<para>TODO</para>
+<itemizedlist>
+
+ <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. This is
+ used in NixOS when rebuilding the stdenv on Linux to ensure that the
+ resulting stdenv doesn't have any surprising dependency, e.g. on
+ bootstrapTools.</para></listitem>
+
+</itemizedlist>
+
</section>
diff --git a/doc/manual/writing-nix-expressions.xml
b/doc/manual/writing-nix-expressions.xml
index 0470625..2c9b4a6 100644
--- a/doc/manual/writing-nix-expressions.xml
+++ b/doc/manual/writing-nix-expressions.xml
@@ -1569,6 +1569,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. This is used in NixOS when
+ rebuilding the stdenv on Linux to ensure that the resulting stdenv
+ doesn't have any surprising dependency, e.g. on bootstrapTools.
+
+ </varlistentry>
<varlistentry><term><varname>exportReferencesGraph</varname></term>
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index c547a5c..6390a74 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -2326,7 +2326,24 @@ void DerivationGoal::registerOutputs()
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);
+ throw BuildError(format("output (‘%1%’) is not allowed to
refer to path ‘%2%’") % actualPath % *i);
+ }
+
+ /* If the derivation specifies an `allowedRequisites'
+ attribute (containing a list of paths that the output may
+ refer to), check that all requisites are in that list. !!!
+ allowedRequisites should really be per-output. */
+ if (drv.env.find("allowedRequisites") != drv.env.end()) {
+ PathSet allowed = parseReferenceSpecifiers(drv, get(drv.env,
"allowedRequisites"));
+ PathSet requisites;
+ /* Our requisites are the union of the closures of our references.
*/
+ foreach (PathSet::iterator, i, references)
+ /* Don't call computeFSClosure on ourselves. */
+ if (actualPath != *i)
+ computeFSClosure(worker.store, *i, requisites);
+ foreach (PathSet::iterator, i, requisites)
+ if (allowed.find(*i) == allowed.end())
+ throw BuildError(format("output (‘%1%’) is not allowed to
refer to requisite path ‘%2%’") % actualPath % *i);
}
worker.store.optimisePath(path); // FIXME: combine with
scanForReferences()
diff --git a/tests/check-reqs.nix b/tests/check-reqs.nix
new file mode 100644
index 0000000..5af8ea6
--- /dev/null
+++ b/tests/check-reqs.nix
@@ -0,0 +1,43 @@
+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 [];
+}
diff --git a/tests/check-reqs.sh b/tests/check-reqs.sh
new file mode 100644
index 0000000..643c2d0
--- /dev/null
+++ b/tests/check-reqs.sh
@@ -0,0 +1,12 @@
+source common.sh
+
+RESULT=$TEST_ROOT/result
+
+# test1 should succeed.
+nix-build -o $RESULT check-reqs.nix -A test1
+
+# test{2,3,4,5} should fail.
+(! 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)
diff --git a/tests/local.mk b/tests/local.mk
index 65aa126..69a2274 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))
- 146/376: Install config.h only once, (continued)
- 146/376: Install config.h only once, Ludovic Courtès, 2015/01/28
- 148/376: Force template regeneration, Ludovic Courtès, 2015/01/28
- 158/376: fix disappearing bash arguments, Ludovic Courtès, 2015/01/28
- 150/376: Provide reasonable default flags for $LESS, Ludovic Courtès, 2015/01/28
- 149/376: Merge commit '2aa93858afee22e0c32d8f4366970976374091ac', Ludovic Courtès, 2015/01/28
- 156/376: Use PR_SET_PDEATHSIG to ensure child cleanup, Ludovic Courtès, 2015/01/28
- 155/376: Set a curl timeout on binary cache lookups, Ludovic Courtès, 2015/01/28
- 163/376: Fix manual build, Ludovic Courtès, 2015/01/28
- 159/376: Document the "out" usage in allowedReferences, Ludovic Courtès, 2015/01/28
- 154/376: Use unshare() instead of clone(), Ludovic Courtès, 2015/01/28
- 162/376: Introduce allowedRequisites feature,
Ludovic Courtès <=
- 157/376: Fix tests, Ludovic Courtès, 2015/01/28
- 151/376: Use pager for more commands, Ludovic Courtès, 2015/01/28
- 153/376: Fix a segfault in ‘nix-env -qa’, Ludovic Courtès, 2015/01/28
- 164/376: allowedRequisites: Drop stdenv mention, Ludovic Courtès, 2015/01/28
- 160/376: Fix building with Clang, Ludovic Courtès, 2015/01/28
- 170/376: Fix dependency ordering, Ludovic Courtès, 2015/01/28
- 169/376: Hack for supporting Boost on Homebrew, Ludovic Courtès, 2015/01/28
- 166/376: Shut up "Wide character" warnings in Perl scripts, Ludovic Courtès, 2015/01/28
- 167/376: Add an 'optimiseStore' remote procedure call., Ludovic Courtès, 2015/01/28
- 171/376: Fix build-remote.pl, Ludovic Courtès, 2015/01/28