diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc index e83ec2479..6cc933069 100644 --- a/src/libcmd/command.cc +++ b/src/libcmd/command.cc @@ -75,7 +75,7 @@ ref StoreConfigCommand::getStoreConfig() ref StoreConfigCommand::createStoreConfig() { - return resolveStoreConfig(StoreReference::parse(settings.storeUri.get())); + return resolveStoreConfig(StoreReference{settings.storeUri.get()}); } void StoreConfigCommand::run() diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index 527a88c13..da13405f0 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -253,7 +253,7 @@ LegacyArgs::LegacyArgs( .longName = "store", .description = "The URL of the Nix store to use.", .labels = {"store-uri"}, - .handler = {&(std::string &) settings.storeUri}, + .handler = {[](std::string s) { settings.storeUri = StoreReference::parse(s); }}, }); } diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc index 97838999c..e26df204d 100644 --- a/src/libstore/daemon.cc +++ b/src/libstore/daemon.cc @@ -246,25 +246,36 @@ struct ClientSettings auto & name(i.first); auto & value(i.second); - auto setSubstituters = [&](Setting & res) { + auto setSubstituters = [&](Setting> & res) { if (name != res.name && res.aliases.count(name) == 0) return false; - StringSet trusted = settings.trustedSubstituters; - for (auto & s : settings.substituters.get()) - trusted.insert(s); - Strings subs; + std::set trusted = settings.trustedSubstituters; + for (auto & ref : settings.substituters.get()) + trusted.insert(ref); + std::vector subs; auto ss = tokenizeString(value); - for (auto & s : ss) - if (trusted.count(s)) - subs.push_back(s); - else if (!hasSuffix(s, "/") && trusted.count(s + "/")) - subs.push_back(s + "/"); + for (auto & s : ss) { + auto ref = StoreReference::parse(s); + auto tryTrust = [&] { + if (trusted.count(ref)) + return true; + if (auto * specified = std::get_if(&ref.variant); + specified && !hasSuffix(specified->authority, "/")) { + specified->authority += "/"; + if (trusted.count(ref)) + return true; + } + return false; + }; + if (tryTrust()) + subs.push_back(std::move(ref)); else warn( "ignoring untrusted substituter '%s', you are not a trusted user.\n" "Run `man nix.conf` for more information on the `substituters` configuration option.", s); - res = subs; + } + res = std::move(subs); return true; }; diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index 695e512f6..1c2f6a778 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -1,4 +1,5 @@ #include "nix/store/globals.hh" +#include "nix/util/config-impl.hh" #include "nix/util/config-global.hh" #include "nix/util/current-process.hh" #include "nix/util/archive.hh" @@ -449,6 +450,88 @@ void BaseSetting::appendOrSet(PathsInChroot newValue, bool append value.insert(std::make_move_iterator(newValue.begin()), std::make_move_iterator(newValue.end())); } +template<> +struct BaseSetting>::trait +{ + static constexpr bool appendable = true; +}; + +template<> +struct BaseSetting>::trait +{ + static constexpr bool appendable = true; +}; + +template<> +StoreReference BaseSetting::parse(const std::string & str) const +{ + return StoreReference::parse(str); +} + +template<> +std::string BaseSetting::to_string() const +{ + return value.render(); +} + +template<> +std::vector BaseSetting>::parse(const std::string & str) const +{ + std::vector res; + for (const auto & s : tokenizeString(str)) + res.push_back(StoreReference::parse(s)); + return res; +} + +template<> +std::string BaseSetting>::to_string() const +{ + Strings ss; + for (const auto & ref : value) + ss.push_back(ref.render()); + return concatStringsSep(" ", ss); +} + +template<> +void BaseSetting>::appendOrSet(std::vector newValue, bool append) +{ + if (append) + value.insert(value.end(), std::make_move_iterator(newValue.begin()), std::make_move_iterator(newValue.end())); + else + value = std::move(newValue); +} + +template<> +std::set BaseSetting>::parse(const std::string & str) const +{ + std::set res; + for (const auto & s : tokenizeString(str)) + res.insert(StoreReference::parse(s)); + return res; +} + +template<> +std::string BaseSetting>::to_string() const +{ + Strings ss; + for (const auto & ref : value) + ss.push_back(ref.render()); + return concatStringsSep(" ", ss); +} + +template<> +void BaseSetting>::appendOrSet(std::set newValue, bool append) +{ + if (append) + value.insert(std::make_move_iterator(newValue.begin()), std::make_move_iterator(newValue.end())); + else + value = std::move(newValue); +} + +template class BaseSetting; +template class BaseSetting>; +template class BaseSetting>; + static void preloadNSS() { /* builtin:fetchurl can trigger a DNS lookup, which with glibc can trigger a dynamic library load of diff --git a/src/libstore/include/nix/store/globals.hh b/src/libstore/include/nix/store/globals.hh index 590887d08..5d3e4a3fa 100644 --- a/src/libstore/include/nix/store/globals.hh +++ b/src/libstore/include/nix/store/globals.hh @@ -8,6 +8,7 @@ #include "nix/util/environment-variables.hh" #include "nix/store/build/derivation-builder.hh" #include "nix/store/local-settings.hh" +#include "nix/store/store-reference.hh" #include "nix/store/config.hh" @@ -133,9 +134,9 @@ public: */ std::filesystem::path nixDaemonSocketFile; - Setting storeUri{ + Setting storeUri{ this, - getEnv("NIX_REMOTE").value_or("auto"), + StoreReference::parse(getEnv("NIX_REMOTE").value_or("auto")), "store", R"( The [URL of the Nix store](@docroot@/store/types/index.md#store-url-format) @@ -616,9 +617,9 @@ public: // Don't document the machine-specific default value false}; - Setting substituters{ + Setting> substituters{ this, - Strings{"https://cache.nixos.org/"}, + std::vector{StoreReference::parse("https://cache.nixos.org/")}, "substituters", R"( A list of [URLs of Nix stores](@docroot@/store/types/index.md#store-url-format) to be used as substituters, separated by whitespace. @@ -637,7 +638,7 @@ public: )", {"binary-caches"}}; - Setting trustedSubstituters{ + Setting> trustedSubstituters{ this, {}, "trusted-substituters", diff --git a/src/libstore/include/nix/store/store-reference.hh b/src/libstore/include/nix/store/store-reference.hh index 8c1c63083..b35c27f82 100644 --- a/src/libstore/include/nix/store/store-reference.hh +++ b/src/libstore/include/nix/store/store-reference.hh @@ -4,6 +4,8 @@ #include #include "nix/util/types.hh" +#include "nix/util/json-impls.hh" +#include "nix/util/json-non-null.hh" namespace nix { @@ -121,4 +123,10 @@ static inline std::ostream & operator<<(std::ostream & os, const StoreReference */ std::pair splitUriAndParams(const std::string & uri); +template<> +struct json_avoids_null : std::true_type +{}; + } // namespace nix + +JSON_IMPL(StoreReference) diff --git a/src/libstore/store-reference.cc b/src/libstore/store-reference.cc index 01e197be7..e26caede0 100644 --- a/src/libstore/store-reference.cc +++ b/src/libstore/store-reference.cc @@ -6,6 +6,7 @@ #include "nix/util/util.hh" #include +#include namespace nix { @@ -184,3 +185,19 @@ std::pair splitUriAndParams(const std::stri } } // namespace nix + +namespace nlohmann { + +using namespace nix; + +StoreReference adl_serializer::from_json(const json & json) +{ + return StoreReference::parse(json.get()); +} + +void adl_serializer::to_json(json & json, const StoreReference & ref) +{ + json = ref.render(); +} + +} // namespace nlohmann diff --git a/src/libstore/store-registration.cc b/src/libstore/store-registration.cc index 3b0b2deaf..13bcec9cb 100644 --- a/src/libstore/store-registration.cc +++ b/src/libstore/store-registration.cc @@ -8,7 +8,7 @@ namespace nix { ref openStore() { - return openStore(settings.storeUri.get()); + return openStore(StoreReference{settings.storeUri.get()}); } ref openStore(const std::string & uri, const Store::Config::Params & extraParams) @@ -79,20 +79,20 @@ std::list> getDefaultSubstituters() static auto stores([]() { std::list> stores; - StringSet done; + std::set done; - auto addStore = [&](const std::string & uri) { - if (!done.insert(uri).second) + auto addStore = [&](const StoreReference & ref) { + if (!done.insert(ref).second) return; try { - stores.push_back(openStore(uri)); + stores.push_back(openStore(StoreReference{ref})); } catch (Error & e) { logWarning(e.info()); } }; - for (const auto & uri : settings.substituters.get()) - addStore(uri); + for (const auto & ref : settings.substituters.get()) + addStore(ref); stores.sort([](ref & a, ref & b) { return a->config.priority < b->config.priority; }); diff --git a/src/nix/unix/daemon.cc b/src/nix/unix/daemon.cc index 842219ddb..7fce2e8f6 100644 --- a/src/nix/unix/daemon.cc +++ b/src/nix/unix/daemon.cc @@ -457,7 +457,7 @@ static int main_nix_daemon(int argc, char ** argv) return true; }); - runDaemon(resolveStoreConfig(StoreReference::parse(settings.storeUri.get())), stdio, isTrustedOpt, processOps); + runDaemon(resolveStoreConfig(StoreReference{settings.storeUri.get()}), stdio, isTrustedOpt, processOps); return 0; }