mirror of
https://github.com/NixOS/nix.git
synced 2024-11-22 14:52:55 +00:00
* 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.
This commit is contained in:
parent
b0aba6ec2a
commit
6a8ef36fe6
@ -7,7 +7,7 @@
|
|||||||
#
|
#
|
||||||
# In general, outputs must be registered as roots separately.
|
# In general, outputs must be registered as roots separately.
|
||||||
# However, even if the output of a derivation is registered as a root,
|
# 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
|
# build time (e.g., the C compiler, or source tarballs downloaded from
|
||||||
# the network). To prevent it from doing so, set this option to
|
# the network). To prevent it from doing so, set this option to
|
||||||
# `true'.
|
# `true'.
|
||||||
@ -28,3 +28,22 @@ gc-keep-outputs = false
|
|||||||
# turned on).
|
# turned on).
|
||||||
gc-keep-derivations = true
|
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
|
||||||
|
@ -306,7 +306,7 @@ void collectGarbage(GCAction action, PathSet & result)
|
|||||||
{
|
{
|
||||||
result.clear();
|
result.clear();
|
||||||
|
|
||||||
string gcKeepOutputs = querySetting("gc-keep-outputs", "false");
|
bool gcKeepOutputs = queryBoolSetting("gc-keep-outputs", false);
|
||||||
|
|
||||||
/* Acquire the global GC root. This prevents
|
/* Acquire the global GC root. This prevents
|
||||||
a) New roots from being added.
|
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)
|
for (PathSet::const_iterator i = roots.begin(); i != roots.end(); ++i)
|
||||||
computeFSClosure(canonPath(*i), livePaths);
|
computeFSClosure(canonPath(*i), livePaths);
|
||||||
|
|
||||||
if (gcKeepOutputs == "true") {
|
if (gcKeepOutputs) {
|
||||||
/* Hmz, identical to storePathRequisites in nix-store. */
|
/* Hmz, identical to storePathRequisites in nix-store. */
|
||||||
for (PathSet::iterator i = livePaths.begin();
|
for (PathSet::iterator i = livePaths.begin();
|
||||||
i != livePaths.end(); ++i)
|
i != livePaths.end(); ++i)
|
||||||
|
@ -52,7 +52,7 @@ static void readSettings()
|
|||||||
string name, sep, value;
|
string name, sep, value;
|
||||||
is >> name >> sep >> value;
|
is >> name >> sep >> value;
|
||||||
if (sep != "=" || !is)
|
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;
|
settings[name] = value;
|
||||||
};
|
};
|
||||||
@ -67,3 +67,13 @@ string querySetting(const string & name, const string & def)
|
|||||||
map<string, string>::iterator i = settings.find(name);
|
map<string, string>::iterator i = settings.find(name);
|
||||||
return i == settings.end() ? def : i->second;
|
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);
|
||||||
|
}
|
||||||
|
@ -55,5 +55,7 @@ extern bool readOnlyMode;
|
|||||||
|
|
||||||
string querySetting(const string & name, const string & def);
|
string querySetting(const string & name, const string & def);
|
||||||
|
|
||||||
|
bool queryBoolSetting(const string & name, bool def);
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__GLOBALS_H */
|
#endif /* !__GLOBALS_H */
|
||||||
|
@ -37,6 +37,7 @@ struct Globals
|
|||||||
EvalState state;
|
EvalState state;
|
||||||
bool dryRun;
|
bool dryRun;
|
||||||
bool preserveInstalled;
|
bool preserveInstalled;
|
||||||
|
bool keepDerivations;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -203,7 +204,7 @@ void queryInstalled(EvalState & state, DrvInfos & drvs,
|
|||||||
|
|
||||||
|
|
||||||
void createUserEnv(EvalState & state, const 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
|
/* Build the components in the user environment, if they don't
|
||||||
exist already. */
|
exist already. */
|
||||||
@ -227,19 +228,23 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs,
|
|||||||
for (DrvInfos::const_iterator i = drvs.begin();
|
for (DrvInfos::const_iterator i = drvs.begin();
|
||||||
i != drvs.end(); ++i)
|
i != drvs.end(); ++i)
|
||||||
{
|
{
|
||||||
ATerm t = makeAttrs(ATmakeList4(
|
Path drvPath = keepDerivations ? i->second.drvPath : "";
|
||||||
|
ATerm t = makeAttrs(ATmakeList5(
|
||||||
makeBind(toATerm("type"),
|
makeBind(toATerm("type"),
|
||||||
makeStr(toATerm("derivation")), makeNoPos()),
|
makeStr(toATerm("derivation")), makeNoPos()),
|
||||||
makeBind(toATerm("name"),
|
makeBind(toATerm("name"),
|
||||||
makeStr(toATerm(i->second.name)), makeNoPos()),
|
makeStr(toATerm(i->second.name)), makeNoPos()),
|
||||||
makeBind(toATerm("system"),
|
makeBind(toATerm("system"),
|
||||||
makeStr(toATerm(i->second.system)), makeNoPos()),
|
makeStr(toATerm(i->second.system)), makeNoPos()),
|
||||||
|
makeBind(toATerm("drvPath"),
|
||||||
|
makePath(toATerm(drvPath)), makeNoPos()),
|
||||||
makeBind(toATerm("outPath"),
|
makeBind(toATerm("outPath"),
|
||||||
makePath(toATerm(i->second.outPath)), makeNoPos())
|
makePath(toATerm(i->second.outPath)), makeNoPos())
|
||||||
));
|
));
|
||||||
manifest = ATinsert(manifest, t);
|
manifest = ATinsert(manifest, t);
|
||||||
inputs = ATinsert(inputs, makeStr(toATerm(i->second.outPath)));
|
inputs = ATinsert(inputs, makeStr(toATerm(i->second.outPath)));
|
||||||
references.insert(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
|
/* 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",
|
Path manifestFile = addTextToStore("env-manifest",
|
||||||
atPrint(makeList(ATreverse(manifest))), references);
|
atPrint(makeList(ATreverse(manifest))), references);
|
||||||
|
|
||||||
printMsg(lvlError, format("manifest is %1%") % manifestFile);
|
|
||||||
|
|
||||||
Expr topLevel = makeCall(envBuilder, makeAttrs(ATmakeList3(
|
Expr topLevel = makeCall(envBuilder, makeAttrs(ATmakeList3(
|
||||||
makeBind(toATerm("system"),
|
makeBind(toATerm("system"),
|
||||||
makeStr(toATerm(thisSystem)), makeNoPos()),
|
makeStr(toATerm(thisSystem)), makeNoPos()),
|
||||||
@ -281,15 +284,14 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void installDerivations(EvalState & state,
|
static void installDerivations(Globals & globals,
|
||||||
const InstallSourceInfo & instSource, DrvNames & selectors,
|
DrvNames & selectors, const Path & profile)
|
||||||
const Path & profile, bool dryRun, bool preserveInstalled)
|
|
||||||
{
|
{
|
||||||
debug(format("installing derivations"));
|
debug(format("installing derivations"));
|
||||||
|
|
||||||
/* Fetch all derivations from the input file. */
|
/* Fetch all derivations from the input file. */
|
||||||
DrvInfos availDrvs;
|
DrvInfos availDrvs;
|
||||||
queryInstSources(state, instSource, availDrvs);
|
queryInstSources(globals.state, globals.instSource, availDrvs);
|
||||||
|
|
||||||
/* Filter out the ones we're not interested in. */
|
/* Filter out the ones we're not interested in. */
|
||||||
DrvInfos selectedDrvs;
|
DrvInfos selectedDrvs;
|
||||||
@ -320,13 +322,13 @@ static void installDerivations(EvalState & state,
|
|||||||
|
|
||||||
/* Add in the already installed derivations. */
|
/* Add in the already installed derivations. */
|
||||||
DrvInfos installedDrvs;
|
DrvInfos installedDrvs;
|
||||||
queryInstalled(state, installedDrvs, profile);
|
queryInstalled(globals.state, installedDrvs, profile);
|
||||||
|
|
||||||
for (DrvInfos::iterator i = installedDrvs.begin();
|
for (DrvInfos::iterator i = installedDrvs.begin();
|
||||||
i != installedDrvs.end(); ++i)
|
i != installedDrvs.end(); ++i)
|
||||||
{
|
{
|
||||||
DrvName drvName(i->second.name);
|
DrvName drvName(i->second.name);
|
||||||
if (!preserveInstalled &&
|
if (!globals.preserveInstalled &&
|
||||||
selectedNames.find(drvName.name) != selectedNames.end())
|
selectedNames.find(drvName.name) != selectedNames.end())
|
||||||
printMsg(lvlInfo,
|
printMsg(lvlInfo,
|
||||||
format("uninstalling `%1%'") % i->second.name);
|
format("uninstalling `%1%'") % i->second.name);
|
||||||
@ -334,9 +336,10 @@ static void installDerivations(EvalState & state,
|
|||||||
selectedDrvs.insert(*i);
|
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);
|
DrvNames drvNames = drvNamesFromArgs(opArgs);
|
||||||
|
|
||||||
installDerivations(globals.state, globals.instSource,
|
installDerivations(globals, drvNames, globals.profile);
|
||||||
drvNames, globals.profile, globals.dryRun,
|
|
||||||
globals.preserveInstalled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef enum { utLt, utLeq, utAlways } UpgradeType;
|
typedef enum { utLt, utLeq, utAlways } UpgradeType;
|
||||||
|
|
||||||
|
|
||||||
static void upgradeDerivations(EvalState & state,
|
static void upgradeDerivations(Globals & globals,
|
||||||
const InstallSourceInfo & instSource, DrvNames & selectors, const Path & profile,
|
DrvNames & selectors, const Path & profile,
|
||||||
UpgradeType upgradeType, bool dryRun)
|
UpgradeType upgradeType)
|
||||||
{
|
{
|
||||||
debug(format("upgrading derivations"));
|
debug(format("upgrading derivations"));
|
||||||
|
|
||||||
@ -370,11 +371,11 @@ static void upgradeDerivations(EvalState & state,
|
|||||||
|
|
||||||
/* Load the currently installed derivations. */
|
/* Load the currently installed derivations. */
|
||||||
DrvInfos installedDrvs;
|
DrvInfos installedDrvs;
|
||||||
queryInstalled(state, installedDrvs, profile);
|
queryInstalled(globals.state, installedDrvs, profile);
|
||||||
|
|
||||||
/* Fetch all derivations from the input file. */
|
/* Fetch all derivations from the input file. */
|
||||||
DrvInfos availDrvs;
|
DrvInfos availDrvs;
|
||||||
// xxx loadDerivations(state, nePath, availDrvs, systemFilter);
|
queryInstSources(globals.state, globals.instSource, availDrvs);
|
||||||
|
|
||||||
/* Go through all installed derivations. */
|
/* Go through all installed derivations. */
|
||||||
DrvInfos newDrvs;
|
DrvInfos newDrvs;
|
||||||
@ -440,9 +441,10 @@ static void upgradeDerivations(EvalState & state,
|
|||||||
} else newDrvs.insert(*i);
|
} 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);
|
DrvNames drvNames = drvNamesFromArgs(opArgs);
|
||||||
|
|
||||||
upgradeDerivations(globals.state, globals.instSource,
|
upgradeDerivations(globals, drvNames, globals.profile, upgradeType);
|
||||||
drvNames, globals.profile, upgradeType, globals.dryRun);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void uninstallDerivations(EvalState & state, DrvNames & selectors,
|
static void uninstallDerivations(Globals & globals, DrvNames & selectors,
|
||||||
Path & profile, bool dryRun)
|
Path & profile)
|
||||||
{
|
{
|
||||||
DrvInfos installedDrvs;
|
DrvInfos installedDrvs;
|
||||||
queryInstalled(state, installedDrvs, profile);
|
queryInstalled(globals.state, installedDrvs, profile);
|
||||||
|
|
||||||
for (DrvInfos::iterator i = installedDrvs.begin();
|
for (DrvInfos::iterator i = installedDrvs.begin();
|
||||||
i != installedDrvs.end(); ++i)
|
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);
|
DrvNames drvNames = drvNamesFromArgs(opArgs);
|
||||||
|
|
||||||
uninstallDerivations(globals.state, drvNames,
|
uninstallDerivations(globals, drvNames,
|
||||||
globals.profile, globals.dryRun);
|
globals.profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -798,6 +800,7 @@ void run(Strings args)
|
|||||||
Operation op = 0;
|
Operation op = 0;
|
||||||
|
|
||||||
Globals globals;
|
Globals globals;
|
||||||
|
|
||||||
globals.instSource.type = srcUnknown;
|
globals.instSource.type = srcUnknown;
|
||||||
globals.instSource.nixExprPath = getDefNixExprPath();
|
globals.instSource.nixExprPath = getDefNixExprPath();
|
||||||
globals.instSource.systemFilter = thisSystem;
|
globals.instSource.systemFilter = thisSystem;
|
||||||
@ -805,6 +808,9 @@ void run(Strings args)
|
|||||||
globals.dryRun = false;
|
globals.dryRun = false;
|
||||||
globals.preserveInstalled = false;
|
globals.preserveInstalled = false;
|
||||||
|
|
||||||
|
globals.keepDerivations =
|
||||||
|
queryBoolSetting("env-keep-derivations", false);
|
||||||
|
|
||||||
for (Strings::iterator i = args.begin(); i != args.end(); ++i) {
|
for (Strings::iterator i = args.begin(); i != args.end(); ++i) {
|
||||||
string arg = *i;
|
string arg = *i;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user