summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--admin.go23
-rw-r--r--caddy.go3
-rw-r--r--cmd/commandfuncs.go15
-rw-r--r--cmd/commands.go6
4 files changed, 38 insertions, 9 deletions
diff --git a/admin.go b/admin.go
index 1d19066..e584a3b 100644
--- a/admin.go
+++ b/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"
diff --git a/caddy.go b/caddy.go
index 1184bc9..0092641 100644
--- a/caddy.go
+++ b/caddy.go
@@ -470,6 +470,9 @@ func stopAndCleanup() error {
return err
}
certmagic.CleanUpOwnLocks()
+ if pidfile != "" {
+ os.Remove(pidfile)
+ }
return nil
}
diff --git a/cmd/commandfuncs.go b/cmd/commandfuncs.go
index efdcfdc..f9e1033 100644
--- a/cmd/commandfuncs.go
+++ b/cmd/commandfuncs.go
@@ -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") != "" &&
diff --git a/cmd/commands.go b/cmd/commands.go
index e02f6a0..5a40b1d 100644
--- a/cmd/commands.go
+++ b/cmd/commands.go
@@ -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
}(),