Decouple the internal Config
Go struct from the user config file in .ipfs/conf
: use a subset of user overrides instead
#8925
Labels
Milestone
This issue is about fixing our internal technical debt without changing external UX. Some internal APIs will need to be broken but that can be minimized in a progressive deployment.
Problem
We currently map the JSON data of the user configuration file (UCF) in
.ipfs/conf
to our internalConfig
Go struct. This brings many problems:Config
struct in the UCF we end up relying on stopgaps like thejson:",omitempty"
option, but that ends up creating even more confusion as it only just hides the underlying coupling that remains between these two sources of configuration.The last point in turn has given rise to "optional" variables,
OptionalInteger
and related, to handle the JSON-GO mismatch of unspecified configuration options with the following drawbacks:Flag
,Strings
,Priority
,OptionalDuration
,OptionalInteger
,OptionalString
, and the list just keeps growing.WithDefault()
API scatters system default values in the places that access these values, instead of centralizing them in theconfig
package where they are defined. These system defaults end up hard-coded deep in the code base, or we flat-out copy an external default structure field by field like:https://github.com/ipfs/go-ipfs/blob/7162a63e9629258bac0b9d135acae4c3c1b9fb33/core/node/libp2p/relay.go#L28-L40
(Looking at the above list now, it seems like the copy/paste used to write the last 4 lines left the text
relayOpts.MaxReservations
untouched without adding thePerPeer
,PerIP
, andPerASN
suffixes needed. This is a perfect example of the motivation for fixing technical debt like this one.)Proposed solution
We should clearly differentiate the two sources of configuration:
System configuration: what the
go-ipfs
node is running with, encoded in aConfig
Go struct. It defaults to an internal set of values that depend on the node version.User overrides: Stored in
.ipfs/conf
, contains a JSON map of a subset of the configuration options the user wants to impose over the system defaults.The user overrides are not the JSON-serialized version of the system configuration. We should not leak Go implementation details; for the user the only thing that exists is the JSON file (only internally do we use the
Config
struct to validate if those attributes are actually system-defined configuration options).When the node starts it should load the
Config
with its internally-defined default values and only change the options specified in the user overrides, nothing else. The user overrides.ipfs/conf
should be a bare-bones file afteripfs init
.All that is currently hard-coded in the
.ipfs/conf
file because of the exposure through the direct serialization of theConfig
struct, which at the moment is slowly and painfully being hidden through the cumbersome "optional" variables, will remain only in theConfig
struct as system-defined defaults (subject to change with the release version).With this decoupling there is no more ambiguity on unspecified user options in the
.ipfs/conf
file since all options will be set in the internalConfig
struct: an option the user doesn't specify just leaves in place the system default (no morejson:",omitempty"
).Implementation
The progressive road to implementation is illustrated in this branch. The
Repo
interface is mostly maintained, what changes is that theConfig
struct (and related API calls) is no longer just the serialized user JSON file but instead the merge between the system defaults and JSON overrides (which are never serialized directly into theConfig
struct). The main objective of the first iteration is identifying which API consumers were relying on having all the configuration stored in the JSON file and start clearly differentiating between the user overrides and the internal system defaults: we should eliminate as much as possible the expectation of a user configuration (as it now exists) that contains all the configuration needed to run the node.The text was updated successfully, but these errors were encountered: