* 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.
This commit is contained in:
parent
daa8f85fcd
commit
6a67556f71
|
@ -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()
|
void DerivationGoal::computeClosure()
|
||||||
{
|
{
|
||||||
map<Path, PathSet> allReferences;
|
map<Path, PathSet> allReferences;
|
||||||
|
@ -1442,6 +1462,17 @@ void DerivationGoal::computeClosure()
|
||||||
|
|
||||||
allReferences[path] = references;
|
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
|
/* Hash the contents of the path. The hash is stored in the
|
||||||
database so that we can verify later on whether nobody has
|
database so that we can verify later on whether nobody has
|
||||||
messed with the store. !!! inefficient: it would be nice
|
messed with the store. !!! inefficient: it would be nice
|
||||||
|
|
Loading…
Reference in a new issue