Skip to content

Commit

Permalink
Adds enviroment variable override to config loading
Browse files Browse the repository at this point in the history
  • Loading branch information
tjayrush committed Jan 1, 2025
1 parent 15e77ae commit 0d78238
Show file tree
Hide file tree
Showing 13 changed files with 252 additions and 153 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ go.work.sum
khedra
khedra.log
config.yaml
.DS_Store
36 changes: 36 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package app

import (
"log/slog"
"os"

"github.com/TrueBlocks/trueblocks-khedra/v2/pkg/config"
"github.com/urfave/cli/v2"
)

type KhedraApp struct {
Cli *cli.App
Config *config.Config
FileLogger *slog.Logger
ProgLogger *slog.Logger
}

func NewKhedraApp() *KhedraApp {
cfg := config.MustLoadConfig("config.yaml")
fileLogger, progLogger := config.NewLoggers(cfg.Logging)
cli := initializeCli()

k := &KhedraApp{
Config: cfg,
FileLogger: fileLogger,
ProgLogger: progLogger,
Cli: cli,
}

return k
}

// Run runs the Khedra cli
func (k *KhedraApp) Run() error {
return k.Cli.Run(os.Args)
}
72 changes: 72 additions & 0 deletions app/cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package app

import (
"log/slog"

"github.com/urfave/cli/v2"
)

func initializeCli() *cli.App {
return &cli.App{
Name: "khedra",
Usage: "A tool to index, monitor, serve, and share blockchain data",
Commands: []*cli.Command{
{
Name: "init",
Usage: "Initializes Khedra",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "mode",
Usage: "Initialization mode (all, blooms, none)",
},
},
Action: func(c *cli.Context) error {
slog.Info("command calls: init", "mode", c.String("mode"))
return nil
},
},
{
Name: "scrape",
Usage: "Controls the blockchain scraper",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "state",
Usage: "Scraper state (on, off)",
},
},
Action: func(c *cli.Context) error {
slog.Info("command calls: scrape", "state", c.String("state"))
return nil
},
},
{
Name: "api",
Usage: "Starts or stops the API server",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "state",
Usage: "API state (on, off)",
},
},
Action: func(c *cli.Context) error {
slog.Info("command calls: api", "state", c.String("state"))
return nil
},
},
{
Name: "sleep",
Usage: "Sets the duration between updates",
Flags: []cli.Flag{
&cli.IntFlag{
Name: "duration",
Usage: "Sleep duration in seconds",
},
},
Action: func(c *cli.Context) error {
slog.Info("command calls: sleep", "duration", c.Int("duration"))
return nil
},
},
},
}
}
52 changes: 49 additions & 3 deletions book/src/user_man/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Overview

The `config` package in Khedra manages application configuration through the `config.yaml` file. This file allows you to specify key parameters for running Khedra, including logging, blockchain chains, and services. This document outlines the configuration file structure, validation rules, and default values.
The `config` package in Khedra manages application configuration through the `config.yaml` file. This file allows you to specify key parameters for running Khedra, including logging, blockchain chains, and services. Additionally, environment variables can override specific configuration options. This document outlines the configuration file structure, validation rules, default values, and environment variable usage.

---

