mirror of https://github.com/caddyserver/caddy.git
cmd: Add pidfile support (closes #3235)
This commit is contained in:
parent
cee5589b98
commit
4df56c77e3
23
admin.go
23
admin.go
|
@ -21,6 +21,7 @@ import (
|
||||||
"expvar"
|
"expvar"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/pprof"
|
"net/http/pprof"
|
||||||
|
@ -546,13 +547,6 @@ func handleUnload(w http.ResponseWriter, r *http.Request) error {
|
||||||
Err: fmt.Errorf("method not allowed"),
|
Err: fmt.Errorf("method not allowed"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentCfgMu.RLock()
|
|
||||||
hasCfg := currentCfg != nil
|
|
||||||
currentCfgMu.RUnlock()
|
|
||||||
if !hasCfg {
|
|
||||||
Log().Named("admin.api").Info("nothing to unload")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
Log().Named("admin.api").Info("unloading")
|
Log().Named("admin.api").Info("unloading")
|
||||||
if err := stopAndCleanup(); err != nil {
|
if err := stopAndCleanup(); err != nil {
|
||||||
Log().Named("admin.api").Error("error unloading", zap.Error(err))
|
Log().Named("admin.api").Error("error unloading", zap.Error(err))
|
||||||
|
@ -801,12 +795,27 @@ var (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// PIDFile writes a pidfile to the file at filename. It
|
||||||
|
// will get deleted before the process gracefully exits.
|
||||||
|
func PIDFile(filename string) error {
|
||||||
|
pid := []byte(strconv.Itoa(os.Getpid()) + "\n")
|
||||||
|
err := ioutil.WriteFile(filename, pid, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pidfile = filename
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// idRegexp is used to match ID fields and their associated values
|
// idRegexp is used to match ID fields and their associated values
|
||||||
// in the config. It also matches adjacent commas so that syntax
|
// in the config. It also matches adjacent commas so that syntax
|
||||||
// can be preserved no matter where in the object the field appears.
|
// can be preserved no matter where in the object the field appears.
|
||||||
// It supports string and most numeric values.
|
// It supports string and most numeric values.
|
||||||
var idRegexp = regexp.MustCompile(`(?m),?\s*"` + idKey + `"\s*:\s*(-?[0-9]+(\.[0-9]+)?|(?U)".*")\s*,?`)
|
var idRegexp = regexp.MustCompile(`(?m),?\s*"` + idKey + `"\s*:\s*(-?[0-9]+(\.[0-9]+)?|(?U)".*")\s*,?`)
|
||||||
|
|
||||||
|
// pidfile is the name of the pidfile, if any.
|
||||||
|
var pidfile string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
rawConfigKey = "config"
|
rawConfigKey = "config"
|
||||||
idKey = "@id"
|
idKey = "@id"
|
||||||
|
|
3
caddy.go
3
caddy.go
|
@ -470,6 +470,9 @@ func stopAndCleanup() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
certmagic.CleanUpOwnLocks()
|
certmagic.CleanUpOwnLocks()
|
||||||
|
if pidfile != "" {
|
||||||
|
os.Remove(pidfile)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ import (
|
||||||
func cmdStart(fl Flags) (int, error) {
|
func cmdStart(fl Flags) (int, error) {
|
||||||
startCmdConfigFlag := fl.String("config")
|
startCmdConfigFlag := fl.String("config")
|
||||||
startCmdConfigAdapterFlag := fl.String("adapter")
|
startCmdConfigAdapterFlag := fl.String("adapter")
|
||||||
|
startCmdPidfileFlag := fl.String("pidfile")
|
||||||
startCmdWatchFlag := fl.Bool("watch")
|
startCmdWatchFlag := fl.Bool("watch")
|
||||||
|
|
||||||
// open a listener to which the child process will connect when
|
// open a listener to which the child process will connect when
|
||||||
|
@ -71,6 +72,9 @@ func cmdStart(fl Flags) (int, error) {
|
||||||
if startCmdWatchFlag {
|
if startCmdWatchFlag {
|
||||||
cmd.Args = append(cmd.Args, "--watch")
|
cmd.Args = append(cmd.Args, "--watch")
|
||||||
}
|
}
|
||||||
|
if startCmdPidfileFlag != "" {
|
||||||
|
cmd.Args = append(cmd.Args, "--pidfile", startCmdPidfileFlag)
|
||||||
|
}
|
||||||
stdinpipe, err := cmd.StdinPipe()
|
stdinpipe, err := cmd.StdinPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return caddy.ExitCodeFailedStartup,
|
return caddy.ExitCodeFailedStartup,
|
||||||
|
@ -149,6 +153,7 @@ func cmdRun(fl Flags) (int, error) {
|
||||||
runCmdResumeFlag := fl.Bool("resume")
|
runCmdResumeFlag := fl.Bool("resume")
|
||||||
runCmdPrintEnvFlag := fl.Bool("environ")
|
runCmdPrintEnvFlag := fl.Bool("environ")
|
||||||
runCmdWatchFlag := fl.Bool("watch")
|
runCmdWatchFlag := fl.Bool("watch")
|
||||||
|
runCmdPidfileFlag := fl.String("pidfile")
|
||||||
runCmdPingbackFlag := fl.String("pingback")
|
runCmdPingbackFlag := fl.String("pingback")
|
||||||
|
|
||||||
// if we are supposed to print the environment, do that first
|
// if we are supposed to print the environment, do that first
|
||||||
|
@ -225,6 +230,16 @@ func cmdRun(fl Flags) (int, error) {
|
||||||
go watchConfigFile(configFile, runCmdConfigAdapterFlag)
|
go watchConfigFile(configFile, runCmdConfigAdapterFlag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create pidfile
|
||||||
|
if runCmdPidfileFlag != "" {
|
||||||
|
err := caddy.PIDFile(runCmdPidfileFlag)
|
||||||
|
if err != nil {
|
||||||
|
caddy.Log().Error("unable to write PID file",
|
||||||
|
zap.String("pidfile", runCmdPidfileFlag),
|
||||||
|
zap.Error(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// warn if the environment does not provide enough information about the disk
|
// warn if the environment does not provide enough information about the disk
|
||||||
hasXDG := os.Getenv("XDG_DATA_HOME") != "" &&
|
hasXDG := os.Getenv("XDG_DATA_HOME") != "" &&
|
||||||
os.Getenv("XDG_CONFIG_HOME") != "" &&
|
os.Getenv("XDG_CONFIG_HOME") != "" &&
|
||||||
|
|
|
@ -74,7 +74,7 @@ func init() {
|
||||||
RegisterCommand(Command{
|
RegisterCommand(Command{
|
||||||
Name: "start",
|
Name: "start",
|
||||||
Func: cmdStart,
|
Func: cmdStart,
|
||||||
Usage: "[--config <path> [--adapter <name>]] [--watch]",
|
Usage: "[--config <path> [--adapter <name>]] [--watch] [--pidfile <file>]",
|
||||||
Short: "Starts the Caddy process in the background and then returns",
|
Short: "Starts the Caddy process in the background and then returns",
|
||||||
Long: `
|
Long: `
|
||||||
Starts the Caddy process, optionally bootstrapped with an initial config file.
|
Starts the Caddy process, optionally bootstrapped with an initial config file.
|
||||||
|
@ -87,6 +87,7 @@ using 'caddy run' instead to keep it in the foreground.`,
|
||||||
fs := flag.NewFlagSet("start", flag.ExitOnError)
|
fs := flag.NewFlagSet("start", 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("pidfile", "", "Path of file to which to write process ID")
|
||||||
fs.Bool("watch", false, "Reload changed config file automatically")
|
fs.Bool("watch", false, "Reload changed config file automatically")
|
||||||
return fs
|
return fs
|
||||||
}(),
|
}(),
|
||||||
|
@ -95,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] [--watch]",
|
Usage: "[--config <path> [--adapter <name>]] [--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,
|
||||||
|
@ -132,6 +133,7 @@ development environment.`,
|
||||||
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")
|
||||||
|
fs.String("pidfile", "", "Path of file to which to write process ID")
|
||||||
fs.String("pingback", "", "Echo confirmation bytes to this address on success")
|
fs.String("pingback", "", "Echo confirmation bytes to this address on success")
|
||||||
return fs
|
return fs
|
||||||
}(),
|
}(),
|
||||||
|
|
Loading…
Reference in New Issue