Skip to content

Commit

Permalink
Implement alternative to lazy generations:
Browse files Browse the repository at this point in the history
* only the last generation can be lazy
* depend on the '--lazy-generation' flag to be set
  • Loading branch information
ctheune committed May 19, 2015
1 parent 3d83188 commit ea39c98
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 21 deletions.
15 changes: 10 additions & 5 deletions src/nix-env/nix-env.cc
Expand Up @@ -58,6 +58,7 @@ struct Globals
bool removeAll;
string forceName;
bool prebuiltOnly;
bool lazyGeneration;
};


Expand Down Expand Up @@ -510,7 +511,7 @@ static void installDerivations(Globals & globals,
if (globals.dryRun) return;

if (createUserEnv(*globals.state, allElems,
profile, settings.envKeepDerivations, lockToken)) break;
profile, settings.envKeepDerivations, lockToken, globals.lazyGeneration)) break;
}
}

Expand All @@ -524,6 +525,8 @@ static void opInstall(Globals & globals, Strings opFlags, Strings opArgs)
globals.preserveInstalled = true;
else if (arg == "--remove-all" || arg == "-r")
globals.removeAll = true;
else if (arg == "--lazy-generation")
globals.lazyGeneration = true;
else throw UsageError(format("unknown flag ‘%1%’") % arg);
}

Expand Down Expand Up @@ -617,7 +620,7 @@ static void upgradeDerivations(Globals & globals,
if (globals.dryRun) return;

if (createUserEnv(*globals.state, newElems,
globals.profile, settings.envKeepDerivations, lockToken)) break;
globals.profile, settings.envKeepDerivations, lockToken, globals.lazyGeneration)) break;
}
}

Expand Down Expand Up @@ -681,7 +684,7 @@ static void opSetFlag(Globals & globals, Strings opFlags, Strings opArgs)

/* Write the new user environment. */
if (createUserEnv(*globals.state, installedElems,
globals.profile, settings.envKeepDerivations, lockToken)) break;
globals.profile, settings.envKeepDerivations, lockToken, globals.lazyGeneration)) break;
}
}

Expand Down Expand Up @@ -718,7 +721,8 @@ static void opSet(Globals & globals, Strings opFlags, Strings opArgs)
}

debug(format("switching to new user environment"));
Path generation = createGeneration(globals.profile, drv.queryOutPath());
Path generation = createGeneration(globals.profile, drv.queryOutPath(),
globals.lazyGeneration);
switchLink(globals.profile, generation);
}

Expand Down Expand Up @@ -751,7 +755,7 @@ static void uninstallDerivations(Globals & globals, Strings & selectors,
if (globals.dryRun) return;

if (createUserEnv(*globals.state, newElems,
profile, settings.envKeepDerivations, lockToken)) break;
profile, settings.envKeepDerivations, lockToken, globals.lazyGeneration)) break;
}
}

Expand Down Expand Up @@ -1355,6 +1359,7 @@ int main(int argc, char * * argv)
globals.preserveInstalled = false;
globals.removeAll = false;
globals.prebuiltOnly = false;
globals.lazyGeneration = false;

parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
Operation oldOp = op;
Expand Down
19 changes: 11 additions & 8 deletions src/nix-env/profiles.cc
Expand Up @@ -74,7 +74,7 @@ static void makeName(const Path & profile, unsigned int num,
}


Path createGeneration(Path profile, Path outPath)
Path createGeneration(Path profile, Path outPath, bool lazy)
{
/* The new generation number should be higher than old the
previous ones. */
Expand All @@ -83,13 +83,16 @@ Path createGeneration(Path profile, Path outPath)

unsigned int num;
if (gens.size() > 0) {
/* Check existing generations whether they represent an
environment we already materialized before. In that case:
avoid cluttering the system with additional symlinks. */
for (auto & gen : gens) {
if (readLink(gen.path) == outPath) {
return gen.path;
}
Generation last = gens.back();

if (lazy && readLink(last.path) == outPath) {
/* If lazy generations are enabled then we only create a
new generation symlink if it differs from the last one.
This helps keeping gratuitous installs/rebuilds from piling
up uncontrolled numbers of generations, cluttering up the
UI like grub. */
return last.path;
}

num = gens.back().number;
Expand Down
2 changes: 1 addition & 1 deletion src/nix-env/profiles.hh
Expand Up @@ -31,7 +31,7 @@ typedef list<Generation> Generations;
profile, sorted by generation number. */
Generations findGenerations(Path profile, int & curGen);

Path createGeneration(Path profile, Path outPath);
Path createGeneration(Path profile, Path outPath, bool lazy);

void deleteGeneration(const Path & profile, unsigned int gen);

Expand Down
4 changes: 2 additions & 2 deletions src/nix-env/user-env.cc
Expand Up @@ -28,7 +28,7 @@ DrvInfos queryInstalled(EvalState & state, const Path & userEnv)

bool createUserEnv(EvalState & state, DrvInfos & elems,
const Path & profile, bool keepDerivations,
const string & lockToken)
const string & lockToken, bool lazyGeneration)
{
/* Build the components in the user environment, if they don't
exist already. */
Expand Down Expand Up @@ -141,7 +141,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
}

debug(format("switching to new user environment"));
Path generation = createGeneration(profile, topLevelOut);
Path generation = createGeneration(profile, topLevelOut, lazyGeneration);
switchLink(profile, generation);

return true;
Expand Down
2 changes: 1 addition & 1 deletion src/nix-env/user-env.hh
Expand Up @@ -8,6 +8,6 @@ DrvInfos queryInstalled(EvalState & state, const Path & userEnv);

bool createUserEnv(EvalState & state, DrvInfos & elems,
const Path & profile, bool keepDerivations,
const string & lockToken);
const string & lockToken, bool lazyGeneration);

}
18 changes: 14 additions & 4 deletions tests/user-envs.sh
Expand Up @@ -99,14 +99,24 @@ if nix-env -q '*' | grep -q bar; then false; fi
nix-env --list-generations
test "$(nix-env --list-generations | wc -l)" -eq 7

# Doing the same operation twice should result in the same generation, not an
# additional one. At this point we just brought back foo. Installing it again
# should not create a new generation.
# Doing the same operation twice results in the same generation, but creates an
# additional one. At this point we just brought back foo.

nix-env -i foo

# Count generations.
nix-env --list-generations
test "$(nix-env --list-generations | wc -l)" -eq 7
test "$(nix-env --list-generations | wc -l)" -eq 8

# Now, doing that again but passing the --lazy-generations flag will not
# create a new generation.

nix-env -i foo --lazy-generation

# Count generations.
nix-env --list-generations
test "$(nix-env --list-generations | wc -l)" -eq 8


# Switch to a specified generation.
nix-env --switch-generation 7
Expand Down

0 comments on commit ea39c98

Please sign in to comment.