1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-25 06:31:14 +02:00

* Store user environment manifests as a Nix expression in

$out/manifest.nix rather than as an ATerm.

  (Hm, I thought I committed this two days ago...)
This commit is contained in:
Eelco Dolstra 2010-04-21 15:08:58 +00:00
parent f3b8833a48
commit fe2d869e04
11 changed files with 205 additions and 183 deletions

View file

@ -8,7 +8,6 @@
#include "help.txt.hh"
#include "get-drvs.hh"
#include "attr-path.hh"
#include "pathlocks.hh"
#include "common-opts.hh"
#include "xml-writer.hh"
#include "store-api.hh"
@ -193,141 +192,6 @@ static Path getDefNixExprPath()
}
/* Ensure exclusive access to a profile. Any command that modifies
the profile first acquires this lock. */
static void lockProfile(PathLocks & lock, const Path & profile)
{
lock.lockPaths(singleton<PathSet>(profile),
(format("waiting for lock on profile `%1%'") % profile).str());
lock.setDeletion(true);
}
/* Optimistic locking is used by long-running operations like `nix-env
-i'. Instead of acquiring the exclusive lock for the entire
duration of the operation, we just perform the operation
optimistically (without an exclusive lock), and check at the end
whether the profile changed while we were busy (i.e., the symlink
target changed). If so, the operation is restarted. Restarting is
generally cheap, since the build results are still in the Nix
store. Most of the time, only the user environment has to be
rebuilt. */
static string optimisticLockProfile(const Path & profile)
{
return pathExists(profile) ? readLink(profile) : "";
}
static bool createUserEnv(EvalState & state, DrvInfos & elems,
const Path & profile, bool keepDerivations,
const string & lockToken)
{
throw Error("not implemented");
#if 0
/* Build the components in the user environment, if they don't
exist already. */
PathSet drvsToBuild;
foreach (DrvInfos::const_iterator, i, elems)
/* Call to `isDerivation' is for compatibility with Nix <= 0.7
user environments. */
if (i->queryDrvPath(state) != "" &&
isDerivation(i->queryDrvPath(state)))
drvsToBuild.insert(i->queryDrvPath(state));
debug(format("building user environment dependencies"));
store->buildDerivations(drvsToBuild);
/* Get the environment builder expression. */
Expr envBuilder = parseExprFromFile(state,
nixDataDir + "/nix/corepkgs/buildenv"); /* !!! */
/* Construct the whole top level derivation. */
PathSet references;
ATermList manifest = ATempty;
ATermList inputs = ATempty;
foreach (DrvInfos::iterator, i, elems) {
/* Create a pseudo-derivation containing the name, system,
output path, and optionally the derivation path, as well as
the meta attributes. */
Path drvPath = keepDerivations ? i->queryDrvPath(state) : "";
/* Round trip to get rid of "bad" meta values (like
functions). */
MetaInfo meta = i->queryMetaInfo(state);
i->setMetaInfo(meta);
ATermList as = ATmakeList5(
makeBind(toATerm("type"),
makeStr("derivation"), makeNoPos()),
makeBind(toATerm("name"),
makeStr(i->name), makeNoPos()),
makeBind(toATerm("system"),
makeStr(i->system), makeNoPos()),
makeBind(toATerm("outPath"),
makeStr(i->queryOutPath(state)), makeNoPos()),
makeBind(toATerm("meta"),
i->attrs->get(toATerm("meta")), makeNoPos()));
if (drvPath != "") as = ATinsert(as,
makeBind(toATerm("drvPath"),
makeStr(drvPath), makeNoPos()));
manifest = ATinsert(manifest, makeAttrs(as));
inputs = ATinsert(inputs, makeStr(i->queryOutPath(state)));
/* This is only necessary when installing store paths, e.g.,
`nix-env -i /nix/store/abcd...-foo'. */
store->addTempRoot(i->queryOutPath(state));
store->ensurePath(i->queryOutPath(state));
references.insert(i->queryOutPath(state));
if (drvPath != "") references.insert(drvPath);
}
/* Also write a copy of the list of inputs to the store; we need
it for future modifications of the environment. */
Path manifestFile = store->addTextToStore("env-manifest",
atPrint(canonicaliseExpr(makeList(ATreverse(manifest)))), references);
Expr topLevel = makeCall(envBuilder, makeAttrs(ATmakeList3(
makeBind(toATerm("system"),
makeStr(thisSystem), makeNoPos()),
makeBind(toATerm("derivations"),
makeList(ATreverse(manifest)), makeNoPos()),
makeBind(toATerm("manifest"),
makeStr(manifestFile, singleton<PathSet>(manifestFile)), makeNoPos())
)));
/* Instantiate it. */
debug(format("evaluating builder expression `%1%'") % topLevel);
DrvInfo topLevelDrv;
if (!getDerivation(state, topLevel, topLevelDrv))
abort();
/* Realise the resulting store expression. */
debug(format("building user environment"));
store->buildDerivations(singleton<PathSet>(topLevelDrv.queryDrvPath(state)));
/* Switch the current user environment to the output path. */
PathLocks lock;
lockProfile(lock, profile);
Path lockTokenCur = optimisticLockProfile(profile);
if (lockToken != lockTokenCur) {
printMsg(lvlError, format("profile `%1%' changed while we were busy; restarting") % profile);
return false;
}
debug(format("switching to new user environment"));
Path generation = createGeneration(profile, topLevelDrv.queryOutPath(state));
switchLink(profile, generation);
return true;
#endif
}
static int getPriority(EvalState & state, const DrvInfo & drv)
{
MetaValue value = drv.queryMetaInfo(state, "priority");