Skip to content

Commit

Permalink
Move fallback to config sourcing
Browse files Browse the repository at this point in the history
  • Loading branch information
m90 committed Feb 15, 2024
1 parent 7403415 commit a8d2013
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 18 deletions.
17 changes: 10 additions & 7 deletions cmd/backup/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,19 +181,22 @@ type envVarLookup struct {
value string
}

// applyEnv sets the values in `additionalEnvVars` as environment variables.
// It returns a function that reverts all values that have been set to its
// previous state.
func (c *Config) applyEnv() (func() error, error) {
lookups := []envVarLookup{}

unset := func() error {
for _, lookup := range lookups {
if lookup.ok {
if err := os.Setenv(lookup.key, lookup.value); err != nil {
return fmt.Errorf("(*Config).injectEnv: error setting back env var %s: %w", lookup.key, err)
}
} else {
if !lookup.ok {
if err := os.Unsetenv(lookup.key); err != nil {
return fmt.Errorf("(*Config).injectEnv: error unsetting env var %s: %w", lookup.key, err)
return fmt.Errorf("(*Config).applyEnv: error unsetting env var %s: %w", lookup.key, err)
}
continue
}
if err := os.Setenv(lookup.key, lookup.value); err != nil {
return fmt.Errorf("(*Config).applyEnv: error setting back env var %s: %w", lookup.key, err)
}
}
return nil
Expand All @@ -203,7 +206,7 @@ func (c *Config) applyEnv() (func() error, error) {
current, ok := os.LookupEnv(key)
lookups = append(lookups, envVarLookup{ok: ok, key: key, value: current})
if err := os.Setenv(key, value); err != nil {
return unset, fmt.Errorf("(*Config).injectEnv: error setting env var: %w", err)
return unset, fmt.Errorf("(*Config).applyEnv: error setting env var: %w", err)
}
}
return unset, nil
Expand Down
15 changes: 13 additions & 2 deletions cmd/backup/config_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,32 @@ const (
configStrategyConfd configStrategy = "confd"
)

// sourceConfiguration returns a list of config objects using the given
// strategy. It should be the single entrypoint for retrieving configuration
// for all consumers.
func sourceConfiguration(strategy configStrategy) ([]*Config, error) {
switch strategy {
case configStrategyEnv:
c, err := loadConfigFromEnvVars()
return []*Config{c}, err
case configStrategyConfd:
return loadConfigsFromEnvFiles("/etc/dockervolumebackup/conf.d")
cs, err := loadConfigsFromEnvFiles("/etc/dockervolumebackup/conf.d")
if err != nil {
if os.IsNotExist(err) {
return sourceConfiguration(configStrategyEnv)
}
return nil, fmt.Errorf("sourceConfiguration: error loading config files: %w", err)
}
return cs, nil
default:
return nil, fmt.Errorf("newConfig: received unknown config strategy: %v", strategy)
return nil, fmt.Errorf("sourceConfiguration: received unknown config strategy: %v", strategy)
}
}

// envProxy is a function that mimics os.LookupEnv but can read values from any other source
type envProxy func(string) (string, bool)

// loadConfig creates a config object using the given lookup function
func loadConfig(lookup envProxy) (*Config, error) {
envconfig.Lookup = func(key string) (string, bool) {
value, okValue := lookup(key)
Expand Down
20 changes: 11 additions & 9 deletions cmd/backup/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ func newCommand() *command {
}
}

// must exits the program when passed an error. It should be the only
// place where the application exits forcefully.
func (c *command) must(err error) {
if err != nil {
c.logger.Error(
Expand All @@ -48,6 +50,10 @@ func (c *command) must(err error) {
}
}

// runScript instantiates a new script object and orchestrates a backup run.
// To ensure it runs mutually exclusive a global file lock is acquired before
// it starts running. Any panic within the script will be recovered and returned
// as an error.
func runScript(c *Config) (err error) {
defer func() {
if derr := recover(); derr != nil {
Expand Down Expand Up @@ -139,6 +145,8 @@ func runScript(c *Config) (err error) {
}()
}

// runInForeground starts the program as a long running process, scheduling
// a job for each configuration that is available.
func (c *command) runInForeground(profileCronExpression string) error {
cr := cron.New(
cron.WithParser(
Expand Down Expand Up @@ -184,15 +192,7 @@ func (c *command) runInForeground(profileCronExpression string) error {

cs, err := sourceConfiguration(configStrategyConfd)
if err != nil {
if !os.IsNotExist(err) {
return fmt.Errorf("runInForeground: could not load config from environment files: %w", err)
}
cs, err = sourceConfiguration(configStrategyEnv)
if err != nil {
return fmt.Errorf("runInForeground: could not load configuration: %w", err)
}
} else {
c.logger.Info("/etc/dockervolumebackup/conf.d was found, using configuration files from this directory.")
return fmt.Errorf("runInForeground: error sourcing configuration: %w", err)
}

for _, config := range cs {
Expand All @@ -218,6 +218,8 @@ func (c *command) runInForeground(profileCronExpression string) error {
return nil
}

// runAsCommand executes a backup run for each configuration that is available
// and then returns
func (c *command) runAsCommand() error {
configurations, err := sourceConfiguration(configStrategyEnv)
if err != nil {
Expand Down

0 comments on commit a8d2013

Please sign in to comment.