diff --git a/cmd/juno/juno.go b/cmd/juno/juno.go index 17159ec90a..551c06d96a 100644 --- a/cmd/juno/juno.go +++ b/cmd/juno/juno.go @@ -8,6 +8,7 @@ import ( "os/signal" "path/filepath" "runtime" + "strings" "syscall" "time" @@ -186,6 +187,9 @@ func NewCmd(config *node.Config, run func(*cobra.Command, []string) error) *cobr } } + v.AutomaticEnv() + v.SetEnvPrefix("JUNO") + v.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_")) if err := v.BindPFlags(cmd.Flags()); err != nil { return nil } diff --git a/cmd/juno/juno_test.go b/cmd/juno/juno_test.go index 1e93cfd0cc..0386c84adf 100644 --- a/cmd/juno/juno_test.go +++ b/cmd/juno/juno_test.go @@ -52,6 +52,7 @@ func TestConfigPrecedence(t *testing.T) { cfgFileContents string expectErr bool inputArgs []string + env []string expectedConfig *node.Config }{ "default config with no flags": { @@ -400,6 +401,95 @@ network: goerli DBCacheSize: defaultMaxCacheSize, }, }, + "only set env variables": { + env: []string{"JUNO_HTTP_PORT", "8080", "JUNO_WS", "true", "JUNO_HTTP_HOST", "0.0.0.0"}, + expectedConfig: &node.Config{ + LogLevel: defaultLogLevel, + HTTP: defaultHTTP, + HTTPHost: "0.0.0.0", + HTTPPort: 8080, + Websocket: true, + WebsocketHost: defaultHost, + WebsocketPort: defaultWSPort, + GRPC: defaultGRPC, + GRPCHost: defaultHost, + GRPCPort: defaultGRPCPort, + Metrics: defaultMetrics, + MetricsHost: defaultHost, + MetricsPort: defaultMetricsPort, + DatabasePath: defaultDBPath, + Network: defaultNetwork, + Pprof: defaultPprof, + PprofHost: defaultHost, + PprofPort: defaultPprofPort, + Colour: defaultColour, + PendingPollInterval: defaultPendingPollInterval, + MaxVMs: defaultMaxVMs, + MaxVMQueue: 2 * defaultMaxVMs, + RPCMaxBlockScan: defaultRPCMaxBlockScan, + DBCacheSize: defaultMaxCacheSize, + }, + }, + "some setting set in both env variables and flags": { + env: []string{"JUNO_DB_PATH", "/home/env/.juno"}, + inputArgs: []string{"--db-path", "/home/flag/.juno"}, + expectedConfig: &node.Config{ + LogLevel: defaultLogLevel, + HTTP: defaultHTTP, + HTTPHost: defaultHost, + HTTPPort: defaultHTTPPort, + Websocket: defaultWS, + WebsocketHost: defaultHost, + WebsocketPort: defaultWSPort, + GRPC: defaultGRPC, + GRPCHost: defaultHost, + GRPCPort: defaultGRPCPort, + Metrics: defaultMetrics, + MetricsHost: defaultHost, + MetricsPort: defaultMetricsPort, + DatabasePath: "/home/flag/.juno", + Network: defaultNetwork, + Pprof: defaultPprof, + PprofHost: defaultHost, + PprofPort: defaultPprofPort, + Colour: defaultColour, + PendingPollInterval: defaultPendingPollInterval, + MaxVMs: defaultMaxVMs, + MaxVMQueue: 2 * defaultMaxVMs, + RPCMaxBlockScan: defaultRPCMaxBlockScan, + DBCacheSize: defaultMaxCacheSize, + }, + }, + "some setting set in both env variables and config file": { + cfgFileContents: `db-path: /home/file/.juno`, + env: []string{"JUNO_DB_PATH", "/home/env/.juno"}, + expectedConfig: &node.Config{ + LogLevel: defaultLogLevel, + HTTP: defaultHTTP, + HTTPHost: defaultHost, + HTTPPort: defaultHTTPPort, + Websocket: defaultWS, + WebsocketHost: defaultHost, + WebsocketPort: defaultWSPort, + GRPC: defaultGRPC, + GRPCHost: defaultHost, + GRPCPort: defaultGRPCPort, + Metrics: defaultMetrics, + MetricsHost: defaultHost, + MetricsPort: defaultMetricsPort, + DatabasePath: "/home/env/.juno", + Network: defaultNetwork, + Pprof: defaultPprof, + PprofHost: defaultHost, + PprofPort: defaultPprofPort, + Colour: defaultColour, + PendingPollInterval: defaultPendingPollInterval, + MaxVMs: defaultMaxVMs, + MaxVMQueue: 2 * defaultMaxVMs, + RPCMaxBlockScan: defaultRPCMaxBlockScan, + DBCacheSize: defaultMaxCacheSize, + }, + }, } for name, tc := range tests { @@ -409,6 +499,14 @@ network: goerli tc.inputArgs = append(tc.inputArgs, "--config", fileN) } + require.True(t, len(tc.env)%2 == 0, "The number of env variables should be an even number") + + if len(tc.env) > 0 { + for i := 0; i < len(tc.env)/2; i++ { + os.Setenv(tc.env[2*i], tc.env[2*i+1]) + } + } + config := new(node.Config) cmd := juno.NewCmd(config, func(_ *cobra.Command, _ []string) error { return nil }) cmd.SetArgs(tc.inputArgs) @@ -421,6 +519,11 @@ network: goerli require.NoError(t, err) assert.Equal(t, tc.expectedConfig, config) + if len(tc.env) > 0 { + for i := 0; i < len(tc.env)/2; i++ { + os.Unsetenv(tc.env[2*i]) + } + } }) } }