diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2006-10-19T16·09+0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2006-10-19T16·09+0000 |
commit | 6a67556f7192108d612560992e97a14b0fe16a22 (patch) | |
tree | 2ca8124849c212d018f8fc6865b3bec696260717 | |
parent | daa8f85fcd3d5d7c48a51305818e05bee866b936 (diff) |
* Special derivation attribute `allowedReferences' that causes Nix to
check that the references of the output of a derivation are in the specified set. For instance, allowedReferences = []; specifies that the output cannot have any references. (This is useful, for instance, for the generation of bootstrap binaries for stdenv-linux, which must not have any references for purity). It could also be used to guard against undesired runtime dependencies, e.g., {gcc, dynlib}: derivation { ... allowedReferences = [dynlib]; } says that the output can refer to the path of `dynlib' but not `gcc'. A `forbiddedReferences' attribute would be more useful for this, though.
-rw-r--r-- | src/libstore/build.cc | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 647671036de1..2388d008f4cf 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -1349,6 +1349,26 @@ void DerivationGoal::startBuilder() } +/* Parse a list of reference specifiers. Each element must either be + a store path, or the symbolic name of the output of the derivation + (such as `out'). */ +PathSet parseReferenceSpecifiers(const Derivation & drv, string attr) +{ + PathSet result; + Paths paths = tokenizeString(attr); + for (Strings::iterator i = paths.begin(); i != paths.end(); ++i) { + if (isStorePath(*i)) + result.insert(*i); + else if (drv.outputs.find(*i) != drv.outputs.end()) + result.insert(drv.outputs.find(*i)->second.path); + else throw Error( + format("derivation contains an illegal reference specifier `%1%'") + % *i); + } + return result; +} + + void DerivationGoal::computeClosure() { map<Path, PathSet> allReferences; @@ -1442,6 +1462,17 @@ void DerivationGoal::computeClosure() allReferences[path] = references; + /* 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, drv.env["allowedReferences"]); + for (PathSet::iterator i = references.begin(); i != references.end(); ++i) + if (allowed.find(*i) == allowed.end()) + throw Error(format("output is not allowed to refer to path `%1%'") % *i); + } + /* Hash the contents of the path. The hash is stored in the database so that we can verify later on whether nobody has messed with the store. !!! inefficient: it would be nice |