Expand All @@ -19,6 +19,13 @@ The `config` package in Khedra manages application configuration through the `co
2. **Location of `config.yaml`**:
- By default, the `config.yaml` file must be in the current directory or in the `~/.khedra` folder. If the file is not present, Khedra creates a default configuration file in `~/.khedra`.

3. **Using Environment Variables**:
- Environment variables starting with `TB_KHEDRA_` can override specific values in `config.yaml`. For example:

```bash
export TB_KHEDRA_GENERAL_DATADIR="/path/override"
```

---

## Configuration File Format
Expand Down Expand Up @@ -85,6 +92,36 @@ logging:

---

## Using Environment Variables

Khedra allows configuration values to be overridden using environment variables. The environment variable naming convention is:

`TB_KHEDRA_<section>_<key>`

For example:

- To override the `general.data_dir` value:

```bash
export TB_KHEDRA_GENERAL_DATADIR="/path/override"
```

- To set the `log_level`:

```bash
export TB_KHEDRA_GENERAL_LOGLEVEL="debug"
```

### Precedence Rules

1. Default values are loaded first.
2. Values from `config.yaml` override the defaults.
3. Environment variables (e.g., `TB_KHEDRA_<section>_<key>`) take precedence over both the defaults and the file.

Environment variables must conform to the same validation rules as the configuration file.

---

## Configuration Sections

### General Settings
Expand Down Expand Up @@ -129,7 +166,7 @@ Controls the application's logging behavior:
## Validation Rules
The configuration file is validated on load with the following rules:
The configuration file and environment variables are validated on load with the following rules:
### General
Expand Down Expand Up @@ -183,7 +220,7 @@ If the configuration file is not found or incomplete, Khedra uses the following
## Common Commands
1. **Validate Configuration**:
Khedra validates the `config.yaml` file automatically on startup.
Khedra validates the `config.yaml` file and environment variables automatically on startup.
2. **Run Khedra**:
Expand All @@ -193,4 +230,13 @@ If the configuration file is not found or incomplete, Khedra uses the following
Ensure that your `config.yaml` file is properly set up.
3. **Override Configuration with Environment Variables**:
Use environment variables to override specific configurations:
```bash
export TB_KHEDRA_GENERAL_DATADIR="/new/path"
./khedra
```
For additional details, see the technical specification.
2 changes: 1 addition & 1 deletion book/src/user_man/understanding_khedra.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

Khedra operates through:

- **Command-Line Interface (CLI)**: For configuration and command execution.
- **Command-Line Interface (Cli)**: For configuration and command execution.
- **REST API**: For programmatic interaction with indexed data.

## Terminology and Concepts
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ require (
github.com/ipfs/go-ipfs-api v0.6.1 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/knadh/koanf/maps v0.1.1 // indirect
github.com/knadh/koanf/providers/env v1.0.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/libp2p/go-flow-metrics v0.1.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,8 @@ github.com/knadh/koanf/maps v0.1.1 h1:G5TjmUh2D7G2YWf5SQQqSiHRJEjaicvU0KpypqB3NI
github.com/knadh/koanf/maps v0.1.1/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI=
github.com/knadh/koanf/parsers/yaml v0.1.0 h1:ZZ8/iGfRLvKSaMEECEBPM1HQslrZADk8fP1XFUxVI5w=
github.com/knadh/koanf/parsers/yaml v0.1.0/go.mod h1:cvbUDC7AL23pImuQP0oRw/hPuccrNBS2bps8asS0CwY=
github.com/knadh/koanf/providers/env v1.0.0 h1:ufePaI9BnWH+ajuxGGiJ8pdTG0uLEUWC7/HDDPGLah0=
github.com/knadh/koanf/providers/env v1.0.0/go.mod h1:mzFyRZueYhb37oPmC1HAv/oGEEuyvJDA98r3XAa8Gak=
github.com/knadh/koanf/providers/file v1.1.2 h1:aCC36YGOgV5lTtAFz2qkgtWdeQsgfxUkxDOe+2nQY3w=
github.com/knadh/koanf/providers/file v1.1.2/go.mod h1:/faSBcv2mxPVjFrXck95qeoyoZ5myJ6uxN8OOVNJJCI=
github.com/knadh/koanf/v2 v2.1.2 h1:I2rtLRqXRy1p01m/utEtpZSSA6dcJbgGVuE27kW2PzQ=
Expand Down
100 changes: 9 additions & 91 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,103 +1,21 @@
package main

import (
"log"
"log/slog"
"os"
"path/filepath"

"github.com/TrueBlocks/trueblocks-khedra/v2/pkg/config"
"github.com/urfave/cli/v2"
"gopkg.in/natefinch/lumberjack.v2"
"github.com/TrueBlocks/trueblocks-khedra/v2/app"
)

type Khedra struct {
Config *config.Config
Logger *slog.Logger
}

func main() {
cfg := config.MustLoadConfig("config.yaml")

fileLogger := &lumberjack.Logger{
Filename: filepath.Join(cfg.Logging.Folder, cfg.Logging.Filename),
MaxSize: cfg.Logging.MaxSizeMb,
MaxBackups: cfg.Logging.MaxBackups,
MaxAge: cfg.Logging.MaxAgeDays,
Compress: cfg.Logging.Compress,
}
// Create a new Khedra app...
k := app.NewKhedraApp()

fileHandler := slog.NewJSONHandler(fileLogger, nil)
logger := slog.New(fileHandler)
// slog.SetDefault(logger)

logger.Info("Starting Khedra CLI")

app := &cli.App{
Name: "khedra",
Usage: "A CLI tool for Khedra",
Commands: []*cli.Command{
{
Name: "init",
Usage: "Initializes Khedra",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "mode",
Usage: "Initialization mode (all, blooms, none)",
},
},
Action: func(c *cli.Context) error {
slog.Info("command calls: init", "mode", c.String("mode"))
return nil
},
},
{
Name: "scrape",
Usage: "Controls the blockchain scraper",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "state",
Usage: "Scraper state (on, off)",
},
},
Action: func(c *cli.Context) error {
slog.Info("command calls: scrape", "state", c.String("state"))
return nil
},
},
{
Name: "api",
Usage: "Starts or stops the API server",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "state",
Usage: "API state (on, off)",
},
},
Action: func(c *cli.Context) error {
slog.Info("command calls: api", "state", c.String("state"))
return nil
},
},
{
Name: "sleep",
Usage: "Sets the duration between updates",
Flags: []cli.Flag{
&cli.IntFlag{
Name: "duration",
Usage: "Sleep duration in seconds",
},
},
Action: func(c *cli.Context) error {
slog.Info("command calls: sleep", "duration", c.Int("duration"))
return nil
},
},
},
}
k.FileLogger.Info("Khedra started.")
defer k.FileLogger.Info("Khedra stopped.")

err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
// ...and run it
if err := k.Run(); err != nil {
k.ProgLogger.Error(err.Error())
os.Exit(1)
}
}
2 changes: 1 addition & 1 deletion pkg/config/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type Chain struct {

func NewChain() Chain {
return Chain{
Name: "ethereum",
Name: "mainnet",
RPCs: []string{"http://localhost:8545"},
Enabled: true,
}
Expand Down
15 changes: 4 additions & 11 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package config

import (
"encoding/json"

coreFile "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file"
"gopkg.in/yaml.v2"
)
Expand All @@ -19,20 +17,15 @@ func NewConfig() Config {
General: NewGeneral(),
Chains: []Chain{NewChain()},
Services: []Service{
NewScraper(),
NewMonitor(),
NewApi(),
NewIpfs(),
NewService("scraper"),
NewService("monitor"),
NewService("api"),
NewService("ipfs"),
},
Logging: NewLogging(),
}
}

func (c *Config) String() string {
bytes, _ := json.Marshal(c)
return string(bytes)
}

func establishConfig(fn string) bool {
cfg := NewConfig()
bytes, _ := yaml.Marshal(cfg)
Expand Down
Loading

0 comments on commit 0d78238

Please sign in to comment.