mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-27 06:03:48 +03:00
cmd: Add --envfile flag to run command (#3278)
* run: Add the possibility to load an env file * run: change envfile flag var * run: do not ignore err values * Apply suggestions from code review Co-authored-by: Matt Holt <mholt@users.noreply.github.com> Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
This commit is contained in:
parent
bde3823b76
commit
62c9f2cf3e
3 changed files with 82 additions and 1 deletions
|
@ -151,11 +151,20 @@ func cmdRun(fl Flags) (int, error) {
|
|||
runCmdConfigFlag := fl.String("config")
|
||||
runCmdConfigAdapterFlag := fl.String("adapter")
|
||||
runCmdResumeFlag := fl.Bool("resume")
|
||||
runCmdLoadEnvfileFlag := fl.String("envfile")
|
||||
runCmdPrintEnvFlag := fl.Bool("environ")
|
||||
runCmdWatchFlag := fl.Bool("watch")
|
||||
runCmdPidfileFlag := fl.String("pidfile")
|
||||
runCmdPingbackFlag := fl.String("pingback")
|
||||
|
||||
// load all additional envs as soon as possible
|
||||
if runCmdLoadEnvfileFlag != "" {
|
||||
if err := loadEnvFromFile(runCmdLoadEnvfileFlag); err != nil {
|
||||
return caddy.ExitCodeFailedStartup,
|
||||
fmt.Errorf("loading additional environment variables: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// if we are supposed to print the environment, do that first
|
||||
if runCmdPrintEnvFlag {
|
||||
printEnvironment()
|
||||
|
|
|
@ -96,7 +96,7 @@ using 'caddy run' instead to keep it in the foreground.`,
|
|||
RegisterCommand(Command{
|
||||
Name: "run",
|
||||
Func: cmdRun,
|
||||
Usage: "[--config <path> [--adapter <name>]] [--environ] [--resume] [--watch] [--pidfile <fil>]",
|
||||
Usage: "[--config <path> [--adapter <name>]] [--envfile <path>] [--environ] [--resume] [--watch] [--pidfile <fil>]",
|
||||
Short: `Starts the Caddy process and blocks indefinitely`,
|
||||
Long: `
|
||||
Starts the Caddy process, optionally bootstrapped with an initial config file,
|
||||
|
@ -116,6 +116,9 @@ As a special case, if the current working directory has a file called
|
|||
that file will be loaded and used to configure Caddy, even without any command
|
||||
line flags.
|
||||
|
||||
If --envfile is specified, an environment file with environment variables in
|
||||
the KEY=VALUE format will be loaded into the Caddy process.
|
||||
|
||||
If --environ is specified, the environment as seen by the Caddy process will
|
||||
be printed before starting. This is the same as the environ command but does
|
||||
not quit after printing, and can be useful for troubleshooting.
|
||||
|
@ -130,6 +133,7 @@ development environment.`,
|
|||
fs := flag.NewFlagSet("run", flag.ExitOnError)
|
||||
fs.String("config", "", "Configuration file")
|
||||
fs.String("adapter", "", "Name of config adapter to apply")
|
||||
fs.String("envfile", "", "Environment file to load")
|
||||
fs.Bool("environ", false, "Print environment")
|
||||
fs.Bool("resume", false, "Use saved config, if any (and prefer over --config file)")
|
||||
fs.Bool("watch", false, "Watch config file for changes and reload it automatically")
|
||||
|
|
68
cmd/main.go
68
cmd/main.go
|
@ -15,6 +15,7 @@
|
|||
package caddycmd
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
|
@ -339,6 +340,73 @@ func flagHelp(fs *flag.FlagSet) string {
|
|||
return buf.String()
|
||||
}
|
||||
|
||||
func loadEnvFromFile(envFile string) error {
|
||||
file, err := os.Open(envFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading environment file: %v", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
envMap, err := parseEnvFile(file)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing environment file: %v", err)
|
||||
}
|
||||
|
||||
for k, v := range envMap {
|
||||
if err := os.Setenv(k, v); err != nil {
|
||||
return fmt.Errorf("setting environment variables: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseEnvFile(envInput io.Reader) (map[string]string, error) {
|
||||
envMap := make(map[string]string)
|
||||
|
||||
scanner := bufio.NewScanner(envInput)
|
||||
var line string
|
||||
lineNumber := 0
|
||||
|
||||
for scanner.Scan() {
|
||||
line = strings.TrimSpace(scanner.Text())
|
||||
lineNumber++
|
||||
|
||||
// skip lines starting with comment
|
||||
if strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
}
|
||||
|
||||
// skip empty line
|
||||
if len(line) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
fields := strings.SplitN(line, "=", 2)
|
||||
if len(fields) != 2 {
|
||||
return nil, fmt.Errorf("can't parse line %d; line should be in KEY=VALUE format", lineNumber)
|
||||
}
|
||||
|
||||
if strings.Contains(fields[0], " ") {
|
||||
return nil, fmt.Errorf("bad key on line %d: contains whitespace", lineNumber)
|
||||
}
|
||||
|
||||
key := fields[0]
|
||||
val := fields[1]
|
||||
|
||||
if key == "" {
|
||||
return nil, fmt.Errorf("missing or empty key on line %d", lineNumber)
|
||||
}
|
||||
envMap[key] = val
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return envMap, nil
|
||||
}
|
||||
|
||||
func printEnvironment() {
|
||||
fmt.Printf("caddy.HomeDir=%s\n", caddy.HomeDir())
|
||||
fmt.Printf("caddy.AppDataDir=%s\n", caddy.AppDataDir())
|
||||
|
|
Loading…
Reference in a new issue