diff options
Diffstat (limited to 'src/nix-collect-garbage/nix-collect-garbage.cc')
-rw-r--r-- | src/nix-collect-garbage/nix-collect-garbage.cc | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/nix-collect-garbage/nix-collect-garbage.cc b/src/nix-collect-garbage/nix-collect-garbage.cc new file mode 100644 index 000000000000..568a1fa7daa4 --- /dev/null +++ b/src/nix-collect-garbage/nix-collect-garbage.cc @@ -0,0 +1,87 @@ +#include "hash.hh" +#include "shared.hh" +#include "globals.hh" + +#include <iostream> + +using namespace nix; + +std::string gen = ""; +bool dryRun = false; + +void runProgramSimple(Path program, const Strings & args) +{ + checkInterrupt(); + + /* Fork. */ + Pid pid = startProcess([&]() { + Strings args_(args); + args_.push_front(program); + auto cargs = stringsToCharPtrs(args_); + + execv(program.c_str(), (char * *) &cargs[0]); + + throw SysError(format("executing ‘%1%’") % program); + }); + + pid.wait(true); +} + + +/* If `-d' was specified, remove all old generations of all profiles. + * Of course, this makes rollbacks to before this point in time + * impossible. */ + +void removeOldGenerations(std::string dir) +{ + for (auto & i : readDirectory(dir)) { + checkInterrupt(); + + auto path = dir + "/" + i.name; + auto type = getFileType(path); + + if (type == DT_LNK) { + auto link = readLink(path); + if (link.find("link") != string::npos) { + printMsg(lvlInfo, format("removing old generations of profile %1%") % path); + + runProgramSimple(settings.nixBinDir + "/nix-env", Strings{"-p", path, "--delete-generations", gen, dryRun ? "--dry-run" : ""}); + } + } else if (type == DT_DIR) { + removeOldGenerations(path); + } + } +} + +int main(int argc, char * * argv) +{ + bool removeOld = false; + Strings extraArgs; + + return handleExceptions(argv[0], [&]() { + initNix(); + + parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) { + if (*arg == "--help") + showManPage("nix-collect-garbage"); + else if (*arg == "--version") + printVersion("nix-collect-garbage"); + else if (*arg == "--delete-old" || *arg == "-d") removeOld = true; + else if (*arg == "--delete-older-than") { + removeOld = true; + gen = getArg(*arg, arg, end); + } + else if (*arg == "--dry-run") dryRun = true; + else + extraArgs.push_back(*arg); + return true; + }); + + auto profilesDir = settings.nixStateDir + "/profiles"; + if (removeOld) removeOldGenerations(profilesDir); + + // Run the actual garbage collector. + if (!dryRun) runProgramSimple(settings.nixBinDir + "/nix-store", Strings{"--gc"}); + }); +} + |