Merge pull request #15192 from obsidiansystems/store-reference-types

globals: change store settings to use `StoreReference` types directly
This commit is contained in:
John Ericson
2026-02-11 17:49:07 +00:00
committed by GitHub
9 changed files with 146 additions and 26 deletions

View File

@@ -75,7 +75,7 @@ ref<StoreConfig> StoreConfigCommand::getStoreConfig()
ref<StoreConfig> StoreConfigCommand::createStoreConfig()
{
return resolveStoreConfig(StoreReference::parse(settings.storeUri.get()));
return resolveStoreConfig(StoreReference{settings.storeUri.get()});
}
void StoreConfigCommand::run()

View File

@@ -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); }},
});
}

View File

@@ -246,25 +246,36 @@ struct ClientSettings
auto & name(i.first);
auto & value(i.second);
auto setSubstituters = [&](Setting<Strings> & res) {
auto setSubstituters = [&](Setting<std::vector<StoreReference>> & 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<StoreReference> trusted = settings.trustedSubstituters;
for (auto & ref : settings.substituters.get())
trusted.insert(ref);
std::vector<StoreReference> subs;
auto ss = tokenizeString<Strings>(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<StoreReference::Specified>(&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;
};

View File

@@ -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<PathsInChroot>::appendOrSet(PathsInChroot newValue, bool append
value.insert(std::make_move_iterator(newValue.begin()), std::make_move_iterator(newValue.end()));
}
template<>
struct BaseSetting<std::vector<StoreReference>>::trait
{
static constexpr bool appendable = true;
};
template<>
struct BaseSetting<std::set<StoreReference>>::trait
{
static constexpr bool appendable = true;
};
template<>
StoreReference BaseSetting<StoreReference>::parse(const std::string & str) const
{
return StoreReference::parse(str);
}
template<>
std::string BaseSetting<StoreReference>::to_string() const
{
return value.render();
}
template<>
std::vector<StoreReference> BaseSetting<std::vector<StoreReference>>::parse(const std::string & str) const
{
std::vector<StoreReference> res;
for (const auto & s : tokenizeString<Strings>(str))
res.push_back(StoreReference::parse(s));
return res;
}
template<>
std::string BaseSetting<std::vector<StoreReference>>::to_string() const
{
Strings ss;
for (const auto & ref : value)
ss.push_back(ref.render());
return concatStringsSep(" ", ss);
}
template<>
void BaseSetting<std::vector<StoreReference>>::appendOrSet(std::vector<StoreReference> 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<StoreReference> BaseSetting<std::set<StoreReference>>::parse(const std::string & str) const
{
std::set<StoreReference> res;
for (const auto & s : tokenizeString<Strings>(str))
res.insert(StoreReference::parse(s));
return res;
}
template<>
std::string BaseSetting<std::set<StoreReference>>::to_string() const
{
Strings ss;
for (const auto & ref : value)
ss.push_back(ref.render());
return concatStringsSep(" ", ss);
}
template<>
void BaseSetting<std::set<StoreReference>>::appendOrSet(std::set<StoreReference> 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<StoreReference>;
template class BaseSetting<std::vector<StoreReference>>;
template class BaseSetting<std::set<StoreReference>>;
static void preloadNSS()
{
/* builtin:fetchurl can trigger a DNS lookup, which with glibc can trigger a dynamic library load of

View File

@@ -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<std::string> storeUri{
Setting<StoreReference> 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<Strings> substituters{
Setting<std::vector<StoreReference>> substituters{
this,
Strings{"https://cache.nixos.org/"},
std::vector<StoreReference>{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<StringSet> trustedSubstituters{
Setting<std::set<StoreReference>> trustedSubstituters{
this,
{},
"trusted-substituters",

View File

@@ -4,6 +4,8 @@
#include <variant>
#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<std::string, StoreReference::Params> splitUriAndParams(const std::string & uri);
template<>
struct json_avoids_null<StoreReference> : std::true_type
{};
} // namespace nix
JSON_IMPL(StoreReference)

View File

@@ -6,6 +6,7 @@
#include "nix/util/util.hh"
#include <boost/url/ipv6_address.hpp>
#include <nlohmann/json.hpp>
namespace nix {
@@ -184,3 +185,19 @@ std::pair<std::string, StoreReference::Params> splitUriAndParams(const std::stri
}
} // namespace nix
namespace nlohmann {
using namespace nix;
StoreReference adl_serializer<StoreReference>::from_json(const json & json)
{
return StoreReference::parse(json.get<std::string>());
}
void adl_serializer<StoreReference>::to_json(json & json, const StoreReference & ref)
{
json = ref.render();
}
} // namespace nlohmann

View File

@@ -8,7 +8,7 @@ namespace nix {
ref<Store> openStore()
{
return openStore(settings.storeUri.get());
return openStore(StoreReference{settings.storeUri.get()});
}
ref<Store> openStore(const std::string & uri, const Store::Config::Params & extraParams)
@@ -79,20 +79,20 @@ std::list<ref<Store>> getDefaultSubstituters()
static auto stores([]() {
std::list<ref<Store>> stores;
StringSet done;
std::set<StoreReference> 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<Store> & a, ref<Store> & b) { return a->config.priority < b->config.priority; });

View File

@@ -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;
}