Skip to content

Config file - #2808

Closed
realbigsean wants to merge 46 commits into
sigp:unstablefrom
realbigsean:config-file
Closed

realbigsean wants to merge 46 commits into
sigp:unstablefrom
realbigsean:config-file

Conversation

@realbigsean

@realbigsean realbigsean commented Nov 12, 2021 •

Copy link
Copy Markdown
Member

Issue Addressed

Resolves: #2748

Proposed Changes

Added some docs here with some info, there are a couple of quirks.

  • Upgrade clap to 3.0.4
  • Allows reading from a YAML or TOML config file.
  • CLI arguments take precedence over file arguments if both are provided
  • I added constants for argument keys in order to make it easier to update values in the future. Only for the beacon_node, validator_client, and boot_node subcommands for now though. I sort of needed to do this in order to add a layer of validation to config we load from a file. Using the workaround described below, config values provided from file for the wrong subcommand or that are just entirely foreign would silently fail. So I needed the constants to get an idea of all available flags for each subcommand. Seems like we could use these sets of known flags to generate tests like our existing CLI tests. It's a bit tricky to remember to add to those when adding a new flag.

Additional Info

I was able to figure out how to do this within clap with some workarounds.

  1. Get a copy of all cli args (env::args_os())
  2. Create a cli::App with all of lighthouse's commands and flags.
  3. Consume the initial App (this also consumes cli args) and get back matched arguments
    • this initial consumption has to include all commands and flags in order to properly validate the entire command, in case users want to input overriding CLI flags with the --config-file flag.
  4. Check this first set of matched arguments for the --config-file flag. If it exists, read from the file.
  5. Instantiate a second, nearly identical cli::App instance, but as the args are being set, set an additional default_value equal to the matching file config value. This way lighthouse only uses file config value if the value is not passed in via CLI. If the arg has an existing default_value, the latest set default_value takes precedence, so the file config would take precedence over the lighthouse-defined default. This behavior makes sense to me.

Relevant clap issues

Todo:

  • allow reading from TOML
  • self review

@realbigsean
realbigsean changed the base branch from stable to unstable November 12, 2021 23:09
@realbigsean realbigsean added the work-in-progress PR is a work-in-progress label Nov 12, 2021
@realbigsean realbigsean mentioned this pull request Nov 12, 2021
…nfig-file

� Conflicts:
�	Cargo.lock
�	beacon_node/src/cli.rs
�	boot_node/Cargo.toml
�	boot_node/src/lib.rs
…nfig-file

� Conflicts:
�	Cargo.lock
�	beacon_node/src/cli.rs
�	boot_node/src/config.rs
�	boot_node/src/lib.rs
�	common/clap_utils/Cargo.toml
�	lcli/src/main.rs
�	lighthouse/src/main.rs
�	validator_client/Cargo.toml
Comment thread beacon_node/src/cli.rs

Ok(App::new("beacon_node", file_args)
.visible_aliases(&["b", "bn", "beacon"])
.version(crate_version!())

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is no longer available in clap do we want an alternative? I didn't think crate-level versions seemed really relevant

Comment thread beacon_node/src/cli.rs
.visible_aliases(&["b", "bn", "beacon"])
.version(crate_version!())
.author("Sigma Prime <contact@sigmaprime.io>")
.setting(clap::AppSettings::ColoredHelp)

@realbigsean realbigsean Jan 6, 2022 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed this because this is now the default setting

@realbigsean realbigsean added ready-for-review The code is ready for review and removed work-in-progress PR is a work-in-progress labels Jan 6, 2022

@pawanjay176 pawanjay176 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested this out manually with different combinations of cli and config file parameters and it works as expected :)

I wasn't super happy about parsing the parameters twice, but couldn't come up with anything substantively better after spending quite a lot of time with clap.

Another potential design is to use the clap derive feature to create Config structs.
I have a small self-contained example here. The example parses a Config struct which derives clap::Parser and then updates it with additional parameters from the config file.
https://gist.github.com/pawanjay176/0239b7bb80c2244a60216523654df92c

The derive feature seems to contain everything we currently have and is a bit cleaner than the App::new().arg(...) type builder pattern imo. I haven't fully checked if this pattern would give us further issues when used with subcommands, but seems like it should work fine. It would be a substantial refactor though.

Comment thread common/clap_utils/src/lib.rs Outdated
.map(toml_value_to_string)
.collect::<Result<Vec<_>, _>>()?
.join(","),
TomlValue::Table(_) => return Err("Unable to parse YAML table".to_string()),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
TomlValue::Table(_) => return Err("Unable to parse YAML table".to_string()),
TomlValue::Table(_) => return Err("Unable to parse TOML table".to_string()),

Comment thread common/clap_utils/src/lib.rs Outdated
.map(yaml_value_to_string)
.collect::<Result<Vec<_>, _>>()?
.join(","),
YamlValue::Mapping(_) => return Err("Unable to parse TOML table".to_string()),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
YamlValue::Mapping(_) => return Err("Unable to parse TOML table".to_string()),
YamlValue::Mapping(_) => return Err("Unable to parse YAML table".to_string()),

Comment thread book/src/file-config.md Outdated
```
Would be equivalent to this YAML config:
```bash
$ lighthouse --config-file ./beacon-config.yaml

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$ lighthouse --config-file ./beacon-config.yaml
$ lighthouse beacon_node --config-file ./beacon-config.yaml

Comment thread book/src/file-config.md Outdated
```
And this TOML config:
```bash
$ lighthouse --config-file ./beacon-config.toml

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$ lighthouse --config-file ./beacon-config.toml
$ lighthouse beacon_node --config-file ./beacon-config.toml

realbigsean and others added 13 commits January 20, 2022 10:14
Co-authored-by: Divma <26765164+divagant-martian@users.noreply.github.com>
Co-authored-by: Divma <26765164+divagant-martian@users.noreply.github.com>
Co-authored-by: Divma <26765164+divagant-martian@users.noreply.github.com>
Co-authored-by: Divma <26765164+divagant-martian@users.noreply.github.com>
Co-authored-by: Divma <26765164+divagant-martian@users.noreply.github.com>
@realbigsean

realbigsean commented Jan 20, 2022 •

Copy link
Copy Markdown
Member Author

really digging the new link checker! It already helped me find a problem here

thanks @ackintosh !

@realbigsean

Copy link
Copy Markdown
Member Author

@divagant-martian divagant-martian left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @pawanjay176 in attempting a version .2 that leverages structopt, but this change looks good to me as is right now :)

…nfig-file

# Conflicts:
#	account_manager/src/validator/exit.rs
#	lighthouse/src/main.rs
@realbigsean realbigsean mentioned this pull request Feb 7, 2022
@realbigsean

Copy link
Copy Markdown
Member Author

I am working on the migration to clap derive here: #3007

So I'm guessing we will end up closing this PR and working off of that one with something like what Pawan suggested.

@divagant-martian

Copy link
Copy Markdown
Contributor

I am working on the migration to clap derive here: #3007

So I'm guessing we will end up closing this PR and working off of that one with something like what Pawan suggested.

I suggest then if you can, to limit this PR only to the standarization of flags. That's a lot of work that we can merge anyway

@realbigsean realbigsean added do-not-merge and removed ready-for-review The code is ready for review labels Feb 8, 2022
@realbigsean

Copy link
Copy Markdown
Member Author

Closing for #3079

@realbigsean
realbigsean deleted the config-file branch November 21, 2023 16:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support loading client config flags/parameters and values via config file

3 participants