aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/profiles.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2021-09-14 19:05:28 +0200
committerEelco Dolstra <edolstra@gmail.com>2021-09-14 19:32:33 +0200
commit817562e6946fa44c253beb76a36d85b55fd9c14d (patch)
tree9259231b8a4eebd81344a8f323d8737ef2c7f0f9 /src/libstore/profiles.cc
parent1fbaf367292a8eb57a120f74daacabccce622f2f (diff)
Add "nix profile rollback" command
Diffstat (limited to 'src/libstore/profiles.cc')
-rw-r--r--src/libstore/profiles.cc31
1 files changed, 31 insertions, 0 deletions
diff --git a/src/libstore/profiles.cc b/src/libstore/profiles.cc
index 84a21c0ba..9959da535 100644
--- a/src/libstore/profiles.cc
+++ b/src/libstore/profiles.cc
@@ -236,6 +236,37 @@ void switchLink(Path link, Path target)
}
+void switchGeneration(
+ const Path & profile,
+ std::optional<GenerationNumber> dstGen,
+ bool dryRun)
+{
+ PathLocks lock;
+ lockProfile(lock, profile);
+
+ auto [gens, curGen] = findGenerations(profile);
+
+ std::optional<Generation> dst;
+ for (auto & i : gens)
+ if ((!dstGen && i.number < curGen) ||
+ (dstGen && i.number == *dstGen))
+ dst = i;
+
+ if (!dst) {
+ if (dstGen)
+ throw Error("generation %1% does not exist", *dstGen);
+ else
+ throw Error("no generation older than the current (%1%) exists", curGen.value_or(0));
+ }
+
+ notice("switching from generation %d to %d", curGen.value_or(0), dst->number);
+
+ if (dryRun) return;
+
+ switchLink(profile, dst->path);
+}
+
+
void lockProfile(PathLocks & lock, const Path & profile)
{
lock.lockPaths({profile}, (format("waiting for lock on profile '%1%'") % profile).str());