diff --git a/cmd/backup/config_provider.go b/cmd/backup/config_provider.go index 50a588d4..306b7592 100644 --- a/cmd/backup/config_provider.go +++ b/cmd/backup/config_provider.go @@ -49,8 +49,9 @@ func loadEnvVars() (*Config, error) { } type configFile struct { - name string - config *Config + name string + config *Config + additionalEnvVars map[string]string } func loadEnvFiles(directory string) ([]configFile, error) { @@ -74,13 +75,16 @@ func loadEnvFiles(directory string) ([]configFile, error) { } lookup := func(key string) (string, bool) { val, ok := envFile[key] - return val, ok + if ok { + return val, ok + } + return os.LookupEnv(key) } c, err := loadConfig(lookup) if err != nil { return nil, fmt.Errorf("loadEnvFiles: error loading config from file %s: %w", p, err) } - cs = append(cs, configFile{config: c, name: item.Name()}) + cs = append(cs, configFile{config: c, name: item.Name(), additionalEnvVars: envFile}) } return cs, nil diff --git a/cmd/backup/main.go b/cmd/backup/main.go index f52183c3..faa022d7 100644 --- a/cmd/backup/main.go +++ b/cmd/backup/main.go @@ -36,7 +36,7 @@ func (c *command) must(err error) { } } -func runScript(c *Config) (err error) { +func runScript(c *Config, envVars map[string]string) (err error) { defer func() { if derr := recover(); derr != nil { err = fmt.Errorf("runScript: unexpected panic running script: %v", err) @@ -63,6 +63,35 @@ func runScript(c *Config) (err error) { } }() + if envVars != nil { + for key, value := range envVars { + currentVal, currentOk := os.LookupEnv(key) + defer func(currentKey, currentVal string, currentOk bool) { + if !currentOk { + _ = os.Unsetenv(currentKey) + } else { + _ = os.Setenv(currentKey, currentVal) + } + s.logger.Info(fmt.Sprintf("unset %v: %v", currentKey, currentVal)) + }(key, currentVal, currentOk) + + if err := os.Setenv(key, value); err != nil { + return fmt.Errorf( + "Unexpected error overloading environment %s: %w", + s.c.BackupCronExpression, + err, + ) + } + s.logger.Info(fmt.Sprintf("set %v: %v", key, value)) + } + } + + if s.c.BackupFilenameExpand { + s.file = os.ExpandEnv(s.file) + s.c.BackupLatestSymlink = os.ExpandEnv(s.c.BackupLatestSymlink) + s.c.BackupPruningPrefix = os.ExpandEnv(s.c.BackupPruningPrefix) + } + scriptErr := func() error { if err := s.withLabeledCommands(lifecyclePhaseArchive, func() (err error) { restartContainersAndServices, err := s.stopContainersAndServices() @@ -132,7 +161,7 @@ func (c *command) runInForeground(profileCronExpression string) error { ), ) - addJob := func(config *Config, name string) error { + addJob := func(config *Config, name string, envVars map[string]string) error { if _, err := cr.AddFunc(config.BackupCronExpression, func() { c.logger.Info( fmt.Sprintf( @@ -140,7 +169,8 @@ func (c *command) runInForeground(profileCronExpression string) error { config.BackupCronExpression, ), ) - if err := runScript(config); err != nil { + + if err := runScript(config, envVars); err != nil { c.logger.Error( fmt.Sprintf( "Unexpected error running schedule %s: %v", @@ -175,7 +205,7 @@ func (c *command) runInForeground(profileCronExpression string) error { if err != nil { return fmt.Errorf("runInForeground: could not load config from environment variables: %w", err) } else { - err = addJob(c, "from environment") + err = addJob(c, "from environment", nil) if err != nil { return fmt.Errorf("runInForeground: error adding job from env: %w", err) } @@ -183,7 +213,7 @@ func (c *command) runInForeground(profileCronExpression string) error { } else { c.logger.Info("/etc/dockervolumebackup/conf.d was found, using configuration files from this directory.") for _, config := range cs { - err = addJob(config.config, config.name) + err = addJob(config.config, config.name, config.additionalEnvVars) if err != nil { return fmt.Errorf("runInForeground: error adding jobs from conf files: %w", err) } @@ -227,7 +257,7 @@ func (c *command) runAsCommand() error { if err != nil { return fmt.Errorf("runAsCommand: error loading env vars: %w", err) } - err = runScript(config) + err = runScript(config, nil) if err != nil { return fmt.Errorf("runAsCommand: error running script: %w", err) } diff --git a/cmd/backup/script.go b/cmd/backup/script.go index b16d23b1..c3606259 100644 --- a/cmd/backup/script.go +++ b/cmd/backup/script.go @@ -97,11 +97,6 @@ func newScript(c *Config) (*script, error) { } s.file = bf.String() - if s.c.BackupFilenameExpand { - s.file = os.ExpandEnv(s.file) - s.c.BackupLatestSymlink = os.ExpandEnv(s.c.BackupLatestSymlink) - s.c.BackupPruningPrefix = os.ExpandEnv(s.c.BackupPruningPrefix) - } s.file = timeutil.Strftime(&s.stats.StartTime, s.file) _, err := os.Stat("/var/run/docker.sock") diff --git a/test/confd/01backup.env b/test/confd/01backup.env index 8d6d7e3f..1d9d2b5f 100644 --- a/test/confd/01backup.env +++ b/test/confd/01backup.env @@ -1,2 +1,2 @@ -BACKUP_CRON_EXPRESSION="*/1 * * * *" NAME="conf" +BACKUP_CRON_EXPRESSION="*/1 * * * *"