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"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/pprof"
|
||||
|
@ -546,13 +547,6 @@ func handleUnload(w http.ResponseWriter, r *http.Request) error {
|
|||
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")
|
||||
if err := stopAndCleanup(); err != nil {
|
||||
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
|
||||
// in the config. It also matches adjacent commas so that syntax
|
||||
// can be preserved no matter where in the object the field appears.
|
||||
// It supports string and most numeric values.
|
||||
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 (
|
||||
rawConfigKey = "config"
|
||||
idKey = "@id"
|
||||
|
|
3
caddy.go
3
caddy.go
|
@ -470,6 +470,9 @@ func stopAndCleanup() error {
|
|||
return err
|
||||
}
|
||||
certmagic.CleanUpOwnLocks()
|
||||
if pidfile != "" {
|
||||
os.Remove(pidfile)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ import (
|
|||
func cmdStart(fl Flags) (int, error) {
|
||||
startCmdConfigFlag := fl.String("config")
|
||||
startCmdConfigAdapterFlag := fl.String("adapter")
|
||||
startCmdPidfileFlag := fl.String("pidfile")
|
||||
startCmdWatchFlag := fl.Bool("watch")
|
||||
|
||||
// open a listener to which the child process will connect when
|
||||
|
@ -71,6 +72,9 @@ func cmdStart(fl Flags) (int, error) {
|
|||
if startCmdWatchFlag {
|
||||
cmd.Args = append(cmd.Args, "--watch")
|
||||
}
|
||||
if startCmdPidfileFlag != "" {
|
||||
cmd.Args = append(cmd.Args, "--pidfile", startCmdPidfileFlag)
|
||||
}
|
||||
stdinpipe, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
return caddy.ExitCodeFailedStartup,
|
||||
|
@ -149,6 +153,7 @@ func cmdRun(fl Flags) (int, error) {
|
|||
runCmdResumeFlag := fl.Bool("resume")
|
||||
runCmdPrintEnvFlag := fl.Bool("environ")
|
||||
runCmdWatchFlag := fl.Bool("watch")
|
||||
runCmdPidfileFlag := fl.String("pidfile")
|
||||
runCmdPingbackFlag := fl.String("pingback")
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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
|
||||
hasXDG := os.Getenv("XDG_DATA_HOME") != "" &&
|
||||
os.Getenv("XDG_CONFIG_HOME") != "" &&
|
||||
|
|
|
@ -74,7 +74,7 @@ func init() {
|
|||
RegisterCommand(Command{
|
||||
Name: "start",
|
||||
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",
|
||||
Long: `
|
||||
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.String("config", "", "Configuration file")
|
||||
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")
|
||||
return fs
|
||||
}(),
|
||||
|
@ -95,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] [--watch]",
|
||||
Usage: "[--config <path> [--adapter <name>]] [--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,
|
||||
|
@ -132,6 +133,7 @@ development environment.`,
|
|||
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")
|
||||
fs.String("pidfile", "", "Path of file to which to write process ID")
|
||||
fs.String("pingback", "", "Echo confirmation bytes to this address on success")
|
||||
return fs
|
||||
}(),
|
||||
|
|
Loading…
Reference in New Issue