From 8d6d59cb1ba0a2cfe12f9f444a27833dc531c191 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 21 Mar 2023 12:58:14 +0100 Subject: [PATCH 01/18] nix store --help: Include store type documentation --- doc/manual/generate-manpage.nix | 23 +++++++++++--- doc/manual/generate-options.nix | 41 ------------------------- doc/manual/local.mk | 10 +++--- doc/manual/utils.nix | 37 ++++++++++++++++++++++ src/libstore/http-binary-cache-store.cc | 2 +- src/nix/describe-stores.cc | 2 +- src/nix/main.cc | 31 ++++++++++++++----- src/nix/store.cc | 7 +++++ src/nix/store.md | 9 ++++++ 9 files changed, 102 insertions(+), 60 deletions(-) delete mode 100644 doc/manual/generate-options.nix create mode 100644 src/nix/store.md diff --git a/doc/manual/generate-manpage.nix b/doc/manual/generate-manpage.nix index bc19d0303..7bb7a0caa 100644 --- a/doc/manual/generate-manpage.nix +++ b/doc/manual/generate-manpage.nix @@ -1,4 +1,4 @@ -{ toplevel }: +cliDumpStr: with builtins; with import ./utils.nix; @@ -63,7 +63,10 @@ let * [`${command} ${name}`](./${appendName filename name}.md) - ${subcmd.description} ''; - maybeDocumentation = if details ? doc then details.doc else ""; + maybeDocumentation = + if details ? doc + then replaceStrings ["@stores@"] [storeDocs] details.doc + else ""; maybeOptions = if details.flags == {} then "" else '' # Options @@ -110,13 +113,13 @@ let }; in [ cmd ] ++ concatMap subcommand (attrNames details.commands or {}); - parsedToplevel = builtins.fromJSON toplevel; + cliDump = builtins.fromJSON cliDumpStr; manpages = processCommand { command = "nix"; - details = parsedToplevel; + details = cliDump.args; filename = "nix"; - toplevel = parsedToplevel; + toplevel = cliDump.args; }; tableOfContents = let @@ -124,4 +127,14 @@ let " - [${page.command}](command-ref/new-cli/${page.name})"; in concatStringsSep "\n" (map showEntry manpages) + "\n"; + storeDocs = + let + showStore = name: { settings }: + '' + ## ${name} + + ${showSettings false settings} + ''; + in concatStrings (attrValues (mapAttrs showStore cliDump.stores)); + in (listToAttrs manpages) // { "SUMMARY.md" = tableOfContents; } diff --git a/doc/manual/generate-options.nix b/doc/manual/generate-options.nix deleted file mode 100644 index a4ec36477..000000000 --- a/doc/manual/generate-options.nix +++ /dev/null @@ -1,41 +0,0 @@ -let - inherit (builtins) attrNames concatStringsSep isAttrs isBool; - inherit (import ./utils.nix) concatStrings squash splitLines; -in - -optionsInfo: -let - showOption = name: - let - inherit (optionsInfo.${name}) description documentDefault defaultValue aliases; - result = squash '' - - [`${name}`](#conf-${name}) - - ${indent " " body} - ''; - # separate body to cleanly handle indentation - body = '' - ${description} - - **Default:** ${showDefault documentDefault defaultValue} - - ${showAliases aliases} - ''; - showDefault = documentDefault: defaultValue: - if documentDefault then - # a StringMap value type is specified as a string, but - # this shows the value type. The empty stringmap is `null` in - # JSON, but that converts to `{ }` here. - if defaultValue == "" || defaultValue == [] || isAttrs defaultValue - then "*empty*" - else if isBool defaultValue then - if defaultValue then "`true`" else "`false`" - else "`${toString defaultValue}`" - else "*machine-specific*"; - showAliases = aliases: - if aliases == [] then "" else - "**Deprecated alias:** ${(concatStringsSep ", " (map (s: "`${s}`") aliases))}"; - indent = prefix: s: - concatStringsSep "\n" (map (x: if x == "" then x else "${prefix}${x}") (splitLines s)); - in result; -in concatStrings (map showOption (attrNames optionsInfo)) diff --git a/doc/manual/local.mk b/doc/manual/local.mk index 531168e3f..8bf89b408 100644 --- a/doc/manual/local.mk +++ b/doc/manual/local.mk @@ -60,17 +60,17 @@ $(d)/src/SUMMARY.md: $(d)/src/SUMMARY.md.in $(d)/src/command-ref/new-cli @$(call process-includes,$@,$@) $(d)/src/command-ref/new-cli: $(d)/nix.json $(d)/generate-manpage.nix $(bindir)/nix - @rm -rf $@ - $(trace-gen) $(nix-eval) --write-to $@.tmp --expr 'import doc/manual/generate-manpage.nix { toplevel = builtins.readFile $<; }' + @rm -rf $@ $@.tmp + $(trace-gen) $(nix-eval) --write-to $@.tmp --expr 'import doc/manual/generate-manpage.nix (builtins.readFile $<)' @mv $@.tmp $@ -$(d)/src/command-ref/conf-file.md: $(d)/conf-file.json $(d)/generate-options.nix $(d)/src/command-ref/conf-file-prefix.md $(bindir)/nix +$(d)/src/command-ref/conf-file.md: $(d)/conf-file.json $(d)/utils.nix $(d)/src/command-ref/conf-file-prefix.md $(bindir)/nix @cat doc/manual/src/command-ref/conf-file-prefix.md > $@.tmp - $(trace-gen) $(nix-eval) --expr 'import doc/manual/generate-options.nix (builtins.fromJSON (builtins.readFile $<))' >> $@.tmp; + $(trace-gen) $(nix-eval) --expr '(import doc/manual/utils.nix).showSettings true (builtins.fromJSON (builtins.readFile $<))' >> $@.tmp; @mv $@.tmp $@ $(d)/nix.json: $(bindir)/nix - $(trace-gen) $(dummy-env) $(bindir)/nix __dump-args > $@.tmp + $(trace-gen) $(dummy-env) $(bindir)/nix __dump-cli > $@.tmp @mv $@.tmp $@ $(d)/conf-file.json: $(bindir)/nix diff --git a/doc/manual/utils.nix b/doc/manual/utils.nix index d0643ef46..ce0c21c98 100644 --- a/doc/manual/utils.nix +++ b/doc/manual/utils.nix @@ -38,4 +38,41 @@ rec { filterAttrs = pred: set: listToAttrs (concatMap (name: let v = set.${name}; in if pred name v then [(nameValuePair name v)] else []) (attrNames set)); + + showSetting = useSpans: name: { description, documentDefault, defaultValue, aliases, ... }: + let + result = squash '' + - ${if useSpans + then ''[`${name}`](#conf-${name})'' + else ''[`${name}`](#conf-${name})''} + + ${indent " " body} + ''; + # separate body to cleanly handle indentation + body = '' + ${description} + + **Default:** ${showDefault documentDefault defaultValue} + + ${showAliases aliases} + ''; + showDefault = documentDefault: defaultValue: + if documentDefault then + # a StringMap value type is specified as a string, but + # this shows the value type. The empty stringmap is `null` in + # JSON, but that converts to `{ }` here. + if defaultValue == "" || defaultValue == [] || isAttrs defaultValue + then "*empty*" + else if isBool defaultValue then + if defaultValue then "`true`" else "`false`" + else "`${toString defaultValue}`" + else "*machine-specific*"; + showAliases = aliases: + if aliases == [] then "" else + "**Deprecated alias:** ${(concatStringsSep ", " (map (s: "`${s}`") aliases))}"; + indent = prefix: s: + concatStringsSep "\n" (map (x: if x == "" then x else "${prefix}${x}") (splitLines s)); + in result; + + showSettings = useSpans: settingsInfo: concatStrings (attrValues (mapAttrs (showSetting useSpans) settingsInfo)); } diff --git a/src/libstore/http-binary-cache-store.cc b/src/libstore/http-binary-cache-store.cc index 1479822a9..93f25363a 100644 --- a/src/libstore/http-binary-cache-store.cc +++ b/src/libstore/http-binary-cache-store.cc @@ -12,7 +12,7 @@ struct HttpBinaryCacheStoreConfig : virtual BinaryCacheStoreConfig { using BinaryCacheStoreConfig::BinaryCacheStoreConfig; - const std::string name() override { return "Http Binary Cache Store"; } + const std::string name() override { return "HTTP Binary Cache Store"; } }; class HttpBinaryCacheStore : public virtual HttpBinaryCacheStoreConfig, public virtual BinaryCacheStore diff --git a/src/nix/describe-stores.cc b/src/nix/describe-stores.cc index eafcedd1f..ad6b2f0f8 100644 --- a/src/nix/describe-stores.cc +++ b/src/nix/describe-stores.cc @@ -22,7 +22,7 @@ struct CmdDescribeStores : Command, MixJSON for (auto & implem : *Implementations::registered) { auto storeConfig = implem.getConfig(); auto storeName = storeConfig->name(); - res[storeName] = storeConfig->toJSON(); + res[storeName]["settings"] = storeConfig->toJSON(); } if (json) { logger->cout("%s", res); diff --git a/src/nix/main.cc b/src/nix/main.cc index 7b715f281..0ea6d7784 100644 --- a/src/nix/main.cc +++ b/src/nix/main.cc @@ -164,11 +164,28 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs { commands = RegisterCommand::getCommandsFor({}); } + + std::string dumpCli() + { + auto res = nlohmann::json::object(); + + res["args"] = toJSON(); + + auto stores = nlohmann::json::object(); + for (auto & implem : *Implementations::registered) { + auto storeConfig = implem.getConfig(); + auto storeName = storeConfig->name(); + stores[storeName]["settings"] = storeConfig->toJSON(); + } + res["stores"] = std::move(stores); + + return res.dump(); + } }; /* Render the help for the specified subcommand to stdout using lowdown. */ -static void showHelp(std::vector subcommand, MultiCommand & toplevel) +static void showHelp(std::vector subcommand, NixArgs & toplevel) { auto mdName = subcommand.empty() ? "nix" : fmt("nix3-%s", concatStringsSep("-", subcommand)); @@ -189,11 +206,11 @@ static void showHelp(std::vector subcommand, MultiCommand & topleve , "/"), *vUtils); - auto attrs = state.buildBindings(16); - attrs.alloc("toplevel").mkString(toplevel.toJSON().dump()); + auto vDump = state.allocValue(); + vDump->mkString(toplevel.dumpCli()); auto vRes = state.allocValue(); - state.callFunction(*vGenerateManpage, state.allocValue()->mkAttrs(attrs), *vRes, noPos); + state.callFunction(*vGenerateManpage, *vDump, *vRes, noPos); auto attr = vRes->attrs->get(state.symbols.create(mdName + ".md")); if (!attr) @@ -234,7 +251,7 @@ struct CmdHelp : Command assert(parent); MultiCommand * toplevel = parent; while (toplevel->parent) toplevel = toplevel->parent; - showHelp(subcommand, *toplevel); + showHelp(subcommand, dynamic_cast(*toplevel)); } }; @@ -291,8 +308,8 @@ void mainWrapped(int argc, char * * argv) NixArgs args; - if (argc == 2 && std::string(argv[1]) == "__dump-args") { - logger->cout("%s", args.toJSON()); + if (argc == 2 && std::string(argv[1]) == "__dump-cli") { + logger->cout(args.dumpCli()); return; } diff --git a/src/nix/store.cc b/src/nix/store.cc index 2879e03b3..72b037488 100644 --- a/src/nix/store.cc +++ b/src/nix/store.cc @@ -12,6 +12,13 @@ struct CmdStore : virtual NixMultiCommand return "manipulate a Nix store"; } + std::string doc() override + { + return + #include "store.md" + ; + } + Category category() override { return catUtility; } void run() override diff --git a/src/nix/store.md b/src/nix/store.md new file mode 100644 index 000000000..d80a3b1be --- /dev/null +++ b/src/nix/store.md @@ -0,0 +1,9 @@ +R"( + +# Store types + +Nix supports different types of stores. These are listed below. + +@stores@ + +)" From 7704118d2816c2f7939db6771cd4665d5a68596d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 21 Mar 2023 12:59:37 +0100 Subject: [PATCH 02/18] nix describe-stores: Remove This command was intended for docs generation, but it was never used for that and we don't need it. --- doc/manual/src/release-notes/rl-next.md | 4 ++- src/nix/describe-stores.cc | 44 ------------------------- tests/describe-stores.sh | 8 ----- tests/local.mk | 1 - 4 files changed, 3 insertions(+), 54 deletions(-) delete mode 100644 src/nix/describe-stores.cc delete mode 100644 tests/describe-stores.sh diff --git a/doc/manual/src/release-notes/rl-next.md b/doc/manual/src/release-notes/rl-next.md index b8d14e605..3e6bfe3e0 100644 --- a/doc/manual/src/release-notes/rl-next.md +++ b/doc/manual/src/release-notes/rl-next.md @@ -26,4 +26,6 @@ ```shell-session $ nix path-info /nix/store/gzaflydcr6sb3567hap9q6srzx8ggdgg-glibc-2.33-78.drv^* ``` - provides information about each of its outputs. \ No newline at end of file + provides information about each of its outputs. + +* The command `nix describe-stores` has been removed. diff --git a/src/nix/describe-stores.cc b/src/nix/describe-stores.cc deleted file mode 100644 index ad6b2f0f8..000000000 --- a/src/nix/describe-stores.cc +++ /dev/null @@ -1,44 +0,0 @@ -#include "command.hh" -#include "common-args.hh" -#include "shared.hh" -#include "store-api.hh" - -#include - -using namespace nix; - -struct CmdDescribeStores : Command, MixJSON -{ - std::string description() override - { - return "show registered store types and their available options"; - } - - Category category() override { return catUtility; } - - void run() override - { - auto res = nlohmann::json::object(); - for (auto & implem : *Implementations::registered) { - auto storeConfig = implem.getConfig(); - auto storeName = storeConfig->name(); - res[storeName]["settings"] = storeConfig->toJSON(); - } - if (json) { - logger->cout("%s", res); - } else { - for (auto & [storeName, storeConfig] : res.items()) { - std::cout << "## " << storeName << std::endl << std::endl; - for (auto & [optionName, optionDesc] : storeConfig.items()) { - std::cout << "### " << optionName << std::endl << std::endl; - std::cout << optionDesc["description"].get() << std::endl; - std::cout << "default: " << optionDesc["defaultValue"] << std::endl <("describe-stores"); diff --git a/tests/describe-stores.sh b/tests/describe-stores.sh deleted file mode 100644 index 3fea61483..000000000 --- a/tests/describe-stores.sh +++ /dev/null @@ -1,8 +0,0 @@ -source common.sh - -# Query an arbitrary value in `nix describe-stores --json`'s output just to -# check that it has the right structure -[[ $(nix --experimental-features 'nix-command flakes' describe-stores --json | jq '.["SSH Store"]["compress"]["defaultValue"]') == false ]] - -# Ensure that the output of `nix describe-stores` isn't empty -[[ -n $(nix --experimental-features 'nix-command flakes' describe-stores) ]] diff --git a/tests/local.mk b/tests/local.mk index 328f27e90..c6c728a86 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -115,7 +115,6 @@ nix_tests = \ db-migration.sh \ bash-profile.sh \ pass-as-file.sh \ - describe-stores.sh \ nix-profile.sh \ suggestions.sh \ store-ping.sh \ From 9eb53bbf17037691e1278c71517d74d0962aa43f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 21 Mar 2023 14:03:05 +0100 Subject: [PATCH 03/18] Support per-store Markdown documentation --- doc/manual/generate-manpage.nix | 6 +++- src/libstore/dummy-store.cc | 7 +++++ src/libstore/dummy-store.md | 13 ++++++++ src/libstore/http-binary-cache-store.cc | 7 +++++ src/libstore/http-binary-cache-store.md | 8 +++++ src/libstore/legacy-ssh-store.cc | 9 +++++- src/libstore/legacy-ssh-store.md | 8 +++++ src/libstore/local-binary-cache-store.cc | 7 +++++ src/libstore/local-binary-cache-store.md | 16 ++++++++++ src/libstore/local-store.cc | 7 +++++ src/libstore/local-store.hh | 3 +- src/libstore/local-store.md | 40 ++++++++++++++++++++++++ src/libstore/s3-binary-cache-store.cc | 7 +++++ src/libstore/s3-binary-cache-store.md | 8 +++++ src/libstore/ssh-store.cc | 9 +++++- src/libstore/ssh-store.md | 8 +++++ src/libstore/store-api.hh | 5 +++ src/libstore/uds-remote-store.hh | 7 +++++ src/libstore/uds-remote-store.md | 9 ++++++ src/nix/main.cc | 1 + 20 files changed, 181 insertions(+), 4 deletions(-) create mode 100644 src/libstore/dummy-store.md create mode 100644 src/libstore/http-binary-cache-store.md create mode 100644 src/libstore/legacy-ssh-store.md create mode 100644 src/libstore/local-binary-cache-store.md create mode 100644 src/libstore/local-store.md create mode 100644 src/libstore/s3-binary-cache-store.md create mode 100644 src/libstore/ssh-store.md create mode 100644 src/libstore/uds-remote-store.md diff --git a/doc/manual/generate-manpage.nix b/doc/manual/generate-manpage.nix index 7bb7a0caa..02d289eb1 100644 --- a/doc/manual/generate-manpage.nix +++ b/doc/manual/generate-manpage.nix @@ -129,10 +129,14 @@ let storeDocs = let - showStore = name: { settings }: + showStore = name: { settings, doc }: '' ## ${name} + ${doc} + + **Settings**: + ${showSettings false settings} ''; in concatStrings (attrValues (mapAttrs showStore cliDump.stores)); diff --git a/src/libstore/dummy-store.cc b/src/libstore/dummy-store.cc index b4fbe0b70..16e5fafd7 100644 --- a/src/libstore/dummy-store.cc +++ b/src/libstore/dummy-store.cc @@ -7,6 +7,13 @@ struct DummyStoreConfig : virtual StoreConfig { using StoreConfig::StoreConfig; const std::string name() override { return "Dummy Store"; } + + std::string doc() override + { + return + #include "dummy-store.md" + ; + } }; struct DummyStore : public virtual DummyStoreConfig, public virtual Store diff --git a/src/libstore/dummy-store.md b/src/libstore/dummy-store.md new file mode 100644 index 000000000..eb7b4ba0d --- /dev/null +++ b/src/libstore/dummy-store.md @@ -0,0 +1,13 @@ +R"( + +**Store URL format**: `dummy://` + +This store type represents a store that contains no store paths and +cannot be written to. It's useful when you want to use the Nix +evaluator when no actual Nix store exists, e.g. + +```console +# nix eval --store dummy:// --expr '1 + 2' +``` + +)" diff --git a/src/libstore/http-binary-cache-store.cc b/src/libstore/http-binary-cache-store.cc index 93f25363a..238fd1d98 100644 --- a/src/libstore/http-binary-cache-store.cc +++ b/src/libstore/http-binary-cache-store.cc @@ -13,6 +13,13 @@ struct HttpBinaryCacheStoreConfig : virtual BinaryCacheStoreConfig using BinaryCacheStoreConfig::BinaryCacheStoreConfig; const std::string name() override { return "HTTP Binary Cache Store"; } + + std::string doc() override + { + return + #include "http-binary-cache-store.md" + ; + } }; class HttpBinaryCacheStore : public virtual HttpBinaryCacheStoreConfig, public virtual BinaryCacheStore diff --git a/src/libstore/http-binary-cache-store.md b/src/libstore/http-binary-cache-store.md new file mode 100644 index 000000000..20c26d0c2 --- /dev/null +++ b/src/libstore/http-binary-cache-store.md @@ -0,0 +1,8 @@ +R"( + +**Store URL format**: `http://...`, `https://...` + +This store allows a binary cache to be accessed via the HTTP +protocol. + +)" diff --git a/src/libstore/legacy-ssh-store.cc b/src/libstore/legacy-ssh-store.cc index 2c9dd2680..7ce3dac6b 100644 --- a/src/libstore/legacy-ssh-store.cc +++ b/src/libstore/legacy-ssh-store.cc @@ -22,7 +22,14 @@ struct LegacySSHStoreConfig : virtual StoreConfig const Setting remoteProgram{(StoreConfig*) this, "nix-store", "remote-program", "path to the nix-store executable on the remote system"}; const Setting remoteStore{(StoreConfig*) this, "", "remote-store", "URI of the store on the remote system"}; - const std::string name() override { return "Legacy SSH Store"; } + const std::string name() override { return "SSH Store"; } + + std::string doc() override + { + return + #include "legacy-ssh-store.md" + ; + } }; struct LegacySSHStore : public virtual LegacySSHStoreConfig, public virtual Store diff --git a/src/libstore/legacy-ssh-store.md b/src/libstore/legacy-ssh-store.md new file mode 100644 index 000000000..043acebd6 --- /dev/null +++ b/src/libstore/legacy-ssh-store.md @@ -0,0 +1,8 @@ +R"( + +**Store URL format**: `ssh://[username@]hostname` + +This store type allows limited access to a remote store on another +machine via SSH. + +)" diff --git a/src/libstore/local-binary-cache-store.cc b/src/libstore/local-binary-cache-store.cc index f20b1fa02..e5ee6fc15 100644 --- a/src/libstore/local-binary-cache-store.cc +++ b/src/libstore/local-binary-cache-store.cc @@ -11,6 +11,13 @@ struct LocalBinaryCacheStoreConfig : virtual BinaryCacheStoreConfig using BinaryCacheStoreConfig::BinaryCacheStoreConfig; const std::string name() override { return "Local Binary Cache Store"; } + + std::string doc() override + { + return + #include "local-binary-cache-store.md" + ; + } }; class LocalBinaryCacheStore : public virtual LocalBinaryCacheStoreConfig, public virtual BinaryCacheStore diff --git a/src/libstore/local-binary-cache-store.md b/src/libstore/local-binary-cache-store.md new file mode 100644 index 000000000..93fddc840 --- /dev/null +++ b/src/libstore/local-binary-cache-store.md @@ -0,0 +1,16 @@ +R"( + +**Store URL format**: `file://`*path* + +This store allows reading and writing a binary cache stored in *path* +in the local filesystem. If *path* does not exist, it will be created. + +For example, the following builds or downloads `nixpkgs#hello` into +the local store and then copies it to the binary cache in +`/tmp/binary-cache`: + +``` +# nix copy --to file:///tmp/binary-cache nixpkgs#hello +``` + +)" diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index c9a466ee8..1eada7cc3 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -44,6 +44,13 @@ namespace nix { +std::string LocalStoreConfig::doc() +{ + return + #include "local-store.md" + ; +} + struct LocalStore::State::Stmts { /* Some precompiled SQLite statements. */ SQLiteStmt RegisterValidPath; diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index a84eb7c26..5e5ce86c8 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -41,8 +41,9 @@ struct LocalStoreConfig : virtual LocalFSStoreConfig "require-sigs", "whether store paths should have a trusted signature on import"}; const std::string name() override { return "Local Store"; } -}; + std::string doc() override; +}; class LocalStore : public virtual LocalStoreConfig, public virtual LocalFSStore, public virtual GcStore { diff --git a/src/libstore/local-store.md b/src/libstore/local-store.md new file mode 100644 index 000000000..893457d32 --- /dev/null +++ b/src/libstore/local-store.md @@ -0,0 +1,40 @@ +R"( + +**Store URL format**: `local`, *root* + +This store type accesses a Nix store in the local filesystem directly +(i.e. not via the Nix daemon). *root* is an absolute path that denotes +the "root" of the filesystem; other directories such as the Nix store +directory (as denoted by the `store` setting) are interpreted relative +to *root*. The store pseudo-URL `local` denotes a store that uses `/` +as its root directory. + +A store that uses a *root* other than `/` is called a *chroot +store*. With such stores, the store directory is "logically" still +`/nix/store`, so programs stored in them can only be built and +executed by `chroot`-ing into *root*. Chroot stores only support +building and running on Linux when mount and user namespaces are +enabled. + +For example, the following uses `/tmp/root` as the chroot environment +to build or download `nixpkgs#hello` and then execute it: + +```console +# nix run --store /tmp/root nixpkgs#hello +Hello, world! +``` + +Here, the "physical" store location is `/tmp/root/nix/store`, and +Nix's store metadata is in `/tmp/root/nix/var/nix/db`. + +It is also possible, but not recommended, to change the "logical" +location of the Nix store from its default of `/nix/store`. This makes +it impossible to use default substituters such as +`https://cache.nixos.org/`, and thus you may have to build everything +locally. Here is an example: + +```console +# nix build --store 'local?store=/tmp/my-nix/store&state=/tmp/my-nix/state&log=/tmp/my-nix/log' nixpkgs#hello +``` + +)" diff --git a/src/libstore/s3-binary-cache-store.cc b/src/libstore/s3-binary-cache-store.cc index 8006bd733..05842a2ea 100644 --- a/src/libstore/s3-binary-cache-store.cc +++ b/src/libstore/s3-binary-cache-store.cc @@ -205,6 +205,13 @@ struct S3BinaryCacheStoreConfig : virtual BinaryCacheStoreConfig (StoreConfig*) this, 5 * 1024 * 1024, "buffer-size", "size (in bytes) of each part in multi-part uploads"}; const std::string name() override { return "S3 Binary Cache Store"; } + + std::string doc() override + { + return + #include "s3-binary-cache-store.md" + ; + } }; struct S3BinaryCacheStoreImpl : virtual S3BinaryCacheStoreConfig, public virtual S3BinaryCacheStore diff --git a/src/libstore/s3-binary-cache-store.md b/src/libstore/s3-binary-cache-store.md new file mode 100644 index 000000000..70fe0eb09 --- /dev/null +++ b/src/libstore/s3-binary-cache-store.md @@ -0,0 +1,8 @@ +R"( + +**Store URL format**: `s3://`*bucket-name* + +This store allows reading and writing a binary cache stored in an AWS +S3 bucket. + +)" diff --git a/src/libstore/ssh-store.cc b/src/libstore/ssh-store.cc index cfa063803..6f3ee6262 100644 --- a/src/libstore/ssh-store.cc +++ b/src/libstore/ssh-store.cc @@ -18,7 +18,14 @@ struct SSHStoreConfig : virtual RemoteStoreConfig const Setting remoteProgram{(StoreConfig*) this, "nix-daemon", "remote-program", "path to the nix-daemon executable on the remote system"}; const Setting remoteStore{(StoreConfig*) this, "", "remote-store", "URI of the store on the remote system"}; - const std::string name() override { return "SSH Store"; } + const std::string name() override { return "Experimental SSH Store"; } + + std::string doc() override + { + return + #include "ssh-store.md" + ; + } }; class SSHStore : public virtual SSHStoreConfig, public virtual RemoteStore diff --git a/src/libstore/ssh-store.md b/src/libstore/ssh-store.md new file mode 100644 index 000000000..881537e71 --- /dev/null +++ b/src/libstore/ssh-store.md @@ -0,0 +1,8 @@ +R"( + +**Store URL format**: `ssh-ng://[username@]hostname` + +Experimental store type that allows full access to a Nix store on a +remote machine. + +)" diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 4d8db3596..9afb33b9e 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -101,6 +101,11 @@ struct StoreConfig : public Config virtual const std::string name() = 0; + virtual std::string doc() + { + return ""; + } + const PathSetting storeDir_{this, false, settings.nixStore, "store", "path to the Nix store"}; const Path storeDir = storeDir_; diff --git a/src/libstore/uds-remote-store.hh b/src/libstore/uds-remote-store.hh index d31a4d592..caa452919 100644 --- a/src/libstore/uds-remote-store.hh +++ b/src/libstore/uds-remote-store.hh @@ -15,6 +15,13 @@ struct UDSRemoteStoreConfig : virtual LocalFSStoreConfig, virtual RemoteStoreCon } const std::string name() override { return "Local Daemon Store"; } + + std::string doc() override + { + return + #include "uds-remote-store.md" + ; + } }; class UDSRemoteStore : public virtual UDSRemoteStoreConfig, public virtual LocalFSStore, public virtual RemoteStore diff --git a/src/libstore/uds-remote-store.md b/src/libstore/uds-remote-store.md new file mode 100644 index 000000000..8df0bd6ff --- /dev/null +++ b/src/libstore/uds-remote-store.md @@ -0,0 +1,9 @@ +R"( + +**Store URL format**: `daemon`, `unix://`*path* + +This store type accesses a Nix store by talking to a Nix daemon +listening on the Unix domain socket *path*. The store pseudo-URL +`daemon` is equivalent to `unix:///nix/var/nix/daemon-socket/socket`. + +)" diff --git a/src/nix/main.cc b/src/nix/main.cc index 0ea6d7784..6caca9c22 100644 --- a/src/nix/main.cc +++ b/src/nix/main.cc @@ -175,6 +175,7 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs for (auto & implem : *Implementations::registered) { auto storeConfig = implem.getConfig(); auto storeName = storeConfig->name(); + stores[storeName]["doc"] = storeConfig->doc(); stores[storeName]["settings"] = storeConfig->toJSON(); } res["stores"] = std::move(stores); From 3fc4659d22fc3c8cfbffd7322fd6c034efaaa3ab Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 21 Mar 2023 14:12:15 +0100 Subject: [PATCH 04/18] Formatting --- doc/manual/utils.nix | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/manual/utils.nix b/doc/manual/utils.nix index ce0c21c98..c0a40c9ff 100644 --- a/doc/manual/utils.nix +++ b/doc/manual/utils.nix @@ -48,6 +48,7 @@ rec { ${indent " " body} ''; + # separate body to cleanly handle indentation body = '' ${description} @@ -56,6 +57,7 @@ rec { ${showAliases aliases} ''; + showDefault = documentDefault: defaultValue: if documentDefault then # a StringMap value type is specified as a string, but @@ -67,12 +69,15 @@ rec { if defaultValue then "`true`" else "`false`" else "`${toString defaultValue}`" else "*machine-specific*"; + showAliases = aliases: if aliases == [] then "" else "**Deprecated alias:** ${(concatStringsSep ", " (map (s: "`${s}`") aliases))}"; + indent = prefix: s: concatStringsSep "\n" (map (x: if x == "" then x else "${prefix}${x}") (splitLines s)); - in result; + + in result; showSettings = useSpans: settingsInfo: concatStrings (attrValues (mapAttrs (showSetting useSpans) settingsInfo)); } From 233b063b08b6a82921d26fb5a86e15c2b94a72ee Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 21 Mar 2023 14:37:09 +0100 Subject: [PATCH 05/18] Move store docs to 'nix help-stores' Why not 'nix help stores'? Well, 'nix help ' already means 'show help on the "arg" subcommand'. --- src/libstore/globals.hh | 5 ++++- src/nix/help-stores.md | 7 +++++++ src/nix/main.cc | 32 +++++++++++++++++++++++++++++++- src/nix/nix.md | 5 ++--- src/nix/store.cc | 7 ------- src/nix/store.md | 9 --------- 6 files changed, 44 insertions(+), 21 deletions(-) create mode 100644 src/nix/help-stores.md delete mode 100644 src/nix/store.md diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index 93086eaf8..4382d1b85 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -97,7 +97,10 @@ public: Path nixDaemonSocketFile; Setting storeUri{this, getEnv("NIX_REMOTE").value_or("auto"), "store", - "The default Nix store to use."}; + R"( + The URL of the Nix store to use. See [`nix help-stores`](@docroot@/command-ref/new-cli/nix3-help-stores.md) + for supported store types and settings. + )"}; Setting keepFailed{this, false, "keep-failed", "Whether to keep temporary directories of failed builds."}; diff --git a/src/nix/help-stores.md b/src/nix/help-stores.md new file mode 100644 index 000000000..a33a7ea70 --- /dev/null +++ b/src/nix/help-stores.md @@ -0,0 +1,7 @@ +R"( + +Nix supports different types of stores. These are described below. + +@stores@ + +)" diff --git a/src/nix/main.cc b/src/nix/main.cc index 6caca9c22..5981028f7 100644 --- a/src/nix/main.cc +++ b/src/nix/main.cc @@ -223,6 +223,14 @@ static void showHelp(std::vector subcommand, NixArgs & toplevel) std::cout << renderMarkdownToTerminal(markdown) << "\n"; } +static NixArgs & getNixArgs(Command & cmd) +{ + assert(cmd.parent); + MultiCommand * toplevel = cmd.parent; + while (toplevel->parent) toplevel = toplevel->parent; + return dynamic_cast(*toplevel); +} + struct CmdHelp : Command { std::vector subcommand; @@ -252,12 +260,34 @@ struct CmdHelp : Command assert(parent); MultiCommand * toplevel = parent; while (toplevel->parent) toplevel = toplevel->parent; - showHelp(subcommand, dynamic_cast(*toplevel)); + showHelp(subcommand, getNixArgs(*this)); } }; static auto rCmdHelp = registerCommand("help"); +struct CmdHelpStores : Command +{ + std::string description() override + { + return "show help about store types and their settings"; + } + + std::string doc() override + { + return + #include "help-stores.md" + ; + } + + void run() override + { + showHelp({"help-stores"}, getNixArgs(*this)); + } +}; + +static auto rCmdHelpStores = registerCommand("help-stores"); + void mainWrapped(int argc, char * * argv) { savedArgv = argv; diff --git a/src/nix/nix.md b/src/nix/nix.md index 0a90fa6c9..e1865b31c 100644 --- a/src/nix/nix.md +++ b/src/nix/nix.md @@ -220,8 +220,7 @@ operate are determined as follows: # Nix stores -Most `nix` subcommands operate on a *Nix store*. - -TODO: list store types, options +Most `nix` subcommands operate on a *Nix store*. These are documented +in [`nix help-stores`](./nix3-help-stores.md). )"" diff --git a/src/nix/store.cc b/src/nix/store.cc index 72b037488..2879e03b3 100644 --- a/src/nix/store.cc +++ b/src/nix/store.cc @@ -12,13 +12,6 @@ struct CmdStore : virtual NixMultiCommand return "manipulate a Nix store"; } - std::string doc() override - { - return - #include "store.md" - ; - } - Category category() override { return catUtility; } void run() override diff --git a/src/nix/store.md b/src/nix/store.md deleted file mode 100644 index d80a3b1be..000000000 --- a/src/nix/store.md +++ /dev/null @@ -1,9 +0,0 @@ -R"( - -# Store types - -Nix supports different types of stores. These are listed below. - -@stores@ - -)" From c967c29290b1d0b7ea5a169c39324ddca46403ba Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 21 Mar 2023 14:43:58 +0100 Subject: [PATCH 06/18] Add a "help" category This makes the help commands show up prominently at the top of the 'nix' manpage. --- src/libcmd/command.hh | 1 + src/nix/main.cc | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh index 874ca3249..b7a87dad0 100644 --- a/src/libcmd/command.hh +++ b/src/libcmd/command.hh @@ -18,6 +18,7 @@ class EvalState; struct Pos; class Store; +static constexpr Command::Category catHelp = -1; static constexpr Command::Category catSecondary = 100; static constexpr Command::Category catUtility = 101; static constexpr Command::Category catNixInstallation = 102; diff --git a/src/nix/main.cc b/src/nix/main.cc index 5981028f7..ffe558ee8 100644 --- a/src/nix/main.cc +++ b/src/nix/main.cc @@ -65,6 +65,7 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs NixArgs() : MultiCommand(RegisterCommand::getCommandsFor({})), MixCommonArgs("nix") { categories.clear(); + categories[catHelp] = "Help commands"; categories[Command::catDefault] = "Main commands"; categories[catSecondary] = "Infrequently used commands"; categories[catUtility] = "Utility/scripting commands"; @@ -255,6 +256,8 @@ struct CmdHelp : Command ; } + Category category() override { return catHelp; } + void run() override { assert(parent); @@ -280,6 +283,8 @@ struct CmdHelpStores : Command ; } + Category category() override { return catHelp; } + void run() override { showHelp({"help-stores"}, getNixArgs(*this)); From da8903ecc3484c4c6cf4ab6b35da250e435d1964 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 22 Mar 2023 13:11:35 +0100 Subject: [PATCH 07/18] nix help-stores: Don't include anchors Since setting names are not unique we don't have an easy way to produce unique anchors. --- doc/manual/utils.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/manual/utils.nix b/doc/manual/utils.nix index c0a40c9ff..a0e5cf1d1 100644 --- a/doc/manual/utils.nix +++ b/doc/manual/utils.nix @@ -39,12 +39,12 @@ rec { filterAttrs = pred: set: listToAttrs (concatMap (name: let v = set.${name}; in if pred name v then [(nameValuePair name v)] else []) (attrNames set)); - showSetting = useSpans: name: { description, documentDefault, defaultValue, aliases, ... }: + showSetting = useAnchors: name: { description, documentDefault, defaultValue, aliases, ... }: let result = squash '' - - ${if useSpans + - ${if useAnchors then ''[`${name}`](#conf-${name})'' - else ''[`${name}`](#conf-${name})''} + else ''`${name}`''} ${indent " " body} ''; @@ -79,5 +79,5 @@ rec { in result; - showSettings = useSpans: settingsInfo: concatStrings (attrValues (mapAttrs (showSetting useSpans) settingsInfo)); + showSettings = useAnchors: settingsInfo: concatStrings (attrValues (mapAttrs (showSetting useAnchors) settingsInfo)); } From 5691bac2025db9dbf637f23d1d2dd502010df37b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 22 Mar 2023 14:23:36 +0100 Subject: [PATCH 08/18] Improve store setting descriptions / Markdown formatting --- .../src/package-management/s3-substituter.md | 34 +--------- src/libstore/binary-cache-store.hh | 34 +++++++--- src/libstore/legacy-ssh-store.cc | 14 ++-- src/libstore/local-fs-store.hh | 16 +++-- src/libstore/local-store.hh | 3 +- src/libstore/remote-store.hh | 10 +-- src/libstore/s3-binary-cache-store.cc | 64 ++++++++++++++++--- src/libstore/ssh-store-config.hh | 29 +++++++++ src/libstore/ssh-store.cc | 9 +-- src/libstore/store-api.hh | 31 +++++++-- src/nix/help-stores.md | 4 ++ 11 files changed, 167 insertions(+), 81 deletions(-) create mode 100644 src/libstore/ssh-store-config.hh diff --git a/doc/manual/src/package-management/s3-substituter.md b/doc/manual/src/package-management/s3-substituter.md index 30f2b2e11..d8a1d9105 100644 --- a/doc/manual/src/package-management/s3-substituter.md +++ b/doc/manual/src/package-management/s3-substituter.md @@ -1,41 +1,11 @@ # Serving a Nix store via S3 -Nix has built-in support for storing and fetching store paths from +Nix has [built-in support](@docroot@/command-ref/new-cli/nix3-help-stores.md#s3-binary-cache-store) +for storing and fetching store paths from Amazon S3 and S3-compatible services. This uses the same *binary* cache mechanism that Nix usually uses to fetch prebuilt binaries from [cache.nixos.org](https://cache.nixos.org/). -The following options can be specified as URL parameters to the S3 URL: - - - `profile`\ - The name of the AWS configuration profile to use. By default Nix - will use the `default` profile. - - - `region`\ - The region of the S3 bucket. `us–east-1` by default. - - If your bucket is not in `us–east-1`, you should always explicitly - specify the region parameter. - - - `endpoint`\ - The URL to your S3-compatible service, for when not using Amazon S3. - Do not specify this value if you're using Amazon S3. - - > **Note** - > - > This endpoint must support HTTPS and will use path-based - > addressing instead of virtual host based addressing. - - - `scheme`\ - The scheme used for S3 requests, `https` (default) or `http`. This - option allows you to disable HTTPS for binary caches which don't - support it. - - > **Note** - > - > HTTPS should be used if the cache might contain sensitive - > information. - In this example we will use the bucket named `example-nix-cache`. ## Anonymous Reads to your S3-compatible binary cache diff --git a/src/libstore/binary-cache-store.hh b/src/libstore/binary-cache-store.hh index abd92a83c..c1d08926d 100644 --- a/src/libstore/binary-cache-store.hh +++ b/src/libstore/binary-cache-store.hh @@ -16,17 +16,33 @@ struct BinaryCacheStoreConfig : virtual StoreConfig { using StoreConfig::StoreConfig; - const Setting compression{(StoreConfig*) this, "xz", "compression", "NAR compression method ('xz', 'bzip2', 'gzip', 'zstd', or 'none')"}; - const Setting writeNARListing{(StoreConfig*) this, false, "write-nar-listing", "whether to write a JSON file listing the files in each NAR"}; - const Setting writeDebugInfo{(StoreConfig*) this, false, "index-debug-info", "whether to index DWARF debug info files by build ID"}; - const Setting secretKeyFile{(StoreConfig*) this, "", "secret-key", "path to secret key used to sign the binary cache"}; - const Setting localNarCache{(StoreConfig*) this, "", "local-nar-cache", "path to a local cache of NARs"}; + const Setting compression{(StoreConfig*) this, "xz", "compression", + "NAR compression method (`xz`, `bzip2`, `gzip`, `zstd`, or `none`)."}; + + const Setting writeNARListing{(StoreConfig*) this, false, "write-nar-listing", + "Whether to write a JSON file that lists the files in each NAR."}; + + const Setting writeDebugInfo{(StoreConfig*) this, false, "index-debug-info", + R"( + Whether to index DWARF debug info files by build ID. This allows [`dwarffs`](https://github.com/edolstra/dwarffs) to + fetch debug info on demand + )"}; + + const Setting secretKeyFile{(StoreConfig*) this, "", "secret-key", + "Path to the secret key used to sign the binary cache."}; + + const Setting localNarCache{(StoreConfig*) this, "", "local-nar-cache", + "Path to a local cache of NARs fetched from this binary cache, used by commands such as `nix store cat`."}; + const Setting parallelCompression{(StoreConfig*) this, false, "parallel-compression", - "enable multi-threading compression for NARs, available for xz and zstd only currently"}; + "Enable multi-threaded compression of NARs. This is currently only available for `xz` and `zstd`."}; + const Setting compressionLevel{(StoreConfig*) this, -1, "compression-level", - "specify 'preset level' of compression to be used with NARs: " - "meaning and accepted range of values depends on compression method selected, " - "other than -1 which we reserve to indicate Nix defaults should be used"}; + R"( + The *preset level* to be used when compressing NARs. + The meaning and accepted values depend on the compression method selected. + `-1` specifies that the default compression level should be used. + )"}; }; class BinaryCacheStore : public virtual BinaryCacheStoreConfig, diff --git a/src/libstore/legacy-ssh-store.cc b/src/libstore/legacy-ssh-store.cc index 7ce3dac6b..a8ce0b8b0 100644 --- a/src/libstore/legacy-ssh-store.cc +++ b/src/libstore/legacy-ssh-store.cc @@ -1,3 +1,4 @@ +#include "ssh-store-config.hh" #include "archive.hh" #include "pool.hh" #include "remote-store.hh" @@ -12,15 +13,12 @@ namespace nix { -struct LegacySSHStoreConfig : virtual StoreConfig +struct LegacySSHStoreConfig : virtual CommonSSHStoreConfig { - using StoreConfig::StoreConfig; - const Setting maxConnections{(StoreConfig*) this, 1, "max-connections", "maximum number of concurrent SSH connections"}; - const Setting sshKey{(StoreConfig*) this, "", "ssh-key", "path to an SSH private key"}; - const Setting sshPublicHostKey{(StoreConfig*) this, "", "base64-ssh-public-host-key", "The public half of the host's SSH key"}; - const Setting compress{(StoreConfig*) this, false, "compress", "whether to compress the connection"}; - const Setting remoteProgram{(StoreConfig*) this, "nix-store", "remote-program", "path to the nix-store executable on the remote system"}; - const Setting remoteStore{(StoreConfig*) this, "", "remote-store", "URI of the store on the remote system"}; + using CommonSSHStoreConfig::CommonSSHStoreConfig; + + const Setting maxConnections{(StoreConfig*) this, 1, "max-connections", + "Maximum number of concurrent SSH connections."}; const std::string name() override { return "SSH Store"; } diff --git a/src/libstore/local-fs-store.hh b/src/libstore/local-fs-store.hh index 947707341..796e72045 100644 --- a/src/libstore/local-fs-store.hh +++ b/src/libstore/local-fs-store.hh @@ -9,20 +9,28 @@ namespace nix { struct LocalFSStoreConfig : virtual StoreConfig { using StoreConfig::StoreConfig; + // FIXME: the (StoreConfig*) cast works around a bug in gcc that causes // it to omit the call to the Setting constructor. Clang works fine // either way. + const PathSetting rootDir{(StoreConfig*) this, true, "", - "root", "directory prefixed to all other paths"}; + "root", + "Directory prefixed to all other paths."}; + const PathSetting stateDir{(StoreConfig*) this, false, rootDir != "" ? rootDir + "/nix/var/nix" : settings.nixStateDir, - "state", "directory where Nix will store state"}; + "state", + "Directory where Nix will store state."}; + const PathSetting logDir{(StoreConfig*) this, false, rootDir != "" ? rootDir + "/nix/var/log/nix" : settings.nixLogDir, - "log", "directory where Nix will store state"}; + "log", + "directory where Nix will store log files."}; + const PathSetting realStoreDir{(StoreConfig*) this, false, rootDir != "" ? rootDir + "/nix/store" : storeDir, "real", - "physical path to the Nix store"}; + "Physical path of the Nix store."}; }; class LocalFSStore : public virtual LocalFSStoreConfig, diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index 5e5ce86c8..3743f6b10 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -38,7 +38,8 @@ struct LocalStoreConfig : virtual LocalFSStoreConfig Setting requireSigs{(StoreConfig*) this, settings.requireSigs, - "require-sigs", "whether store paths should have a trusted signature on import"}; + "require-sigs", + "Whether store paths copied into this store should have a trusted signature."}; const std::string name() override { return "Local Store"; } diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index 8cd7cc822..999151239 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -22,11 +22,13 @@ struct RemoteStoreConfig : virtual StoreConfig { using StoreConfig::StoreConfig; - const Setting maxConnections{(StoreConfig*) this, 1, - "max-connections", "maximum number of concurrent connections to the Nix daemon"}; + const Setting maxConnections{(StoreConfig*) this, 1, "max-connections", + "Maximum number of concurrent connections to the Nix daemon."}; - const Setting maxConnectionAge{(StoreConfig*) this, std::numeric_limits::max(), - "max-connection-age", "number of seconds to reuse a connection"}; + const Setting maxConnectionAge{(StoreConfig*) this, + std::numeric_limits::max(), + "max-connection-age", + "Maximum age of a connection before it is closed."}; }; /* FIXME: RemoteStore is a misnomer - should be something like diff --git a/src/libstore/s3-binary-cache-store.cc b/src/libstore/s3-binary-cache-store.cc index 05842a2ea..ac82147ee 100644 --- a/src/libstore/s3-binary-cache-store.cc +++ b/src/libstore/s3-binary-cache-store.cc @@ -192,17 +192,63 @@ S3BinaryCacheStore::S3BinaryCacheStore(const Params & params) struct S3BinaryCacheStoreConfig : virtual BinaryCacheStoreConfig { using BinaryCacheStoreConfig::BinaryCacheStoreConfig; - const Setting profile{(StoreConfig*) this, "", "profile", "The name of the AWS configuration profile to use."}; - const Setting region{(StoreConfig*) this, Aws::Region::US_EAST_1, "region", {"aws-region"}}; - const Setting scheme{(StoreConfig*) this, "", "scheme", "The scheme to use for S3 requests, https by default."}; - const Setting endpoint{(StoreConfig*) this, "", "endpoint", "An optional override of the endpoint to use when talking to S3."}; - const Setting narinfoCompression{(StoreConfig*) this, "", "narinfo-compression", "compression method for .narinfo files"}; - const Setting lsCompression{(StoreConfig*) this, "", "ls-compression", "compression method for .ls files"}; - const Setting logCompression{(StoreConfig*) this, "", "log-compression", "compression method for log/* files"}; + + const Setting profile{(StoreConfig*) this, "", "profile", + R"( + The name of the AWS configuration profile to use. By default + Nix will use the `default` profile. + )"}; + + const Setting region{(StoreConfig*) this, Aws::Region::US_EAST_1, "region", + R"( + The region of the S3 bucket. If your bucket is not in + `us–east-1`, you should always explicitly specify the region + parameter. + )"}; + + const Setting scheme{(StoreConfig*) this, "", "scheme", + R"( + The scheme used for S3 requests, `https` (default) or `http`. This + option allows you to disable HTTPS for binary caches which don't + support it. + + > **Note** + > + > HTTPS should be used if the cache might contain sensitive + > information. + )"}; + + const Setting endpoint{(StoreConfig*) this, "", "endpoint", + R"( + The URL of the endpoint of an S3-compatible service such as MinIO. + Do not specify this setting if you're using Amazon S3. + + > **Note** + > + > This endpoint must support HTTPS and will use path-based + > addressing instead of virtual host based addressing. + )"}; + + const Setting narinfoCompression{(StoreConfig*) this, "", "narinfo-compression", + "Compression method for `.narinfo` files."}; + + const Setting lsCompression{(StoreConfig*) this, "", "ls-compression", + "Compression method for `.ls` files."}; + + const Setting logCompression{(StoreConfig*) this, "", "log-compression", + R"( + Compression method for `log/*` files. It is recommended to + use a compression method supported by most web browsers + (e.g. `brotli`). + )"}; + const Setting multipartUpload{ - (StoreConfig*) this, false, "multipart-upload", "whether to use multi-part uploads"}; + (StoreConfig*) this, false, "multipart-upload", + "Whether to use multi-part uploads."}; + const Setting bufferSize{ - (StoreConfig*) this, 5 * 1024 * 1024, "buffer-size", "size (in bytes) of each part in multi-part uploads"}; + (StoreConfig*) this, 5 * 1024 * 1024, "buffer-size", + "Size (in bytes) of each part in multi-part uploads."}; const std::string name() override { return "S3 Binary Cache Store"; } diff --git a/src/libstore/ssh-store-config.hh b/src/libstore/ssh-store-config.hh new file mode 100644 index 000000000..767fc5e05 --- /dev/null +++ b/src/libstore/ssh-store-config.hh @@ -0,0 +1,29 @@ +#include "store-api.hh" + +namespace nix { + +struct CommonSSHStoreConfig : virtual StoreConfig +{ + using StoreConfig::StoreConfig; + + const Setting sshKey{(StoreConfig*) this, "", "ssh-key", + "Path to the SSH private key used to authenticate to the remote machine."}; + + const Setting sshPublicHostKey{(StoreConfig*) this, "", "base64-ssh-public-host-key", + "The public host key of the remote machine."}; + + const Setting compress{(StoreConfig*) this, false, "compress", + "Whether to enable SSH compression."}; + + const Setting remoteProgram{(StoreConfig*) this, "nix-store", "remote-program", + "Path to the `nix-store` executable on the remote machine."}; + + const Setting remoteStore{(StoreConfig*) this, "", "remote-store", + R"( + [Store URL](@docroot@/command-ref/new-cli/nix3-help-stores.md#store-url-format) + to be used on the remote machine. The default is `auto` + (i.e. use the Nix daemon or `/nix/store` directly). + )"}; +}; + +} diff --git a/src/libstore/ssh-store.cc b/src/libstore/ssh-store.cc index 6f3ee6262..3206bf169 100644 --- a/src/libstore/ssh-store.cc +++ b/src/libstore/ssh-store.cc @@ -1,3 +1,4 @@ +#include "ssh-store-config.hh" #include "store-api.hh" #include "remote-store.hh" #include "remote-fs-accessor.hh" @@ -8,16 +9,10 @@ namespace nix { -struct SSHStoreConfig : virtual RemoteStoreConfig +struct SSHStoreConfig : virtual RemoteStoreConfig, virtual CommonSSHStoreConfig { using RemoteStoreConfig::RemoteStoreConfig; - const Setting sshKey{(StoreConfig*) this, "", "ssh-key", "path to an SSH private key"}; - const Setting sshPublicHostKey{(StoreConfig*) this, "", "base64-ssh-public-host-key", "The public half of the host's SSH key"}; - const Setting compress{(StoreConfig*) this, false, "compress", "whether to compress the connection"}; - const Setting remoteProgram{(StoreConfig*) this, "nix-daemon", "remote-program", "path to the nix-daemon executable on the remote system"}; - const Setting remoteStore{(StoreConfig*) this, "", "remote-store", "URI of the store on the remote system"}; - const std::string name() override { return "Experimental SSH Store"; } std::string doc() override diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 9afb33b9e..2f4391c43 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -107,16 +107,35 @@ struct StoreConfig : public Config } const PathSetting storeDir_{this, false, settings.nixStore, - "store", "path to the Nix store"}; + "store", + R"( + Logical location of the Nix store, usually + `/nix/store`. Note that you can only copy store paths + between stores if they have the same `store` setting. + )"}; const Path storeDir = storeDir_; - const Setting pathInfoCacheSize{this, 65536, "path-info-cache-size", "size of the in-memory store path information cache"}; + const Setting pathInfoCacheSize{this, 65536, "path-info-cache-size", + "Size of the in-memory store path metadata cache."}; - const Setting isTrusted{this, false, "trusted", "whether paths from this store can be used as substitutes even when they lack trusted signatures"}; + const Setting isTrusted{this, false, "trusted", + R"( + Whether paths from this store can be used as substitutes + even if they are not signed by a key listed in the + [`trusted-public-keys`](@docroot@/command-ref/conf-file.md#conf-trusted-public-keys) + setting. + )"}; - Setting priority{this, 0, "priority", "priority of this substituter (lower value means higher priority)"}; + Setting priority{this, 0, "priority", + R"( + Priority of this store when used as a substituter. A lower value means a higher priority. + )"}; - Setting wantMassQuery{this, false, "want-mass-query", "whether this substituter can be queried efficiently for path validity"}; + Setting wantMassQuery{this, false, "want-mass-query", + R"( + Whether this store (when used as a substituter) can be + queried efficiently for path validity. + )"}; Setting systemFeatures{this, getDefaultSystemFeatures(), "system-features", @@ -130,8 +149,6 @@ public: typedef std::map Params; - - protected: struct PathInfoCacheValue { diff --git a/src/nix/help-stores.md b/src/nix/help-stores.md index a33a7ea70..8f872cb79 100644 --- a/src/nix/help-stores.md +++ b/src/nix/help-stores.md @@ -2,6 +2,10 @@ R"( Nix supports different types of stores. These are described below. +## Store URL format + +TODO + @stores@ )" From b134546f08000ce80722fdc4de58ac5fd20865ed Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Mar 2023 09:11:15 +0100 Subject: [PATCH 09/18] Fix clang build --- src/libstore/legacy-ssh-store.cc | 1 + src/libstore/ssh-store.cc | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/libstore/legacy-ssh-store.cc b/src/libstore/legacy-ssh-store.cc index a8ce0b8b0..72b8e89fc 100644 --- a/src/libstore/legacy-ssh-store.cc +++ b/src/libstore/legacy-ssh-store.cc @@ -56,6 +56,7 @@ struct LegacySSHStore : public virtual LegacySSHStoreConfig, public virtual Stor LegacySSHStore(const std::string & scheme, const std::string & host, const Params & params) : StoreConfig(params) + , CommonSSHStoreConfig(params) , LegacySSHStoreConfig(params) , Store(params) , host(host) diff --git a/src/libstore/ssh-store.cc b/src/libstore/ssh-store.cc index 3206bf169..be8a67c13 100644 --- a/src/libstore/ssh-store.cc +++ b/src/libstore/ssh-store.cc @@ -12,6 +12,7 @@ namespace nix { struct SSHStoreConfig : virtual RemoteStoreConfig, virtual CommonSSHStoreConfig { using RemoteStoreConfig::RemoteStoreConfig; + using CommonSSHStoreConfig::CommonSSHStoreConfig; const std::string name() override { return "Experimental SSH Store"; } @@ -30,6 +31,7 @@ public: SSHStore(const std::string & scheme, const std::string & host, const Params & params) : StoreConfig(params) , RemoteStoreConfig(params) + , CommonSSHStoreConfig(params) , SSHStoreConfig(params) , Store(params) , RemoteStore(params) From 80f0b8d3070f346bb89bd0ab1a541940a7ceeec1 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Mar 2023 09:35:35 +0100 Subject: [PATCH 10/18] Fix SSHStore --- src/libstore/legacy-ssh-store.cc | 3 +++ src/libstore/ssh-store-config.hh | 3 --- src/libstore/ssh-store.cc | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libstore/legacy-ssh-store.cc b/src/libstore/legacy-ssh-store.cc index 72b8e89fc..98322b045 100644 --- a/src/libstore/legacy-ssh-store.cc +++ b/src/libstore/legacy-ssh-store.cc @@ -17,6 +17,9 @@ struct LegacySSHStoreConfig : virtual CommonSSHStoreConfig { using CommonSSHStoreConfig::CommonSSHStoreConfig; + const Setting remoteProgram{(StoreConfig*) this, "nix-store", "remote-program", + "Path to the `nix-store` executable on the remote machine."}; + const Setting maxConnections{(StoreConfig*) this, 1, "max-connections", "Maximum number of concurrent SSH connections."}; diff --git a/src/libstore/ssh-store-config.hh b/src/libstore/ssh-store-config.hh index 767fc5e05..c4232df34 100644 --- a/src/libstore/ssh-store-config.hh +++ b/src/libstore/ssh-store-config.hh @@ -15,9 +15,6 @@ struct CommonSSHStoreConfig : virtual StoreConfig const Setting compress{(StoreConfig*) this, false, "compress", "Whether to enable SSH compression."}; - const Setting remoteProgram{(StoreConfig*) this, "nix-store", "remote-program", - "Path to the `nix-store` executable on the remote machine."}; - const Setting remoteStore{(StoreConfig*) this, "", "remote-store", R"( [Store URL](@docroot@/command-ref/new-cli/nix3-help-stores.md#store-url-format) diff --git a/src/libstore/ssh-store.cc b/src/libstore/ssh-store.cc index be8a67c13..962221ad2 100644 --- a/src/libstore/ssh-store.cc +++ b/src/libstore/ssh-store.cc @@ -14,6 +14,9 @@ struct SSHStoreConfig : virtual RemoteStoreConfig, virtual CommonSSHStoreConfig using RemoteStoreConfig::RemoteStoreConfig; using CommonSSHStoreConfig::CommonSSHStoreConfig; + const Setting remoteProgram{(StoreConfig*) this, "nix-daemon", "remote-program", + "Path to the `nix-daemon` executable on the remote machine."}; + const std::string name() override { return "Experimental SSH Store"; } std::string doc() override From 2851e239a7a4c7de34a2a2b13d3076b10d34ebd7 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Mar 2023 10:08:49 +0100 Subject: [PATCH 11/18] Make useAnchors a named argument --- doc/manual/generate-manpage.nix | 2 +- doc/manual/local.mk | 2 +- doc/manual/utils.nix | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/manual/generate-manpage.nix b/doc/manual/generate-manpage.nix index 02d289eb1..86f2ca567 100644 --- a/doc/manual/generate-manpage.nix +++ b/doc/manual/generate-manpage.nix @@ -137,7 +137,7 @@ let **Settings**: - ${showSettings false settings} + ${showSettings { useAnchors = false; } settings} ''; in concatStrings (attrValues (mapAttrs showStore cliDump.stores)); diff --git a/doc/manual/local.mk b/doc/manual/local.mk index 8bf89b408..82c9a87a7 100644 --- a/doc/manual/local.mk +++ b/doc/manual/local.mk @@ -66,7 +66,7 @@ $(d)/src/command-ref/new-cli: $(d)/nix.json $(d)/generate-manpage.nix $(bindir)/ $(d)/src/command-ref/conf-file.md: $(d)/conf-file.json $(d)/utils.nix $(d)/src/command-ref/conf-file-prefix.md $(bindir)/nix @cat doc/manual/src/command-ref/conf-file-prefix.md > $@.tmp - $(trace-gen) $(nix-eval) --expr '(import doc/manual/utils.nix).showSettings true (builtins.fromJSON (builtins.readFile $<))' >> $@.tmp; + $(trace-gen) $(nix-eval) --expr '(import doc/manual/utils.nix).showSettings { useAnchors = true; } (builtins.fromJSON (builtins.readFile $<))' >> $@.tmp; @mv $@.tmp $@ $(d)/nix.json: $(bindir)/nix diff --git a/doc/manual/utils.nix b/doc/manual/utils.nix index a0e5cf1d1..c0f2e956c 100644 --- a/doc/manual/utils.nix +++ b/doc/manual/utils.nix @@ -39,7 +39,7 @@ rec { filterAttrs = pred: set: listToAttrs (concatMap (name: let v = set.${name}; in if pred name v then [(nameValuePair name v)] else []) (attrNames set)); - showSetting = useAnchors: name: { description, documentDefault, defaultValue, aliases, ... }: + showSetting = { useAnchors }: name: { description, documentDefault, defaultValue, aliases, ... }: let result = squash '' - ${if useAnchors @@ -79,5 +79,5 @@ rec { in result; - showSettings = useAnchors: settingsInfo: concatStrings (attrValues (mapAttrs (showSetting useAnchors) settingsInfo)); + showSettings = args: settingsInfo: concatStrings (attrValues (mapAttrs (showSetting args) settingsInfo)); } From 4d31618c15ea648fa89b6e1c21d50f6c329f160d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Mar 2023 10:09:25 +0100 Subject: [PATCH 12/18] showSetting: Drop ... --- doc/manual/utils.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/manual/utils.nix b/doc/manual/utils.nix index c0f2e956c..5eacce0dd 100644 --- a/doc/manual/utils.nix +++ b/doc/manual/utils.nix @@ -39,7 +39,7 @@ rec { filterAttrs = pred: set: listToAttrs (concatMap (name: let v = set.${name}; in if pred name v then [(nameValuePair name v)] else []) (attrNames set)); - showSetting = { useAnchors }: name: { description, documentDefault, defaultValue, aliases, ... }: + showSetting = { useAnchors }: name: { description, documentDefault, defaultValue, aliases, value }: let result = squash '' - ${if useAnchors From abc449bc30bd0c8e2aaaa7840e83237729e9af19 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Mar 2023 10:12:57 +0100 Subject: [PATCH 13/18] Update src/libstore/local-store.md Co-authored-by: Valentin Gagarin --- src/libstore/local-store.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstore/local-store.md b/src/libstore/local-store.md index 893457d32..580cf5358 100644 --- a/src/libstore/local-store.md +++ b/src/libstore/local-store.md @@ -13,7 +13,7 @@ A store that uses a *root* other than `/` is called a *chroot store*. With such stores, the store directory is "logically" still `/nix/store`, so programs stored in them can only be built and executed by `chroot`-ing into *root*. Chroot stores only support -building and running on Linux when mount and user namespaces are +building and running on Linux when [`mount namespaces`](https://man7.org/linux/man-pages/man7/mount_namespaces.7.html) and [`user namespaces`](https://man7.org/linux/man-pages/man7/user_namespaces.7.html) are enabled. For example, the following uses `/tmp/root` as the chroot environment From 05d9918a9ce83b5881a32d3b8e1dd4ef596f995f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Mar 2023 10:13:51 +0100 Subject: [PATCH 14/18] Update doc/manual/src/release-notes/rl-next.md Co-authored-by: Valentin Gagarin --- doc/manual/src/release-notes/rl-next.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/manual/src/release-notes/rl-next.md b/doc/manual/src/release-notes/rl-next.md index 3e6bfe3e0..90a7891f7 100644 --- a/doc/manual/src/release-notes/rl-next.md +++ b/doc/manual/src/release-notes/rl-next.md @@ -28,4 +28,4 @@ ``` provides information about each of its outputs. -* The command `nix describe-stores` has been removed. +* The experimental command `nix describe-stores` has been removed. From 161f4b0dea82bdaed7cf8928e523702f61cf899b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Mar 2023 10:38:48 +0100 Subject: [PATCH 15/18] Document store URLs --- src/libcmd/common-eval-args.cc | 6 +++++- src/libstore/globals.hh | 12 +++++++---- src/nix/help-stores.md | 37 +++++++++++++++++++++++++++++++++- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/libcmd/common-eval-args.cc b/src/libcmd/common-eval-args.cc index 908127b4d..166b8aaa9 100644 --- a/src/libcmd/common-eval-args.cc +++ b/src/libcmd/common-eval-args.cc @@ -136,7 +136,11 @@ MixEvalArgs::MixEvalArgs() addFlag({ .longName = "eval-store", - .description = "The Nix store to use for evaluations.", + .description = + R"( + The [URL of the Nix store](@docroot@/command-ref/new-cli/nix3-help-stores.md#store-url-format) + to use for evaluation, i.e. to store derivations (`.drv` files) and inputs referenced by them. + )", .category = category, .labels = {"store-url"}, .handler = {&evalStoreUrl}, diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index 4382d1b85..a74d5a46d 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -98,7 +98,9 @@ public: Setting storeUri{this, getEnv("NIX_REMOTE").value_or("auto"), "store", R"( - The URL of the Nix store to use. See [`nix help-stores`](@docroot@/command-ref/new-cli/nix3-help-stores.md) + The [URL of the Nix store](@docroot@/command-ref/new-cli/nix3-help-stores.md#store-url-format) + to use for most operations. + See [`nix help-stores`](@docroot@/command-ref/new-cli/nix3-help-stores.md) for supported store types and settings. )"}; @@ -681,8 +683,9 @@ public: Strings{"https://cache.nixos.org/"}, "substituters", R"( - A list of URLs of substituters, separated by whitespace. Substituters - are tried based on their Priority value, which each substituter can set + A list of [URLs of Nix stores](@docroot@/command-ref/new-cli/nix3-help-stores.md#store-url-format) + to be used as substituters, separated by whitespace. + Substituters are tried based on their Priority value, which each substituter can set independently. Lower value means higher priority. The default is `https://cache.nixos.org`, with a Priority of 40. @@ -700,7 +703,8 @@ public: Setting trustedSubstituters{ this, {}, "trusted-substituters", R"( - A list of URLs of substituters, separated by whitespace. These are + A list of [URLs of Nix stores](@docroot@/command-ref/new-cli/nix3-help-stores.md#store-url-format), + separated by whitespace. These are not used by default, but can be enabled by users of the Nix daemon by specifying `--option substituters urls` on the command line. Unprivileged users are only allowed to pass a subset of the diff --git a/src/nix/help-stores.md b/src/nix/help-stores.md index 8f872cb79..aa381393b 100644 --- a/src/nix/help-stores.md +++ b/src/nix/help-stores.md @@ -4,7 +4,42 @@ Nix supports different types of stores. These are described below. ## Store URL format -TODO +Stores are specified using a URL-like syntax. For example, the command + +```console +# nix path-info --store https://cache.nixos.org/ --json \ + /nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1 +``` + +fetches information about a store path in the HTTP binary cache +located at https://cache.nixos.org/, which is a type of store. + +Store URLs can specify **store settings** using URL query strings, +i.e. by appending `?name1=value1&name2=value2&...` to the URL. For +instance, + +``` +--store ssh://machine.example.org?ssh-key=/path/to/my/key +``` + +tells Nix to access the store on a remote machine via the SSH +protocol, using `/path/to/my/key` as the SSH private key. The +supported settings for each store type are documented below. + +The special store URL `auto` causes Nix to automatically select a +store as follows: + +* Use the local store `/nix/store` if `/nix/var/nix` is writable by + the current user. + +* Otherwise, if `/nix/var/nix/daemon-socket/socket` exists, [connect + to the Nix daemon listening on that socket](#local-daemon-store). + +* Otherwise, on Linux only, use the local chroot store + `~/.local/share/nix/root`, which will be created automatically if it + does not exist. + +* Otherwise, use the local store `/nix/store`. @stores@ From b79df9dedce957e083870d72e649262b5a8893a7 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Mar 2023 15:23:13 +0100 Subject: [PATCH 16/18] Register LocalStore to ensure it's included in the manual --- src/libstore/local-store.cc | 8 ++++++++ src/libstore/local-store.hh | 4 ++++ src/libstore/uds-remote-store.cc | 6 +++--- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 1eada7cc3..22a5dd8f5 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -420,6 +420,13 @@ LocalStore::LocalStore(const Params & params) } +LocalStore::LocalStore(std::string scheme, std::string path, const Params & params) + : LocalStore(params) +{ + throw UnimplementedError("LocalStore"); +} + + AutoCloseFD LocalStore::openGCLock() { Path fnGCLock = stateDir + "/gc.lock"; @@ -1957,5 +1964,6 @@ std::optional LocalStore::getVersion() return nixVersion; } +static RegisterStoreImplementation regLocalStore; } // namespace nix diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index 3743f6b10..639772b36 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -102,9 +102,13 @@ public: /* Initialise the local store, upgrading the schema if necessary. */ LocalStore(const Params & params); + LocalStore(std::string scheme, std::string path, const Params & params); ~LocalStore(); + static std::set uriSchemes() + { return {}; } + /* Implementations of abstract store API methods. */ std::string getUri() override; diff --git a/src/libstore/uds-remote-store.cc b/src/libstore/uds-remote-store.cc index 5c38323cd..0fb7c38e9 100644 --- a/src/libstore/uds-remote-store.cc +++ b/src/libstore/uds-remote-store.cc @@ -26,9 +26,9 @@ UDSRemoteStore::UDSRemoteStore(const Params & params) UDSRemoteStore::UDSRemoteStore( - const std::string scheme, - std::string socket_path, - const Params & params) + const std::string scheme, + std::string socket_path, + const Params & params) : UDSRemoteStore(params) { path.emplace(socket_path); From 7a61a9aba3154de7b18b6f83161149800625d3d4 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Mar 2023 15:27:06 +0100 Subject: [PATCH 17/18] Update release notes --- doc/manual/src/release-notes/rl-next.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/manual/src/release-notes/rl-next.md b/doc/manual/src/release-notes/rl-next.md index 90a7891f7..ac5a34dfc 100644 --- a/doc/manual/src/release-notes/rl-next.md +++ b/doc/manual/src/release-notes/rl-next.md @@ -29,3 +29,5 @@ provides information about each of its outputs. * The experimental command `nix describe-stores` has been removed. + +* Nix stores and their settings are now documented in [`nix help-stores`](@docroot@/command-ref/new-cli/nix3-help-stores.md). From 168b6021c558f317fc01b142c1610742e9b9096b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Mar 2023 15:32:59 +0100 Subject: [PATCH 18/18] Tweaks --- src/libstore/local-store.md | 9 ++++----- src/nix/help-stores.md | 8 ++++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/libstore/local-store.md b/src/libstore/local-store.md index 580cf5358..8174df839 100644 --- a/src/libstore/local-store.md +++ b/src/libstore/local-store.md @@ -3,11 +3,10 @@ R"( **Store URL format**: `local`, *root* This store type accesses a Nix store in the local filesystem directly -(i.e. not via the Nix daemon). *root* is an absolute path that denotes -the "root" of the filesystem; other directories such as the Nix store -directory (as denoted by the `store` setting) are interpreted relative -to *root*. The store pseudo-URL `local` denotes a store that uses `/` -as its root directory. +(i.e. not via the Nix daemon). *root* is an absolute path that is +prefixed to other directories such as the Nix store directory. The +store pseudo-URL `local` denotes a store that uses `/` as its root +directory. A store that uses a *root* other than `/` is called a *chroot store*. With such stores, the store directory is "logically" still diff --git a/src/nix/help-stores.md b/src/nix/help-stores.md index aa381393b..47ba9b94d 100644 --- a/src/nix/help-stores.md +++ b/src/nix/help-stores.md @@ -29,17 +29,17 @@ supported settings for each store type are documented below. The special store URL `auto` causes Nix to automatically select a store as follows: -* Use the local store `/nix/store` if `/nix/var/nix` is writable by - the current user. +* Use the [local store](#local-store) `/nix/store` if `/nix/var/nix` + is writable by the current user. * Otherwise, if `/nix/var/nix/daemon-socket/socket` exists, [connect to the Nix daemon listening on that socket](#local-daemon-store). -* Otherwise, on Linux only, use the local chroot store +* Otherwise, on Linux only, use the [local chroot store](#local-store) `~/.local/share/nix/root`, which will be created automatically if it does not exist. -* Otherwise, use the local store `/nix/store`. +* Otherwise, use the [local store](#local-store) `/nix/store`. @stores@