Commit 9e2cef38 authored by Matthew Holt's avatar Matthew Holt

Write pidfile only if server starts successfully

Whether the original parent process or a child process as part of a restart, the pidfile will not be written/changed until that process has started successfully. It is written every time caddy.Start() succeeds (may be reundant, but that's probably okay).
parent 33b1d4c5
...@@ -23,6 +23,7 @@ import ( ...@@ -23,6 +23,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log"
"net" "net"
"os" "os"
"path" "path"
...@@ -44,6 +45,9 @@ var ( ...@@ -44,6 +45,9 @@ var (
// HTTP2 indicates whether HTTP2 is enabled or not // HTTP2 indicates whether HTTP2 is enabled or not
HTTP2 bool // TODO: temporary flag until http2 is standard HTTP2 bool // TODO: temporary flag until http2 is standard
// PidFile is the path to the pidfile to create
PidFile string
) )
var ( var (
...@@ -72,8 +76,8 @@ var ( ...@@ -72,8 +76,8 @@ var (
// variable is not safe for concurrent access. // variable is not safe for concurrent access.
loadedGob caddyfileGob loadedGob caddyfileGob
// startedBefore should be set to true if caddy has been // startedBefore should be set to true if caddy has been started
// started at least once. // at least once (does not indicate whether currently running).
startedBefore bool startedBefore bool
) )
...@@ -99,9 +103,18 @@ const ( ...@@ -99,9 +103,18 @@ const (
// In any case, an error is returned if Caddy could not be // In any case, an error is returned if Caddy could not be
// started. // started.
func Start(cdyfile Input) (err error) { func Start(cdyfile Input) (err error) {
defer func() { signalParent(err == nil) }() // When we return, tell the parent whether we started
// successfully, and if so, write the pidfile (if enabled)
// TODO: What if already started -- is that an error? defer func() {
success := err == nil
signalParent(success)
if success && PidFile != "" {
err := writePidFile()
if err != nil {
log.Printf("[ERROR] Could not write pidfile: %v", err)
}
}
}()
// Input must never be nil; try to load something // Input must never be nil; try to load something
if cdyfile == nil { if cdyfile == nil {
......
...@@ -3,6 +3,7 @@ package caddy ...@@ -3,6 +3,7 @@ package caddy
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io/ioutil"
"os" "os"
"os/exec" "os/exec"
"runtime" "runtime"
...@@ -67,6 +68,12 @@ func IsRestart() bool { ...@@ -67,6 +68,12 @@ func IsRestart() bool {
return os.Getenv("CADDY_RESTART") == "true" return os.Getenv("CADDY_RESTART") == "true"
} }
// writePidFile writes the process ID to the file at PidFile, if specified.
func writePidFile() error {
pid := []byte(strconv.Itoa(os.Getpid()) + "\n")
return ioutil.WriteFile(PidFile, pid, 0644)
}
// CaddyfileInput represents a Caddyfile as input // CaddyfileInput represents a Caddyfile as input
// and is simply a convenient way to implement // and is simply a convenient way to implement
// the Input interface. // the Input interface.
......
...@@ -19,7 +19,6 @@ var ( ...@@ -19,7 +19,6 @@ var (
conf string conf string
cpu string cpu string
logfile string logfile string
pidfile string
revoke string revoke string
version bool version bool
) )
...@@ -38,7 +37,7 @@ func init() { ...@@ -38,7 +37,7 @@ func init() {
flag.StringVar(&caddy.Host, "host", caddy.DefaultHost, "Default host") flag.StringVar(&caddy.Host, "host", caddy.DefaultHost, "Default host")
flag.BoolVar(&caddy.HTTP2, "http2", true, "HTTP/2 support") // TODO: temporary flag until http2 merged into std lib flag.BoolVar(&caddy.HTTP2, "http2", true, "HTTP/2 support") // TODO: temporary flag until http2 merged into std lib
flag.StringVar(&logfile, "log", "", "Process log file") flag.StringVar(&logfile, "log", "", "Process log file")
flag.StringVar(&pidfile, "pidfile", "", "Path to write pid file") flag.StringVar(&caddy.PidFile, "pidfile", "", "Path to write pid file")
flag.StringVar(&caddy.Port, "port", caddy.DefaultPort, "Default port") flag.StringVar(&caddy.Port, "port", caddy.DefaultPort, "Default port")
flag.BoolVar(&caddy.Quiet, "quiet", false, "Quiet mode (no initialization output)") flag.BoolVar(&caddy.Quiet, "quiet", false, "Quiet mode (no initialization output)")
flag.StringVar(&revoke, "revoke", "", "Hostname for which to revoke the certificate") flag.StringVar(&revoke, "revoke", "", "Hostname for which to revoke the certificate")
...@@ -68,13 +67,6 @@ func main() { ...@@ -68,13 +67,6 @@ func main() {
log.SetOutput(file) log.SetOutput(file)
} }
if pidfile != "" {
pid := []byte(strconv.Itoa(os.Getpid()) + "\n")
err := ioutil.WriteFile(pidfile, pid, 0644)
if err != nil {
log.Fatal(err)
}
}
if revoke != "" { if revoke != "" {
err := letsencrypt.Revoke(revoke) err := letsencrypt.Revoke(revoke)
if err != nil { if err != nil {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment