diff --git a/doc/manual/src/command-ref/nix-instantiate.md b/doc/manual/src/command-ref/nix-instantiate.md index 5b5ee0439..d09f5ed6a 100644 --- a/doc/manual/src/command-ref/nix-instantiate.md +++ b/doc/manual/src/command-ref/nix-instantiate.md @@ -12,7 +12,6 @@ Title: nix-instantiate [`--arg` *name* *value*] [{`--attr`| `-A`} *attrPath*] [`--add-root` *path*] - [`--indirect`] [`--expr` | `-E`] *files…* @@ -32,8 +31,8 @@ standard input. # Options - - `--add-root` *path*; `--indirect` - See the [corresponding options](nix-store.md) in `nix-store`. + - `--add-root` *path* + See the [corresponding option](nix-store.md) in `nix-store`. - `--parse` Just parse the input files, and print their abstract syntax trees on diff --git a/doc/manual/src/command-ref/nix-store.md b/doc/manual/src/command-ref/nix-store.md index 193d670c2..4680339e4 100644 --- a/doc/manual/src/command-ref/nix-store.md +++ b/doc/manual/src/command-ref/nix-store.md @@ -9,7 +9,6 @@ Title: nix-store `nix-store` *operation* [*options…*] [*arguments…*] [`--option` *name* *value*] [`--add-root` *path*] - [`--indirect`] # Description @@ -28,27 +27,12 @@ have an effect. - `--add-root` *path* Causes the result of a realisation (`--realise` and `--force-realise`) to be registered as a root of the garbage - collector. The root is stored in *path*, which must be inside a - directory that is scanned for roots by the garbage collector - (i.e., typically in a subdirectory of `/nix/var/nix/gcroots/`) - *unless* the `--indirect` flag is used. - - If there are multiple results, then multiple symlinks will be - created by sequentially numbering symlinks beyond the first one - (e.g., `foo`, `foo-2`, `foo-3`, and so on). - - - `--indirect` - In conjunction with `--add-root`, this option allows roots to be - stored *outside* of the GC roots directory. This is useful for - commands such as `nix-build` that place a symlink to the build - result in the current directory; such a build result should not be - garbage-collected unless the symlink is removed. - - The `--indirect` flag causes a uniquely named symlink to *path* to - be stored in `/nix/var/nix/gcroots/auto/`. For instance, + collector. *path* will be created as a symlink to the resulting + store path. In addition, a uniquely named symlink to *path* will + be created in `/nix/var/nix/gcroots/auto/`. For instance, ```console - $ nix-store --add-root /home/eelco/bla/result --indirect -r ... + $ nix-store --add-root /home/eelco/bla/result -r ... $ ls -l /nix/var/nix/gcroots/auto lrwxrwxrwx 1 ... 2005-03-13 21:10 dn54lcypm8f8... -> /home/eelco/bla/result @@ -63,11 +47,13 @@ have an effect. > **Warning** > - > Note that it is not possible to move or rename indirect GC roots, - > since the symlink in the `auto` directory will still point to the - > old location. + > Note that it is not possible to move or rename GC roots, since + > the symlink in the `auto` directory will still point to the old + > location. - + If there are multiple results, then multiple symlinks will be + created by sequentially numbering symlinks beyond the first one + (e.g., `foo`, `foo-2`, `foo-3`, and so on). # Operation `--realise` diff --git a/src/libexpr/eval-cache.cc b/src/libexpr/eval-cache.cc index 46177a0a4..381344b40 100644 --- a/src/libexpr/eval-cache.cc +++ b/src/libexpr/eval-cache.cc @@ -391,7 +391,8 @@ Value & AttrCursor::forceValue() if (root->db && (!cachedValue || std::get_if(&cachedValue->second))) { if (v.type == tString) - cachedValue = {root->db->setString(getKey(), v.string.s, v.string.context), v.string.s}; + cachedValue = {root->db->setString(getKey(), v.string.s, v.string.context), + string_t{v.string.s, {}}}; else if (v.type == tPath) cachedValue = {root->db->setString(getKey(), v.path), v.path}; else if (v.type == tBool) diff --git a/src/libfetchers/registry.cc b/src/libfetchers/registry.cc index d4134ce29..4367ee810 100644 --- a/src/libfetchers/registry.cc +++ b/src/libfetchers/registry.cc @@ -147,7 +147,7 @@ static std::shared_ptr getGlobalRegistry(ref store) if (!hasPrefix(path, "/")) { auto storePath = downloadFile(store, path, "flake-registry.json", false).storePath; if (auto store2 = store.dynamic_pointer_cast()) - store2->addPermRoot(storePath, getCacheDir() + "/nix/flake-registry.json", true); + store2->addPermRoot(storePath, getCacheDir() + "/nix/flake-registry.json"); path = store->toRealPath(storePath); } diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index e74382ed2..e6cbc525d 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -85,8 +85,7 @@ void LocalStore::addIndirectRoot(const Path & path) } -Path LocalFSStore::addPermRoot(const StorePath & storePath, - const Path & _gcRoot, bool indirect, bool allowOutsideRootsDir) +Path LocalFSStore::addPermRoot(const StorePath & storePath, const Path & _gcRoot) { Path gcRoot(canonPath(_gcRoot)); @@ -95,47 +94,12 @@ Path LocalFSStore::addPermRoot(const StorePath & storePath, "creating a garbage collector root (%1%) in the Nix store is forbidden " "(are you running nix-build inside the store?)", gcRoot); - if (indirect) { - /* Don't clobber the link if it already exists and doesn't - point to the Nix store. */ - if (pathExists(gcRoot) && (!isLink(gcRoot) || !isInStore(readLink(gcRoot)))) - throw Error("cannot create symlink '%1%'; already exists", gcRoot); - makeSymlink(gcRoot, printStorePath(storePath)); - addIndirectRoot(gcRoot); - } - - else { - if (!allowOutsideRootsDir) { - Path rootsDir = canonPath((format("%1%/%2%") % stateDir % gcRootsDir).str()); - - if (string(gcRoot, 0, rootsDir.size() + 1) != rootsDir + "/") - throw Error( - "path '%1%' is not a valid garbage collector root; " - "it's not in the directory '%2%'", - gcRoot, rootsDir); - } - - if (baseNameOf(gcRoot) == std::string(storePath.to_string())) - writeFile(gcRoot, ""); - else - makeSymlink(gcRoot, printStorePath(storePath)); - } - - /* Check that the root can be found by the garbage collector. - !!! This can be very slow on machines that have many roots. - Instead of reading all the roots, it would be more efficient to - check if the root is in a directory in or linked from the - gcroots directory. */ - if (settings.checkRootReachability) { - auto roots = findRoots(false); - if (roots[storePath].count(gcRoot) == 0) - logWarning({ - .name = "GC root", - .hint = hintfmt("warning: '%1%' is not in a directory where the garbage collector looks for roots; " - "therefore, '%2%' might be removed by the garbage collector", - gcRoot, printStorePath(storePath)) - }); - } + /* Don't clobber the link if it already exists and doesn't + point to the Nix store. */ + if (pathExists(gcRoot) && (!isLink(gcRoot) || !isInStore(readLink(gcRoot)))) + throw Error("cannot create symlink '%1%'; already exists", gcRoot); + makeSymlink(gcRoot, printStorePath(storePath)); + addIndirectRoot(gcRoot); /* Grab the global GC root, causing us to block while a GC is in progress. This prevents the set of permanent roots from diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index ab9f42ce6..8a2d3ff75 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -293,10 +293,6 @@ public: Setting pollInterval{this, 5, "build-poll-interval", "How often (in seconds) to poll for locks."}; - Setting checkRootReachability{this, false, "gc-check-reachability", - "Whether to check if new GC roots can in fact be found by the " - "garbage collector."}; - Setting gcKeepOutputs{ this, false, "keep-outputs", R"( diff --git a/src/libstore/http-binary-cache-store.cc b/src/libstore/http-binary-cache-store.cc index c1ceb08cf..1733239fb 100644 --- a/src/libstore/http-binary-cache-store.cc +++ b/src/libstore/http-binary-cache-store.cc @@ -85,7 +85,7 @@ protected: checkEnabled(); try { - FileTransferRequest request(cacheUri + "/" + path); + FileTransferRequest request(makeRequest(path)); request.head = true; getFileTransfer()->download(request); return true; @@ -103,7 +103,7 @@ protected: std::shared_ptr> istream, const std::string & mimeType) override { - auto req = FileTransferRequest(cacheUri + "/" + path); + auto req = makeRequest(path); req.data = std::make_shared(StreamToSourceAdapter(istream).drain()); req.mimeType = mimeType; try { @@ -115,8 +115,11 @@ protected: FileTransferRequest makeRequest(const std::string & path) { - FileTransferRequest request(cacheUri + "/" + path); - return request; + return FileTransferRequest( + hasPrefix(path, "https://") || hasPrefix(path, "http://") || hasPrefix(path, "file://") + ? path + : cacheUri + "/" + path); + } void getFile(const std::string & path, Sink & sink) override diff --git a/src/libstore/profiles.cc b/src/libstore/profiles.cc index 6862b42f0..c20386e2b 100644 --- a/src/libstore/profiles.cc +++ b/src/libstore/profiles.cc @@ -72,7 +72,7 @@ static void makeName(const Path & profile, GenerationNumber num, } -Path createGeneration(ref store, Path profile, Path outPath) +Path createGeneration(ref store, Path profile, StorePath outPath) { /* The new generation number should be higher than old the previous ones. */ @@ -82,7 +82,7 @@ Path createGeneration(ref store, Path profile, Path outPath) if (gens.size() > 0) { Generation last = gens.back(); - if (readLink(last.path) == outPath) { + if (readLink(last.path) == store->printStorePath(outPath)) { /* We only create a new generation symlink if it differs from the last one. @@ -105,7 +105,7 @@ Path createGeneration(ref store, Path profile, Path outPath) user environment etc. we've just built. */ Path generation; makeName(profile, num + 1, generation); - store->addPermRoot(store->parseStorePath(outPath), generation, false, true); + store->addPermRoot(outPath, generation); return generation; } diff --git a/src/libstore/profiles.hh b/src/libstore/profiles.hh index abe507f0e..be55a65d4 100644 --- a/src/libstore/profiles.hh +++ b/src/libstore/profiles.hh @@ -8,6 +8,8 @@ namespace nix { +class StorePath; + typedef unsigned int GenerationNumber; @@ -28,7 +30,7 @@ std::pair> findGenerations(Path pro class LocalFSStore; -Path createGeneration(ref store, Path profile, Path outPath); +Path createGeneration(ref store, Path profile, StorePath outPath); void deleteGeneration(const Path & profile, GenerationNumber gen); diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 6583413a6..8b42aa6d2 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -651,8 +651,7 @@ public: ref getFSAccessor() override; /* Register a permanent GC root. */ - Path addPermRoot(const StorePath & storePath, - const Path & gcRoot, bool indirect, bool allowOutsideRootsDir = false); + Path addPermRoot(const StorePath & storePath, const Path & gcRoot); virtual Path getRealStoreDir() { return storeDir; } diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index ea4b407e7..e6fd7a4e6 100755 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -526,7 +526,7 @@ static void _main(int argc, char * * argv) if (auto store2 = store.dynamic_pointer_cast()) { std::string symlink = drvPrefix; if (outputName != "out") symlink += "-" + outputName; - store2->addPermRoot(outputPath, absPath(symlink), true); + store2->addPermRoot(outputPath, absPath(symlink)); } outPaths.push_back(outputPath); diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index ddd036070..e5a433ac0 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -708,7 +708,9 @@ static void opSet(Globals & globals, Strings opFlags, Strings opArgs) } debug(format("switching to new user environment")); - Path generation = createGeneration(ref(store2), globals.profile, drv.queryOutPath()); + Path generation = createGeneration( + ref(store2), globals.profile, + store2->parseStorePath(drv.queryOutPath())); switchLink(globals.profile, generation); } diff --git a/src/nix-env/user-env.cc b/src/nix-env/user-env.cc index 8e7f09e12..8c6c8af05 100644 --- a/src/nix-env/user-env.cc +++ b/src/nix-env/user-env.cc @@ -151,7 +151,8 @@ bool createUserEnv(EvalState & state, DrvInfos & elems, } debug(format("switching to new user environment")); - Path generation = createGeneration(ref(store2), profile, topLevelOut); + Path generation = createGeneration(ref(store2), profile, + store2->parseStorePath(topLevelOut)); switchLink(profile, generation); } diff --git a/src/nix-instantiate/nix-instantiate.cc b/src/nix-instantiate/nix-instantiate.cc index bf353677a..539092cbe 100644 --- a/src/nix-instantiate/nix-instantiate.cc +++ b/src/nix-instantiate/nix-instantiate.cc @@ -20,7 +20,6 @@ using namespace nix; static Path gcRoot; static int rootNr = 0; -static bool indirectRoot = false; enum OutputKind { okPlain, okXML, okJSON }; @@ -71,11 +70,11 @@ void processExpr(EvalState & state, const Strings & attrPaths, if (gcRoot == "") printGCWarning(); else { - Path rootName = indirectRoot ? absPath(gcRoot) : gcRoot; + Path rootName = absPath(gcRoot); if (++rootNr > 1) rootName += "-" + std::to_string(rootNr); auto store2 = state.store.dynamic_pointer_cast(); if (store2) - drvPath = store2->addPermRoot(store2->parseStorePath(drvPath), rootName, indirectRoot); + drvPath = store2->addPermRoot(store2->parseStorePath(drvPath), rootName); } std::cout << fmt("%s%s\n", drvPath, (outputName != "out" ? "!" + outputName : "")); } @@ -127,7 +126,7 @@ static int _main(int argc, char * * argv) else if (*arg == "--add-root") gcRoot = getArg(*arg, arg, end); else if (*arg == "--indirect") - indirectRoot = true; + ; else if (*arg == "--xml") outputKind = okXML; else if (*arg == "--json") diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index ce5de2ae5..b027e84b7 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -34,7 +34,6 @@ typedef void (* Operation) (Strings opFlags, Strings opArgs); static Path gcRoot; static int rootNr = 0; -static bool indirectRoot = false; static bool noOutput = false; static std::shared_ptr store; @@ -87,7 +86,7 @@ static PathSet realisePath(StorePathWithOutputs path, bool build = true) Path rootName = gcRoot; if (rootNr > 1) rootName += "-" + std::to_string(rootNr); if (i->first != "out") rootName += "-" + i->first; - retPath = store2->addPermRoot(outPath, rootName, indirectRoot); + retPath = store2->addPermRoot(outPath, rootName); } } outputs.insert(retPath); @@ -106,7 +105,7 @@ static PathSet realisePath(StorePathWithOutputs path, bool build = true) Path rootName = gcRoot; rootNr++; if (rootNr > 1) rootName += "-" + std::to_string(rootNr); - return {store2->addPermRoot(path.path, rootName, indirectRoot)}; + return {store2->addPermRoot(path.path, rootName)}; } } return {store->printStorePath(path.path)}; @@ -1090,7 +1089,7 @@ static int _main(int argc, char * * argv) else if (*arg == "--add-root") gcRoot = absPath(getArg(*arg, arg, end)); else if (*arg == "--indirect") - indirectRoot = true; + ; else if (*arg == "--no-output") noOutput = true; else if (*arg != "" && arg->at(0) == '-') { diff --git a/src/nix/build.cc b/src/nix/build.cc index cb12ee933..4605eb13e 100644 --- a/src/nix/build.cc +++ b/src/nix/build.cc @@ -71,7 +71,7 @@ struct CmdBuild : InstallablesCommand, MixDryRun, MixProfile [&](BuildableOpaque bo) { std::string symlink = outLink; if (i) symlink += fmt("-%d", i); - store2->addPermRoot(bo.path, absPath(symlink), true); + store2->addPermRoot(bo.path, absPath(symlink)); }, [&](BuildableFromDrv bfd) { auto builtOutputs = store->queryDerivationOutputMap(bfd.drvPath); @@ -79,7 +79,7 @@ struct CmdBuild : InstallablesCommand, MixDryRun, MixProfile std::string symlink = outLink; if (i) symlink += fmt("-%d", i); if (output.first != "out") symlink += fmt("-%s", output.first); - store2->addPermRoot(output.second, absPath(symlink), true); + store2->addPermRoot(output.second, absPath(symlink)); } }, }, buildables[i]); diff --git a/src/nix/bundle.cc b/src/nix/bundle.cc index eb3339f5d..241c8699b 100644 --- a/src/nix/bundle.cc +++ b/src/nix/bundle.cc @@ -122,7 +122,7 @@ struct CmdBundle : InstallableCommand if (!outLink) outLink = baseNameOf(app.program); - store.dynamic_pointer_cast()->addPermRoot(outPath, absPath(*outLink), true); + store.dynamic_pointer_cast()->addPermRoot(outPath, absPath(*outLink)); } }; diff --git a/src/nix/command.cc b/src/nix/command.cc index fefd72f45..f697eb84c 100644 --- a/src/nix/command.cc +++ b/src/nix/command.cc @@ -134,7 +134,7 @@ void MixProfile::updateProfile(const StorePath & storePath) switchLink(profile2, createGeneration( ref(store), - profile2, store->printStorePath(storePath))); + profile2, storePath)); } void MixProfile::updateProfile(const Buildables & buildables) diff --git a/tests/nix-build.sh b/tests/nix-build.sh index 0eb599608..3123c6da3 100644 --- a/tests/nix-build.sh +++ b/tests/nix-build.sh @@ -24,5 +24,5 @@ outPath2=$(nix-build $(nix-instantiate dependencies.nix) --no-out-link) outPath2=$(nix-build $(nix-instantiate dependencies.nix)!out --no-out-link) [[ $outPath = $outPath2 ]] -outPath2=$(nix-store -r $(nix-instantiate --indirect --add-root $TEST_ROOT/indirect dependencies.nix)!out) +outPath2=$(nix-store -r $(nix-instantiate --add-root $TEST_ROOT/indirect dependencies.nix)!out) [[ $outPath = $outPath2 ]] diff --git a/tests/nix-shell.sh b/tests/nix-shell.sh index 650904057..1228bb04f 100644 --- a/tests/nix-shell.sh +++ b/tests/nix-shell.sh @@ -27,12 +27,12 @@ output=$(nix-shell --pure --keep SELECTED_IMPURE_VAR shell.nix -A shellDrv --run # Test nix-shell on a .drv symlink # Legacy: absolute path and .drv extension required -nix-instantiate shell.nix -A shellDrv --indirect --add-root $TEST_ROOT/shell.drv +nix-instantiate shell.nix -A shellDrv --add-root $TEST_ROOT/shell.drv [[ $(nix-shell --pure $TEST_ROOT/shell.drv --run \ 'echo "$IMPURE_VAR - $VAR_FROM_STDENV_SETUP - $VAR_FROM_NIX"') = " - foo - bar" ]] # New behaviour: just needs to resolve to a derivation in the store -nix-instantiate shell.nix -A shellDrv --indirect --add-root $TEST_ROOT/shell +nix-instantiate shell.nix -A shellDrv --add-root $TEST_ROOT/shell [[ $(nix-shell --pure $TEST_ROOT/shell --run \ 'echo "$IMPURE_VAR - $VAR_FROM_STDENV_SETUP - $VAR_FROM_NIX"') = " - foo - bar" ]]