about summary refs log tree commit diff
path: root/src/libstore
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2015-05-21T14·26+0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2015-05-21T14·28+0200
commit4ca5a9dcfd577487f8a5b192e8ec525c5baad8cb (patch)
treed3686237252fae1cf7e719a4f4116cabfd467a18 /src/libstore
parent22b1a8d43f0dea4f85bce2e79b1b986ecd8ba7f6 (diff)
nix-collect-garbage: Don't call nix-env
Also, make sure --delete-older-than doesn't delete the current
generation.
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/profiles.cc82
-rw-r--r--src/libstore/profiles.hh10
2 files changed, 91 insertions, 1 deletions
diff --git a/src/libstore/profiles.cc b/src/libstore/profiles.cc
index 5b7a533df290..da3f7da9d19d 100644
--- a/src/libstore/profiles.cc
+++ b/src/libstore/profiles.cc
@@ -129,6 +129,88 @@ void deleteGeneration(const Path & profile, unsigned int gen)
 }
 
 
+static void deleteGeneration2(const Path & profile, unsigned int gen, bool dryRun)
+{
+    if (dryRun)
+        printMsg(lvlInfo, format("would remove generation %1%") % gen);
+    else {
+        printMsg(lvlInfo, format("removing generation %1%") % gen);
+        deleteGeneration(profile, gen);
+    }
+}
+
+
+void deleteGenerations(const Path & profile, const std::set<unsigned int> & gensToDelete, bool dryRun)
+{
+    PathLocks lock;
+    lockProfile(lock, profile);
+
+    int curGen;
+    Generations gens = findGenerations(profile, curGen);
+
+    if (gensToDelete.find(curGen) != gensToDelete.end())
+        throw Error(format("cannot delete current generation of profile %1%’") % profile);
+
+    for (auto & i : gens) {
+        if (gensToDelete.find(i.number) == gensToDelete.end()) continue;
+        deleteGeneration2(profile, i.number, dryRun);
+    }
+}
+
+
+void deleteOldGenerations(const Path & profile, bool dryRun)
+{
+    PathLocks lock;
+    lockProfile(lock, profile);
+
+    int curGen;
+    Generations gens = findGenerations(profile, curGen);
+
+    for (auto & i : gens)
+        if (i.number != curGen)
+            deleteGeneration2(profile, i.number, dryRun);
+}
+
+
+void deleteGenerationsOlderThan(const Path & profile, time_t t, bool dryRun)
+{
+    PathLocks lock;
+    lockProfile(lock, profile);
+
+    int curGen;
+    Generations gens = findGenerations(profile, curGen);
+
+    bool canDelete = false;
+    for (auto i = gens.rbegin(); i != gens.rend(); ++i)
+        if (canDelete) {
+            assert(i->creationTime < t);
+            if (i->number != curGen)
+                deleteGeneration2(profile, i->number, dryRun);
+        } else if (i->creationTime < t) {
+            /* We may now start deleting generations, but we don't
+               delete this generation yet, because this generation was
+               still the one that was active at the requested point in
+               time. */
+            canDelete = true;
+        }
+}
+
+
+void deleteGenerationsOlderThan(const Path & profile, const string & timeSpec, bool dryRun)
+{
+    time_t curTime = time(0);
+    string strDays = string(timeSpec, 0, timeSpec.size() - 1);
+    int days;
+
+    if (!string2Int(strDays, days) || days < 1)
+        throw Error(format("invalid number of days specifier ‘%1%’") % timeSpec);
+
+    time_t oldTime = curTime - days * 24 * 3600;
+
+    deleteGenerationsOlderThan(profile, oldTime, dryRun);
+}
+
+
 void switchLink(Path link, Path target)
 {
     /* Hacky. */
diff --git a/src/libstore/profiles.hh b/src/libstore/profiles.hh
index 30d2376d998c..e99bbf398a86 100644
--- a/src/libstore/profiles.hh
+++ b/src/libstore/profiles.hh
@@ -30,11 +30,19 @@ typedef list<Generation> Generations;
 /* Returns the list of currently present generations for the specified
    profile, sorted by generation number. */
 Generations findGenerations(Path profile, int & curGen);
-    
+
 Path createGeneration(Path profile, Path outPath);
 
 void deleteGeneration(const Path & profile, unsigned int gen);
 
+void deleteGenerations(const Path & profile, const std::set<unsigned int> & gensToDelete, bool dryRun);
+
+void deleteOldGenerations(const Path & profile, bool dryRun);
+
+void deleteGenerationsOlderThan(const Path & profile, time_t t, bool dryRun);
+
+void deleteGenerationsOlderThan(const Path & profile, const string & timeSpec, bool dryRun);
+
 void switchLink(Path link, Path target);
 
 /* Ensure exclusive access to a profile.  Any command that modifies