Files
service/stdservice/stdservice.go
T
Daniel Theophanes eb52bdfe36 all: run goimports.
2014-05-27 07:11:50 -07:00

154 lines
3.4 KiB
Go

/*
Many services that run on different platforms cannot rely
on flags to be passed for configuration. Some platforms
require explicit install commands. This package handles the common
boilerplate code. The following command may be passed to the
executable as the first argument:
install | remove | run | start | stop
These commands will do the following actions:
install - Install the running executable as a service on the system.
remove - Remove the running executable as a service on the system.
run - Run the service as a command line application, output log to prompt.
start - Starts the service via system controls.
stop - Stops the service via system controls.
*/
package stdservice
import (
"fmt"
"os"
"bitbucket.org/kardianos/service"
)
// Standard service configuration. Start MUST block.
// Stop MUST NOT block for more then a second or two.
type Config struct {
// Used to register the service with the operating system.
Name, DisplayName, LongDescription string
// Called when the service starts or stops.
// Stop may be nil.
Start, Stop func(c *Config)
// Called after logging may be setup but before the service is started.
// Init is optional and may be nil.
// If Init returns an error, that error is logged to the logger
// and the service start is aborted.
// Init should not block.
Init func(c *Config) error
s service.Service
l service.Logger
}
// Get service after Run() has been called.
func (c *Config) Service() service.Service {
return c.s
}
// Get logger after Run() has been called.
func (c *Config) Logger() service.Logger {
return c.l
}
// Fill in configuration, then call Run() to setup basic handling.
// Blocks until program completes. Is intended to handle the standard
// simple cases for running a service.
func (c *Config) Run() {
run(c)
}
// Depreciated. Same as *Config.Run().
func Run(c *Config) {
run(c)
}
func run(c *Config) {
var s, err = service.NewService(c.Name, c.DisplayName, c.LongDescription)
c.s = s
c.l = s
if err != nil {
fmt.Printf("%s unable to start: %s", c.DisplayName, err)
return
}
if len(os.Args) > 1 {
var err error
verb := os.Args[1]
switch verb {
case "install":
err = s.Install()
if err != nil {
fmt.Printf("Failed to install: %s\n", err)
return
}
fmt.Printf("Service \"%s\" installed.\n", c.DisplayName)
case "remove":
err = s.Remove()
if err != nil {
fmt.Printf("Failed to remove: %s\n", err)
return
}
fmt.Printf("Service \"%s\" removed.\n", c.DisplayName)
case "run":
c.l = ConsoleLogger{}
defer func() {
if c.Stop != nil {
c.Stop(c)
}
}()
if c.Init != nil {
err := c.Init(c)
if err != nil {
c.l.Error(err.Error())
return
}
}
c.Start(c)
case "start":
err = s.Start()
if err != nil {
fmt.Printf("Failed to start: %s\n", err)
return
}
fmt.Printf("Service \"%s\" started.\n", c.DisplayName)
case "stop":
err = s.Stop()
if err != nil {
fmt.Printf("Failed to stop: %s\n", err)
return
}
fmt.Printf("Service \"%s\" stopped.\n", c.DisplayName)
default:
fmt.Printf("Options for \"%s\": (install | remove | run | start | stop)\n", os.Args[0])
}
return
}
if c.Init != nil {
err := c.Init(c)
if err != nil {
c.l.Error(err.Error())
return
}
}
err = s.Run(func() error {
// start
go c.Start(c)
return nil
}, func() error {
// stop
if c.Stop != nil {
c.Stop(c)
}
return nil
})
if err != nil {
c.l.Error(err.Error())
}
}