ipfs / kubo

An IPFS implementation in Go
https://docs.ipfs.tech/how-to/command-line-quick-start/
Other
16.17k stars 3.02k forks source link

config: defaults difficult to update #8776

Open aschmahmann opened 5 years ago

aschmahmann commented 5 years ago

As it currently stands it's pretty difficult to change default behavior of clients since the bulk of the configuration is done during the initialization of the repo. A few examples:

1) Want to have a value default to true, but because we use an empty go struct to define the config it defaults to false (forces us to have config names like DisableSigning instead of EnableSigning. (e.g. https://github.com/ipfs/go-ipfs/issues/6621#issuecomment-527968044)

2) Want to remove old bootstrap peers and replace them with new ones

3) Want to change the default pubsub router from floodsub to gossipsub in the same place all the configs are defined (instead of defining the default as empty string "", and changing ipfs constructor code to reinterpret "" as gossipsub instead of floodsub.

Idea: Let's define defaults programmatically, and use the config files to add user preferences.

Defaults being defined programmatically solves problem 1 and makes defining default values easy (solves part of problem 3). Solving problem 2 and the rest of problem 3 is more complicated though.

A few options to consider:

1) Create a default Config struct that we use as a base when reading in config files, and continue to write the entire config file to disk.

2) Whenever we write a config file, cfg to disk calculate the difference cfg - defaultCfg and write that instead.

3) Create a copy-on-write style config object where the net config object is the defaults + what's read from disk

My plan is to start on option 1 because it gives us the most utility for the least work. However, I'd like to talk about options 2 and 3.

Thoughts @Stebalien @magik6k

daviddias commented 5 years ago

Ideally, this would be in sync with js-ipfs. In js-ipfs there is a sequence in which the final config is set. It is done by:

cli args (if through daemon) > env variables > options passed on node constructor > new config passed on the constructor > default config.json

The new config passed on the constructor is merged with the default config (so you only need to pass the values you want to change/augment) https://github.com/ipfs/js-ipfs#optionsconfig

aschmahmann commented 5 years ago

@daviddias how does that deal with IPFS CLI commands that set one key in the config file? go-ipfs loads the config file, sets the key, then writes the entire config (which could include default options) back. This approach makes it difficult to deal with updating defaults.

Stebalien commented 4 years ago

I'd go with 3, actually, and I don't think it'll be a problem.

  1. Reading the config isn't an issue. The "config" object we expose can include the defaults.
  2. When writing the config, we usually call special setter functions anyways.