Skip to content

Commit f2ab709

Browse files
cmd: Prevent overwriting existing env vars with --envfile (#5803)
Co-authored-by: Francis Lavoie <[email protected]>
1 parent 50cea4e commit f2ab709

File tree

3 files changed

+57
-33
lines changed

3 files changed

+57
-33
lines changed

cmd/commandfuncs.go

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,14 @@ func cmdStart(fl Flags) (int, error) {
4646
startCmdConfigAdapterFlag := fl.String("adapter")
4747
startCmdPidfileFlag := fl.String("pidfile")
4848
startCmdWatchFlag := fl.Bool("watch")
49-
startCmdEnvfileFlag := fl.String("envfile")
49+
50+
var err error
51+
var startCmdEnvfileFlag []string
52+
startCmdEnvfileFlag, err = fl.GetStringSlice("envfile")
53+
if err != nil {
54+
return caddy.ExitCodeFailedStartup,
55+
fmt.Errorf("reading envfile flag: %v", err)
56+
}
5057

5158
// open a listener to which the child process will connect when
5259
// it is ready to confirm that it has successfully started
@@ -70,8 +77,9 @@ func cmdStart(fl Flags) (int, error) {
7077
if startCmdConfigFlag != "" {
7178
cmd.Args = append(cmd.Args, "--config", startCmdConfigFlag)
7279
}
73-
if startCmdEnvfileFlag != "" {
74-
cmd.Args = append(cmd.Args, "--envfile", startCmdEnvfileFlag)
80+
81+
for _, envFile := range startCmdEnvfileFlag {
82+
cmd.Args = append(cmd.Args, "--envfile", envFile)
7583
}
7684
if startCmdConfigAdapterFlag != "" {
7785
cmd.Args = append(cmd.Args, "--adapter", startCmdConfigAdapterFlag)
@@ -160,15 +168,22 @@ func cmdRun(fl Flags) (int, error) {
160168
runCmdConfigFlag := fl.String("config")
161169
runCmdConfigAdapterFlag := fl.String("adapter")
162170
runCmdResumeFlag := fl.Bool("resume")
163-
runCmdLoadEnvfileFlag := fl.String("envfile")
164171
runCmdPrintEnvFlag := fl.Bool("environ")
165172
runCmdWatchFlag := fl.Bool("watch")
166173
runCmdPidfileFlag := fl.String("pidfile")
167174
runCmdPingbackFlag := fl.String("pingback")
168175

176+
var err error
177+
var runCmdLoadEnvfileFlag []string
178+
runCmdLoadEnvfileFlag, err = fl.GetStringSlice("envfile")
179+
if err != nil {
180+
return caddy.ExitCodeFailedStartup,
181+
fmt.Errorf("reading envfile flag: %v", err)
182+
}
183+
169184
// load all additional envs as soon as possible
170-
if runCmdLoadEnvfileFlag != "" {
171-
if err := loadEnvFromFile(runCmdLoadEnvfileFlag); err != nil {
185+
for _, envFile := range runCmdLoadEnvfileFlag {
186+
if err := loadEnvFromFile(envFile); err != nil {
172187
return caddy.ExitCodeFailedStartup,
173188
fmt.Errorf("loading additional environment variables: %v", err)
174189
}
@@ -181,7 +196,6 @@ func cmdRun(fl Flags) (int, error) {
181196

182197
// load the config, depending on flags
183198
var config []byte
184-
var err error
185199
if runCmdResumeFlag {
186200
config, err = os.ReadFile(caddy.ConfigAutosavePath)
187201
if os.IsNotExist(err) {
@@ -497,18 +511,24 @@ func cmdAdaptConfig(fl Flags) (int, error) {
497511
func cmdValidateConfig(fl Flags) (int, error) {
498512
validateCmdConfigFlag := fl.String("config")
499513
validateCmdAdapterFlag := fl.String("adapter")
500-
runCmdLoadEnvfileFlag := fl.String("envfile")
514+
515+
var err error
516+
var runCmdLoadEnvfileFlag []string
517+
runCmdLoadEnvfileFlag, err = fl.GetStringSlice("envfile")
518+
if err != nil {
519+
return caddy.ExitCodeFailedStartup,
520+
fmt.Errorf("reading envfile flag: %v", err)
521+
}
501522

502523
// load all additional envs as soon as possible
503-
if runCmdLoadEnvfileFlag != "" {
504-
if err := loadEnvFromFile(runCmdLoadEnvfileFlag); err != nil {
524+
for _, envFile := range runCmdLoadEnvfileFlag {
525+
if err := loadEnvFromFile(envFile); err != nil {
505526
return caddy.ExitCodeFailedStartup,
506527
fmt.Errorf("loading additional environment variables: %v", err)
507528
}
508529
}
509530

510531
// use default config and ensure a config file is specified
511-
var err error
512532
validateCmdConfigFlag, err = configFileWithRespectToDefault(caddy.Log(), validateCmdConfigFlag)
513533
if err != nil {
514534
return caddy.ExitCodeFailedStartup, err

cmd/commands.go

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ using 'caddy run' instead to keep it in the foreground.
104104
CobraFunc: func(cmd *cobra.Command) {
105105
cmd.Flags().StringP("config", "c", "", "Configuration file")
106106
cmd.Flags().StringP("adapter", "a", "", "Name of config adapter to apply")
107-
cmd.Flags().StringP("envfile", "", "", "Environment file to load")
107+
cmd.Flags().StringSliceP("envfile", "", []string{}, "Environment file(s) to load")
108108
cmd.Flags().BoolP("watch", "w", false, "Reload changed config file automatically")
109109
cmd.Flags().StringP("pidfile", "", "", "Path of file to which to write process ID")
110110
cmd.RunE = WrapCommandFuncForCobra(cmdStart)
@@ -150,7 +150,7 @@ option in a local development environment.
150150
CobraFunc: func(cmd *cobra.Command) {
151151
cmd.Flags().StringP("config", "c", "", "Configuration file")
152152
cmd.Flags().StringP("adapter", "a", "", "Name of config adapter to apply")
153-
cmd.Flags().StringP("envfile", "", "", "Environment file to load")
153+
cmd.Flags().StringSliceP("envfile", "", []string{}, "Environment file(s) to load")
154154
cmd.Flags().BoolP("environ", "e", false, "Print environment")
155155
cmd.Flags().BoolP("resume", "r", false, "Use saved config, if any (and prefer over --config file)")
156156
cmd.Flags().BoolP("watch", "w", false, "Watch config file for changes and reload it automatically")
@@ -301,7 +301,7 @@ the KEY=VALUE format will be loaded into the Caddy process.
301301
CobraFunc: func(cmd *cobra.Command) {
302302
cmd.Flags().StringP("config", "c", "", "Input configuration file")
303303
cmd.Flags().StringP("adapter", "a", "", "Name of config adapter")
304-
cmd.Flags().StringP("envfile", "", "", "Environment file to load")
304+
cmd.Flags().StringSliceP("envfile", "", []string{}, "Environment file(s) to load")
305305
cmd.RunE = WrapCommandFuncForCobra(cmdValidateConfig)
306306
},
307307
})
@@ -402,7 +402,7 @@ latest versions. EXPERIMENTAL: May be changed or removed.
402402
Short: "Adds Caddy packages (EXPERIMENTAL)",
403403
Long: `
404404
Downloads an updated Caddy binary with the specified packages (module/plugin)
405-
added. Retains existing packages. Returns an error if the any of packages are
405+
added. Retains existing packages. Returns an error if the any of packages are
406406
already included. EXPERIMENTAL: May be changed or removed.
407407
`,
408408
CobraFunc: func(cmd *cobra.Command) {
@@ -417,8 +417,8 @@ already included. EXPERIMENTAL: May be changed or removed.
417417
Usage: "<packages...>",
418418
Short: "Removes Caddy packages (EXPERIMENTAL)",
419419
Long: `
420-
Downloads an updated Caddy binaries without the specified packages (module/plugin).
421-
Returns an error if any of the packages are not included.
420+
Downloads an updated Caddy binaries without the specified packages (module/plugin).
421+
Returns an error if any of the packages are not included.
422422
EXPERIMENTAL: May be changed or removed.
423423
`,
424424
CobraFunc: func(cmd *cobra.Command) {
@@ -464,40 +464,40 @@ argument of --directory. If the directory does not exist, it will be created.
464464
Use: "completion [bash|zsh|fish|powershell]",
465465
Short: "Generate completion script",
466466
Long: fmt.Sprintf(`To load completions:
467-
467+
468468
Bash:
469-
469+
470470
$ source <(%[1]s completion bash)
471-
471+
472472
# To load completions for each session, execute once:
473473
# Linux:
474474
$ %[1]s completion bash > /etc/bash_completion.d/%[1]s
475475
# macOS:
476476
$ %[1]s completion bash > $(brew --prefix)/etc/bash_completion.d/%[1]s
477-
477+
478478
Zsh:
479-
479+
480480
# If shell completion is not already enabled in your environment,
481481
# you will need to enable it. You can execute the following once:
482-
482+
483483
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
484-
484+
485485
# To load completions for each session, execute once:
486486
$ %[1]s completion zsh > "${fpath[1]}/_%[1]s"
487-
487+
488488
# You will need to start a new shell for this setup to take effect.
489-
489+
490490
fish:
491-
491+
492492
$ %[1]s completion fish | source
493-
493+
494494
# To load completions for each session, execute once:
495495
$ %[1]s completion fish > ~/.config/fish/completions/%[1]s.fish
496-
496+
497497
PowerShell:
498-
498+
499499
PS> %[1]s completion powershell | Out-String | Invoke-Expression
500-
500+
501501
# To load completions for every new session, run:
502502
PS> %[1]s completion powershell > %[1]s.ps1
503503
# and source this file from your PowerShell profile.

cmd/main.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,12 @@ func loadEnvFromFile(envFile string) error {
300300
}
301301

302302
for k, v := range envMap {
303-
if err := os.Setenv(k, v); err != nil {
304-
return fmt.Errorf("setting environment variables: %v", err)
303+
// do not overwrite existing environment variables
304+
_, exists := os.LookupEnv(k)
305+
if !exists {
306+
if err := os.Setenv(k, v); err != nil {
307+
return fmt.Errorf("setting environment variables: %v", err)
308+
}
305309
}
306310
}
307311

0 commit comments

Comments
 (0)