service: update API to allow for programs that install their own signal handlers.
This commit is contained in:
+21
-4
@@ -78,6 +78,9 @@ const (
|
|||||||
optionUserServiceDefault = false
|
optionUserServiceDefault = false
|
||||||
optionSessionCreate = "SessionCreate"
|
optionSessionCreate = "SessionCreate"
|
||||||
optionSessionCreateDefault = false
|
optionSessionCreateDefault = false
|
||||||
|
|
||||||
|
optionRunWait = "RunWait"
|
||||||
|
optionReloadSignal = "ReloadSignal"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config provides the setup for a Service. The Name field is required.
|
// Config provides the setup for a Service. The Name field is required.
|
||||||
@@ -106,6 +109,9 @@ type Config struct {
|
|||||||
// - RunAtLoad bool (false)
|
// - RunAtLoad bool (false)
|
||||||
// - UserService bool (false) - Install as a current user service.
|
// - UserService bool (false) - Install as a current user service.
|
||||||
// - SessionCreate bool (false) - Create a full user session.
|
// - SessionCreate bool (false) - Create a full user session.
|
||||||
|
// * POSIX
|
||||||
|
// - RunWait func() (wait for SIGNAL) - Do not install signal but wait for this function to return.
|
||||||
|
// - ReloadSignal string () [USR1, ...] - Signal to send on reaload.
|
||||||
Option KeyValue
|
Option KeyValue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +149,7 @@ func New(i Interface, c *Config) (Service, error) {
|
|||||||
// more details.
|
// more details.
|
||||||
type KeyValue map[string]interface{}
|
type KeyValue map[string]interface{}
|
||||||
|
|
||||||
// Bool returns the value of the given name, assuming the value is a boolean.
|
// bool returns the value of the given name, assuming the value is a boolean.
|
||||||
// If the value isn't found or is not of the type, the defaultValue is returned.
|
// If the value isn't found or is not of the type, the defaultValue is returned.
|
||||||
func (kv KeyValue) bool(name string, defaultValue bool) bool {
|
func (kv KeyValue) bool(name string, defaultValue bool) bool {
|
||||||
if v, found := kv[name]; found {
|
if v, found := kv[name]; found {
|
||||||
@@ -154,7 +160,7 @@ func (kv KeyValue) bool(name string, defaultValue bool) bool {
|
|||||||
return defaultValue
|
return defaultValue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int returns the value of the given name, assuming the value is an int.
|
// int returns the value of the given name, assuming the value is an int.
|
||||||
// If the value isn't found or is not of the type, the defaultValue is returned.
|
// If the value isn't found or is not of the type, the defaultValue is returned.
|
||||||
func (kv KeyValue) int(name string, defaultValue int) int {
|
func (kv KeyValue) int(name string, defaultValue int) int {
|
||||||
if v, found := kv[name]; found {
|
if v, found := kv[name]; found {
|
||||||
@@ -165,7 +171,7 @@ func (kv KeyValue) int(name string, defaultValue int) int {
|
|||||||
return defaultValue
|
return defaultValue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int returns the value of the given name, assuming the value is a string.
|
// string returns the value of the given name, assuming the value is a string.
|
||||||
// If the value isn't found or is not of the type, the defaultValue is returned.
|
// If the value isn't found or is not of the type, the defaultValue is returned.
|
||||||
func (kv KeyValue) string(name string, defaultValue string) string {
|
func (kv KeyValue) string(name string, defaultValue string) string {
|
||||||
if v, found := kv[name]; found {
|
if v, found := kv[name]; found {
|
||||||
@@ -176,7 +182,7 @@ func (kv KeyValue) string(name string, defaultValue string) string {
|
|||||||
return defaultValue
|
return defaultValue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int returns the value of the given name, assuming the value is a float64.
|
// float64 returns the value of the given name, assuming the value is a float64.
|
||||||
// If the value isn't found or is not of the type, the defaultValue is returned.
|
// If the value isn't found or is not of the type, the defaultValue is returned.
|
||||||
func (kv KeyValue) float64(name string, defaultValue float64) float64 {
|
func (kv KeyValue) float64(name string, defaultValue float64) float64 {
|
||||||
if v, found := kv[name]; found {
|
if v, found := kv[name]; found {
|
||||||
@@ -187,6 +193,17 @@ func (kv KeyValue) float64(name string, defaultValue float64) float64 {
|
|||||||
return defaultValue
|
return defaultValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// funcSingle returns the value of the given name, assuming the value is a float64.
|
||||||
|
// If the value isn't found or is not of the type, the defaultValue is returned.
|
||||||
|
func (kv KeyValue) funcSingle(name string, defaultValue func()) func() {
|
||||||
|
if v, found := kv[name]; found {
|
||||||
|
if castValue, is := v.(func()); is {
|
||||||
|
return castValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
// Platform returns a description of the system service.
|
// Platform returns a description of the system service.
|
||||||
func Platform() string {
|
func Platform() string {
|
||||||
if system == nil {
|
if system == nil {
|
||||||
|
|||||||
+5
-5
@@ -196,11 +196,11 @@ func (s *darwinLaunchdService) Run() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var sigChan = make(chan os.Signal, 3)
|
s.Option.funcSingle(optionRunWait, func() {
|
||||||
|
var sigChan = make(chan os.Signal, 3)
|
||||||
signal.Notify(sigChan, syscall.SIGTERM, os.Interrupt)
|
signal.Notify(sigChan, syscall.SIGTERM, os.Interrupt)
|
||||||
|
<-sigChan
|
||||||
<-sigChan
|
})()
|
||||||
|
|
||||||
return s.i.Stop(s)
|
return s.i.Stop(s)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,9 +80,11 @@ func (s *systemd) Install() error {
|
|||||||
var to = &struct {
|
var to = &struct {
|
||||||
*Config
|
*Config
|
||||||
Path string
|
Path string
|
||||||
|
ReloadSignal string
|
||||||
}{
|
}{
|
||||||
s.Config,
|
s.Config,
|
||||||
path,
|
path,
|
||||||
|
s.Option.string(optionReloadSignal, ""),
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.template().Execute(f, to)
|
err = s.template().Execute(f, to)
|
||||||
@@ -128,11 +130,11 @@ func (s *systemd) Run() (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
sigChan := make(chan os.Signal, 3)
|
s.Option.funcSingle(optionRunWait, func() {
|
||||||
|
var sigChan = make(chan os.Signal, 3)
|
||||||
signal.Notify(sigChan, syscall.SIGTERM, os.Interrupt)
|
signal.Notify(sigChan, syscall.SIGTERM, os.Interrupt)
|
||||||
|
<-sigChan
|
||||||
<-sigChan
|
})()
|
||||||
|
|
||||||
return s.i.Stop(s)
|
return s.i.Stop(s)
|
||||||
}
|
}
|
||||||
@@ -160,6 +162,7 @@ ExecStart={{.Path|cmdEscape}}{{range .Arguments}} {{.|cmd}}{{end}}
|
|||||||
{{if .ChRoot}}RootDirectory={{.ChRoot|cmd}}{{end}}
|
{{if .ChRoot}}RootDirectory={{.ChRoot|cmd}}{{end}}
|
||||||
{{if .WorkingDirectory}}WorkingDirectory={{.WorkingDirectory|cmd}}{{end}}
|
{{if .WorkingDirectory}}WorkingDirectory={{.WorkingDirectory|cmd}}{{end}}
|
||||||
{{if .UserName}}User={{.UserName}}{{end}}
|
{{if .UserName}}User={{.UserName}}{{end}}
|
||||||
|
{{if .ReloadSignal}}ExecReload=/bin/kill -{{.ReloadSignal}} "$MAINPID"{{end}}
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=120
|
RestartSec=120
|
||||||
|
|
||||||
|
|||||||
@@ -127,11 +127,11 @@ func (s *sysv) Run() (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
sigChan := make(chan os.Signal, 3)
|
s.Option.funcSingle(optionRunWait, func() {
|
||||||
|
var sigChan = make(chan os.Signal, 3)
|
||||||
signal.Notify(sigChan, syscall.SIGTERM, os.Interrupt)
|
signal.Notify(sigChan, syscall.SIGTERM, os.Interrupt)
|
||||||
|
<-sigChan
|
||||||
<-sigChan
|
})()
|
||||||
|
|
||||||
return s.i.Stop(s)
|
return s.i.Stop(s)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,11 +117,11 @@ func (s *upstart) Run() (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
sigChan := make(chan os.Signal, 3)
|
s.Option.funcSingle(optionRunWait, func() {
|
||||||
|
var sigChan = make(chan os.Signal, 3)
|
||||||
signal.Notify(sigChan, os.Interrupt, os.Kill)
|
signal.Notify(sigChan, os.Interrupt, os.Kill)
|
||||||
|
<-sigChan
|
||||||
<-sigChan
|
})()
|
||||||
|
|
||||||
return s.i.Stop(s)
|
return s.i.Stop(s)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user