caddy/startupshutdown/startupshutdown.go
Matthew Holt 15fa5cf2da
OnFirstStartup and OnFinalShutdown callbacks added
OnStartup and OnShutdown callbacks now run as part of restarts, too.
The startup and shutdown directives only run their commands NOT as part
of restarts, as before. Some middleware that use OnStartup may need to
switch to OnFirstStartup and implement OnFinalShutdown to do any cleanup
as needed.
2016-06-23 18:02:12 -06:00

71 lines
1.5 KiB
Go

package startupshutdown
import (
"os"
"os/exec"
"strings"
"github.com/mholt/caddy"
)
func init() {
caddy.RegisterPlugin("startup", caddy.Plugin{Action: Startup})
caddy.RegisterPlugin("shutdown", caddy.Plugin{Action: Shutdown})
}
// Startup registers a startup callback to execute during server start.
func Startup(c *caddy.Controller) error {
return registerCallback(c, c.OnFirstStartup)
}
// Shutdown registers a shutdown callback to execute during server stop.
func Shutdown(c *caddy.Controller) error {
return registerCallback(c, c.OnFinalShutdown)
}
// registerCallback registers a callback function to execute by
// using c to parse the directive. It registers the callback
// to be executed using registerFunc.
func registerCallback(c *caddy.Controller, registerFunc func(func() error)) error {
var funcs []func() error
for c.Next() {
args := c.RemainingArgs()
if len(args) == 0 {
return c.ArgErr()
}
nonblock := false
if len(args) > 1 && args[len(args)-1] == "&" {
// Run command in background; non-blocking
nonblock = true
args = args[:len(args)-1]
}
command, args, err := caddy.SplitCommandAndArgs(strings.Join(args, " "))
if err != nil {
return c.Err(err.Error())
}
fn := func() error {
cmd := exec.Command(command, args...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if nonblock {
return cmd.Start()
}
return cmd.Run()
}
funcs = append(funcs, fn)
}
return c.OncePerServerBlock(func() error {
for _, fn := range funcs {
registerFunc(fn)
}
return nil
})
}