-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New store settings system #11139
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
New store settings system #11139
Conversation
@L-as I think I need to UBSAN, because the store unit tests are failing for what looks like a random variable corruption. |
We should just enable it by default, but it causes some weird test failures. |
I don't really get the motivation for this change (another massive refactoring PR, which I assume will be followed by an even bigger change when this gets applied to the main settings). #10766 doesn't really give a motivation other than "we always go directly from a StoreReference to the Store data type directly" which is apparently a bad thing. #11106 mentions support for structured settings, but I don't see why that requires completely replacing the current This PR scatters the settings mechanism for a class like I don't really like types like:
We should really keep the template metaprogramming to a minimum! Again for readability, this is not great since looking at this code, the reader has no idea what |
I believe it's quite valuable in this situation, and not all that confusing when documented properly. For this we can make use of the language server. (not using one is cruel anyway) Example: diff --git a/src/libstore/binary-cache-store.hh b/src/libstore/binary-cache-store.hh
index af649aaab..a638248c5 100644
--- a/src/libstore/binary-cache-store.hh
+++ b/src/libstore/binary-cache-store.hh
@@ -13,6 +13,7 @@ namespace nix {
struct NarInfo;
+/** @param T Either 'nix::config::JustValue' or `nix::config::SettingInfo` */
template<template<typename> class F>
struct BinaryCacheStoreConfigT
{
diff --git a/src/libutil/config-abstract.hh b/src/libutil/config-abstract.hh
index 2c34ff50b..e7f71e700 100644
--- a/src/libutil/config-abstract.hh
+++ b/src/libutil/config-abstract.hh
@@ -5,6 +5,9 @@
namespace nix::config {
+/**
+ * Just a value, no metadata. explain explain
+ */
template<typename T>
struct JustValue
{ With docs in these positions, readers can easily navigate to the explanations in the two relevant types that instantiate the fields. Note also that when hovering over a |
ede1c2b
to
6ba8c57
Compare
382f994
to
38b376c
Compare
If the Linux tests fail again, I think it might something to do with UBSan? I'll need to figure out how to run that locally. |
9511fe1
to
668c465
Compare
Yay, fixed the UBSAN issues! |
static const std::string name() { return "Local Daemon Store"; } | ||
|
||
std::string doc() override; | ||
static std::string doc(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Downgrade to constants?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We I think we could, but I am tempted to do in a separate commit since this one is already so big. How does that sound?
} catch (nlohmann::json::exception &) { | ||
// if its not valid JSON... | ||
if (k == "remote-program" || k == "system-features") { | ||
// Back compat hack! Split and take that array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we not do hacks? Presumably this needs to be part of the non-JSON parsing logic only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am trying to allow query parameters to also be JSON, however. For example, I made it so ssh://localhost?remote-program=["nix","store","--serve"]
works (provided one does enough HTML %
escaping).
|
||
void adl_serializer<ref<const StoreConfig>>::to_json(json & obj, ref<const StoreConfig> s) | ||
{ | ||
// TODO, for tests maybe |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or nix store show
/info
#include <optional> | ||
|
||
namespace nix::config { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs documentation. I believe this was part of an earlier review.
d146a6e
to
c7a1caa
Compare
6249504
to
1ceada0
Compare
* settings record in order to ensure don't forgot to parse or document | ||
* settings field. | ||
*/ | ||
template<template<typename> class F> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
template<template<typename> class F> | |
template<template<typename> class Mode> |
template<template<typename> class F> | |
template<template<typename> class Container> |
template<template<typename> class F> | |
template<template<typename> class Setting> |
template<template<typename> class F> | |
template<template<typename> class Interpretation> |
between stores if they have the same `store` setting. | ||
)"}; | ||
const Path storeDir = storeDir_; | ||
F<Path> _storeDir; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If use Setting<F, Path> = F<Path>;
works and needs no extra initializer braces:
F<Path> _storeDir; | |
Setting<F, Path> _storeDir; |
#if 0 | ||
/** | ||
* @see SettingInfo::aliases | ||
*/ | ||
std::set<std::string> aliases; | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not very clear why this is if 0
'd out. Is this some placeholder for future work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, to subsume the old configuration system more completely (not just what is in-use for store settings) we would add this stuff also
auto config = make_ref<LocalStore::Config>(*getLocalStore().config); | ||
config->pathInfoCacheSize.value = 0; | ||
config->stateDir.value = "/no-such-path"; | ||
config->logDir.value = "/no-such-path"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be good for readability if PlainValue
overloaded operator=
so that we could just do this:
auto config = make_ref<LocalStore::Config>(*getLocalStore().config); | |
config->pathInfoCacheSize.value = 0; | |
config->stateDir.value = "/no-such-path"; | |
config->logDir.value = "/no-such-path"; | |
auto config = make_ref<LocalStore::Config>(*getLocalStore().config); | |
config->pathInfoCacheSize = 0; | |
config->stateDir = "/no-such-path"; | |
config->logDir = "/no-such-path"; |
Might be worth adding something like:
template <std::convertible_to<T> U>
PlainValue & operator=(U rhs) &
{
value = static_cast<T>(rhs);
return *this;
}
wantMassQuery.setDefault(cacheInfo->wantMassQuery); | ||
priority.setDefault(cacheInfo->priority); | ||
resolvedSubstConfig.wantMassQuery.value = | ||
config->storeConfig.wantMassQuery.optValue.value_or(cacheInfo->wantMassQuery); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is quite a mouthful. Can't we just forward value_or
method to the OptValue
class so that this would work:
config->storeConfig.wantMassQuery.optValue.value_or(cacheInfo->wantMassQuery); | |
config->storeConfig.wantMassQuery.value_or(cacheInfo->wantMassQuery); |
This works:
template<typename T>
struct OptValue : private std::optional<T>
{
private:
using OptBase = std::optional<T>;
public:
OptValue(OptBase opt) : OptBase(std::move(opt)) {}
using OptBase::OptBase;
using OptBase::value_or;
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I can just use std::optional
directly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't really have a strong opinion on this, but that a good example of the Law of Demeter and saves on some typing. But again, not a blocking suggestion in any way.
1ceada0
to
02446fd
Compare
Fix NixOS#10766 See that ticket for details. Progress (I hope!) towards NixOS#11139.
02446fd
to
a4a23a7
Compare
Fix NixOS#10766 See that ticket for details. Progress (I hope!) towards NixOS#11139.
a4a23a7
to
9a01d3b
Compare
Fix NixOS#10766 See that ticket for details. Progress (I hope!) towards NixOS#11139.
9a01d3b
to
48a8c2c
Compare
Fix NixOS#10766 See that ticket for details. Progress (I hope!) towards NixOS#11139. Co-Authored-By: Sergei Zimmerman <[email protected]>
48a8c2c
to
e302ab6
Compare
Fix NixOS#10766 See that ticket for details. Progress (I hope!) towards NixOS#11139. Co-Authored-By: Sergei Zimmerman <[email protected]>
🎉 All dependencies have been resolved ! |
e302ab6
to
2daf1ee
Compare
9b5b2b9
to
2ea9f59
Compare
2ea9f59
to
6c4c845
Compare
Co-authored-by: Sergei Zimmerman <[email protected]>
93f958b
to
c7f126b
Compare
Motivation: See the linked issues for details. The most notable user-relevant bits are: - This cleans up the `MountedSSHStore`: decomposed into its orthogonal parts - This brings us pretty close to being able to then implement a JSON-based config. - Store query parameters can be JSON - Stores can entirely be specified via JSON objects, but this is not yet hooked up to anything. Also behind the scenes have these benefits: 1. The docs are moved out of the headers, good for less rebuilding when they changes 2. Stores are always constructed from store configs 3. Use JSON, avoid custom serializers Context: Part of NixOS#11106 Co-Authored-By: Robert Hensing <[email protected]> Co-authored-by: Sergei Zimmerman <[email protected]>
c7f126b
to
fe8b42d
Compare
Motivation
See the linked issues for details.
The most notable user-relevant bits are:
This cleans up the
MountedSSHStore
: decomposed into its orthogonal partsThis brings us pretty close to being able to then implement a JSON-based config.
Also behind the scenes have these benefits:
Requirements
General requirements for settings:
Other requirements:
nix.conf
can be in JSON, not a custom line oriented formatconfiguration.hh
, there is a huge amount of inheritance. This new system avoids that entirely. Parsing is just a function.StoreReference
) into doing actions to open aStore
in one step.libstore
/libexpr
in the library use-case.Context
Do not review by commits
Part of #11106
Depends on #13154
Priorities and Process
Add 👍 to pull requests you find important.
The Nix maintainer team uses a GitHub project board to schedule and track reviews.