From 6a8ef36fe62c1b53572b0cf64685ece6190b22e5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 14 Feb 2005 13:07:09 +0000 Subject: [PATCH] * Global configuration option `env-keep-derivations' to store pointer to derivations in user environments. Nice for developers (since it prevents build-time-only dependencies from being GC'ed, in conjunction with `gc-keep-outputs'). Turned off by default. --- nix.conf.example | 21 ++++++++++++- src/libstore/gc.cc | 4 +-- src/libstore/globals.cc | 12 +++++++- src/libstore/globals.hh | 2 ++ src/nix-env/main.cc | 68 ++++++++++++++++++++++------------------- 5 files changed, 72 insertions(+), 35 deletions(-) diff --git a/nix.conf.example b/nix.conf.example index 1af5df952..fcdf6fccd 100644 --- a/nix.conf.example +++ b/nix.conf.example @@ -7,7 +7,7 @@ # # In general, outputs must be registered as roots separately. # However, even if the output of a derivation is registered as a root, -# the collector will still delete store paths that are used only a +# the collector will still delete store paths that are used only at # build time (e.g., the C compiler, or source tarballs downloaded from # the network). To prevent it from doing so, set this option to # `true'. @@ -28,3 +28,22 @@ gc-keep-outputs = false # turned on). gc-keep-derivations = true + +### Option `env-keep-derivations' +# +# If `false' (default), derivations are not stored in Nix user +# environments. That is, the derivation any build-time-only +# dependencies may be garbage-collected. +# +# If `true', when you add a Nix derivation to a user environment, the +# path of the derivation is stored in the user environment. Thus, the +# derivation will not be garbage-collected until the user environment +# generation is deleted (`nix-env --delete-generations'). To prevent +# build-time-only dependencies from being collected, you should also +# turn on `gc-keep-outputs'. +# +# The difference between this option and `gc-keep-derivations' is that +# this one is `sticky': it applies to any user environment created +# while this option was enabled, while `gc-keep-derivations' only +# applies at the moment the garbage collector is run. +env-keep-derivations = false diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index 4d63d46ea..98b863314 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -306,7 +306,7 @@ void collectGarbage(GCAction action, PathSet & result) { result.clear(); - string gcKeepOutputs = querySetting("gc-keep-outputs", "false"); + bool gcKeepOutputs = queryBoolSetting("gc-keep-outputs", false); /* Acquire the global GC root. This prevents a) New roots from being added. @@ -330,7 +330,7 @@ void collectGarbage(GCAction action, PathSet & result) for (PathSet::const_iterator i = roots.begin(); i != roots.end(); ++i) computeFSClosure(canonPath(*i), livePaths); - if (gcKeepOutputs == "true") { + if (gcKeepOutputs) { /* Hmz, identical to storePathRequisites in nix-store. */ for (PathSet::iterator i = livePaths.begin(); i != livePaths.end(); ++i) diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index 22820f2fe..4387c8acc 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -52,7 +52,7 @@ static void readSettings() string name, sep, value; is >> name >> sep >> value; if (sep != "=" || !is) - throw Error(format("illegal configuration line `%1%'") % line); + throw Error(format("illegal configuration line `%1%' in `%2%'") % line % settingsFile); settings[name] = value; }; @@ -67,3 +67,13 @@ string querySetting(const string & name, const string & def) map::iterator i = settings.find(name); return i == settings.end() ? def : i->second; } + + +bool queryBoolSetting(const string & name, bool def) +{ + string value = querySetting(name, def ? "true" : "false"); + if (value == "true") return true; + else if (value == "false") return false; + else throw Error(format("configuration option `%1%' should be either `true' or `false', not `%2%'") + % name % value); +} diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index 0e851fd74..e2ae2ed65 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -55,5 +55,7 @@ extern bool readOnlyMode; string querySetting(const string & name, const string & def); +bool queryBoolSetting(const string & name, bool def); + #endif /* !__GLOBALS_H */ diff --git a/src/nix-env/main.cc b/src/nix-env/main.cc index d45dd2bd8..fa07135fc 100644 --- a/src/nix-env/main.cc +++ b/src/nix-env/main.cc @@ -37,6 +37,7 @@ struct Globals EvalState state; bool dryRun; bool preserveInstalled; + bool keepDerivations; }; @@ -203,7 +204,7 @@ void queryInstalled(EvalState & state, DrvInfos & drvs, void createUserEnv(EvalState & state, const DrvInfos & drvs, - const Path & profile) + const Path & profile, bool keepDerivations) { /* Build the components in the user environment, if they don't exist already. */ @@ -227,19 +228,23 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs, for (DrvInfos::const_iterator i = drvs.begin(); i != drvs.end(); ++i) { - ATerm t = makeAttrs(ATmakeList4( + Path drvPath = keepDerivations ? i->second.drvPath : ""; + ATerm t = makeAttrs(ATmakeList5( makeBind(toATerm("type"), makeStr(toATerm("derivation")), makeNoPos()), makeBind(toATerm("name"), makeStr(toATerm(i->second.name)), makeNoPos()), makeBind(toATerm("system"), makeStr(toATerm(i->second.system)), makeNoPos()), + makeBind(toATerm("drvPath"), + makePath(toATerm(drvPath)), makeNoPos()), makeBind(toATerm("outPath"), makePath(toATerm(i->second.outPath)), makeNoPos()) )); manifest = ATinsert(manifest, t); inputs = ATinsert(inputs, makeStr(toATerm(i->second.outPath))); references.insert(i->second.outPath); + if (drvPath != "") references.insert(drvPath); } /* Also write a copy of the list of inputs to the store; we need @@ -247,8 +252,6 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs, Path manifestFile = addTextToStore("env-manifest", atPrint(makeList(ATreverse(manifest))), references); - printMsg(lvlError, format("manifest is %1%") % manifestFile); - Expr topLevel = makeCall(envBuilder, makeAttrs(ATmakeList3( makeBind(toATerm("system"), makeStr(toATerm(thisSystem)), makeNoPos()), @@ -281,15 +284,14 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs, } -static void installDerivations(EvalState & state, - const InstallSourceInfo & instSource, DrvNames & selectors, - const Path & profile, bool dryRun, bool preserveInstalled) +static void installDerivations(Globals & globals, + DrvNames & selectors, const Path & profile) { debug(format("installing derivations")); /* Fetch all derivations from the input file. */ DrvInfos availDrvs; - queryInstSources(state, instSource, availDrvs); + queryInstSources(globals.state, globals.instSource, availDrvs); /* Filter out the ones we're not interested in. */ DrvInfos selectedDrvs; @@ -320,13 +322,13 @@ static void installDerivations(EvalState & state, /* Add in the already installed derivations. */ DrvInfos installedDrvs; - queryInstalled(state, installedDrvs, profile); + queryInstalled(globals.state, installedDrvs, profile); for (DrvInfos::iterator i = installedDrvs.begin(); i != installedDrvs.end(); ++i) { DrvName drvName(i->second.name); - if (!preserveInstalled && + if (!globals.preserveInstalled && selectedNames.find(drvName.name) != selectedNames.end()) printMsg(lvlInfo, format("uninstalling `%1%'") % i->second.name); @@ -334,9 +336,10 @@ static void installDerivations(EvalState & state, selectedDrvs.insert(*i); } - if (dryRun) return; + if (globals.dryRun) return; - createUserEnv(state, selectedDrvs, profile); + createUserEnv(globals.state, selectedDrvs, + profile, globals.keepDerivations); } @@ -348,18 +351,16 @@ static void opInstall(Globals & globals, DrvNames drvNames = drvNamesFromArgs(opArgs); - installDerivations(globals.state, globals.instSource, - drvNames, globals.profile, globals.dryRun, - globals.preserveInstalled); + installDerivations(globals, drvNames, globals.profile); } typedef enum { utLt, utLeq, utAlways } UpgradeType; -static void upgradeDerivations(EvalState & state, - const InstallSourceInfo & instSource, DrvNames & selectors, const Path & profile, - UpgradeType upgradeType, bool dryRun) +static void upgradeDerivations(Globals & globals, + DrvNames & selectors, const Path & profile, + UpgradeType upgradeType) { debug(format("upgrading derivations")); @@ -370,11 +371,11 @@ static void upgradeDerivations(EvalState & state, /* Load the currently installed derivations. */ DrvInfos installedDrvs; - queryInstalled(state, installedDrvs, profile); + queryInstalled(globals.state, installedDrvs, profile); /* Fetch all derivations from the input file. */ DrvInfos availDrvs; - // xxx loadDerivations(state, nePath, availDrvs, systemFilter); + queryInstSources(globals.state, globals.instSource, availDrvs); /* Go through all installed derivations. */ DrvInfos newDrvs; @@ -440,9 +441,10 @@ static void upgradeDerivations(EvalState & state, } else newDrvs.insert(*i); } - if (dryRun) return; + if (globals.dryRun) return; - createUserEnv(state, newDrvs, profile); + createUserEnv(globals.state, newDrvs, + profile, globals.keepDerivations); } @@ -459,16 +461,15 @@ static void opUpgrade(Globals & globals, DrvNames drvNames = drvNamesFromArgs(opArgs); - upgradeDerivations(globals.state, globals.instSource, - drvNames, globals.profile, upgradeType, globals.dryRun); + upgradeDerivations(globals, drvNames, globals.profile, upgradeType); } -static void uninstallDerivations(EvalState & state, DrvNames & selectors, - Path & profile, bool dryRun) +static void uninstallDerivations(Globals & globals, DrvNames & selectors, + Path & profile) { DrvInfos installedDrvs; - queryInstalled(state, installedDrvs, profile); + queryInstalled(globals.state, installedDrvs, profile); for (DrvInfos::iterator i = installedDrvs.begin(); i != installedDrvs.end(); ++i) @@ -483,9 +484,10 @@ static void uninstallDerivations(EvalState & state, DrvNames & selectors, } } - if (dryRun) return; + if (globals.dryRun) return; - createUserEnv(state, installedDrvs, profile); + createUserEnv(globals.state, installedDrvs, + profile, globals.keepDerivations); } @@ -497,8 +499,8 @@ static void opUninstall(Globals & globals, DrvNames drvNames = drvNamesFromArgs(opArgs); - uninstallDerivations(globals.state, drvNames, - globals.profile, globals.dryRun); + uninstallDerivations(globals, drvNames, + globals.profile); } @@ -798,6 +800,7 @@ void run(Strings args) Operation op = 0; Globals globals; + globals.instSource.type = srcUnknown; globals.instSource.nixExprPath = getDefNixExprPath(); globals.instSource.systemFilter = thisSystem; @@ -805,6 +808,9 @@ void run(Strings args) globals.dryRun = false; globals.preserveInstalled = false; + globals.keepDerivations = + queryBoolSetting("env-keep-derivations", false); + for (Strings::iterator i = args.begin(); i != args.end(); ++i) { string arg = *i;