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")
|
runCmdConfigFlag := fl.String("config")
|
||||||
runCmdConfigAdapterFlag := fl.String("adapter")
|
runCmdConfigAdapterFlag := fl.String("adapter")
|
||||||
runCmdResumeFlag := fl.Bool("resume")
|
runCmdResumeFlag := fl.Bool("resume")
|
||||||
|
runCmdLoadEnvfileFlag := fl.String("envfile")
|
||||||
runCmdPrintEnvFlag := fl.Bool("environ")
|
runCmdPrintEnvFlag := fl.Bool("environ")
|
||||||
runCmdWatchFlag := fl.Bool("watch")
|
runCmdWatchFlag := fl.Bool("watch")
|
||||||
runCmdPidfileFlag := fl.String("pidfile")
|
runCmdPidfileFlag := fl.String("pidfile")
|
||||||
runCmdPingbackFlag := fl.String("pingback")
|
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 we are supposed to print the environment, do that first
|
||||||
if runCmdPrintEnvFlag {
|
if runCmdPrintEnvFlag {
|
||||||
printEnvironment()
|
printEnvironment()
|
||||||
|
|
|
@ -96,7 +96,7 @@ using 'caddy run' instead to keep it in the foreground.`,
|
||||||
RegisterCommand(Command{
|
RegisterCommand(Command{
|
||||||
Name: "run",
|
Name: "run",
|
||||||
Func: cmdRun,
|
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`,
|
Short: `Starts the Caddy process and blocks indefinitely`,
|
||||||
Long: `
|
Long: `
|
||||||
Starts the Caddy process, optionally bootstrapped with an initial config file,
|
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
|
that file will be loaded and used to configure Caddy, even without any command
|
||||||
line flags.
|
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
|
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
|
be printed before starting. This is the same as the environ command but does
|
||||||
not quit after printing, and can be useful for troubleshooting.
|
not quit after printing, and can be useful for troubleshooting.
|
||||||
|
@ -130,6 +133,7 @@ development environment.`,
|
||||||
fs := flag.NewFlagSet("run", flag.ExitOnError)
|
fs := flag.NewFlagSet("run", flag.ExitOnError)
|
||||||
fs.String("config", "", "Configuration file")
|
fs.String("config", "", "Configuration file")
|
||||||
fs.String("adapter", "", "Name of config adapter to apply")
|
fs.String("adapter", "", "Name of config adapter to apply")
|
||||||
|
fs.String("envfile", "", "Environment file to load")
|
||||||
fs.Bool("environ", false, "Print environment")
|
fs.Bool("environ", false, "Print environment")
|
||||||
fs.Bool("resume", false, "Use saved config, if any (and prefer over --config file)")
|
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")
|
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
|
package caddycmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -339,6 +340,73 @@ func flagHelp(fs *flag.FlagSet) string {
|
||||||
return buf.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() {
|
func printEnvironment() {
|
||||||
fmt.Printf("caddy.HomeDir=%s\n", caddy.HomeDir())
|
fmt.Printf("caddy.HomeDir=%s\n", caddy.HomeDir())
|
||||||
fmt.Printf("caddy.AppDataDir=%s\n", caddy.AppDataDir())
|
fmt.Printf("caddy.AppDataDir=%s\n", caddy.AppDataDir())
|
||||||
|
|
Loading…
Reference in a new issue