* 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:
Eelco Dolstra 2006-10-19 16:09:24 +00:00
parent daa8f85fcd
commit 6a67556f71
1 changed files with 31 additions and 0 deletions

View File

@ -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