diff --git a/caddy/caddy.go b/caddy/caddy.go index 9e5fcf3c..91561602 100644 --- a/caddy/caddy.go +++ b/caddy/caddy.go @@ -52,6 +52,11 @@ var ( // GracefulTimeout is the maximum duration of a graceful shutdown. GracefulTimeout time.Duration + + // RestartMode is the mode used for restart, + // "inproc" will restart in process, + // otherwise default behavior is used (inproc on Windows, fork on Linux). + RestartMode = "" ) var ( diff --git a/caddy/restart.go b/caddy/restart.go index cc1ac516..99dab19e 100644 --- a/caddy/restart.go +++ b/caddy/restart.go @@ -25,6 +25,10 @@ func init() { // downtime if on a POSIX-compatible system, or forcefully if on // Windows but with imperceptibly-short downtime. // +// The behavior can be controlled by the RestartMode variable, +// where "inproc" will restart forcefully in process same as +// Windows on a POSIX-compatible system. +// // The restarted application will use newCaddyfile as its input // configuration. If newCaddyfile is nil, the current (existing) // Caddyfile configuration will be used. @@ -48,6 +52,10 @@ func Restart(newCaddyfile Input) error { return errors.New("TLS preload: " + err.Error()) } + if RestartMode == "inproc" { + return restartInProc(newCaddyfile) + } + if len(os.Args) == 0 { // this should never happen, but... os.Args = []string{""} } @@ -164,3 +172,22 @@ func getCertsForNewCaddyfile(newCaddyfile Input) error { return nil } + +// restartInProc restarts Caddy forcefully in process using newCaddyfile. +func restartInProc(newCaddyfile Input) error { + wg.Add(1) // barrier so Wait() doesn't unblock + + err := Stop() + if err != nil { + return err + } + + err = Start(newCaddyfile) + if err != nil { + return err + } + + wg.Done() // take down our barrier + + return nil +} diff --git a/main.go b/main.go index abb1b3f3..c07e0161 100644 --- a/main.go +++ b/main.go @@ -33,6 +33,7 @@ func init() { flag.StringVar(&caddy.PidFile, "pidfile", "", "Path to write pid file") flag.StringVar(&caddy.Port, "port", caddy.DefaultPort, "Default port") flag.BoolVar(&caddy.Quiet, "quiet", false, "Quiet mode (no initialization output)") + flag.StringVar(&caddy.RestartMode, "restart", "", "Restart mode (inproc for in process restart)") flag.StringVar(&revoke, "revoke", "", "Hostname for which to revoke the certificate") flag.StringVar(&caddy.Root, "root", caddy.DefaultRoot, "Root path to default site") flag.BoolVar(&version, "version", false, "Show version")