Files
service/service_linux.go
T
Daniel Theophanes c880387dea service: break out each linux service into its own file.
Breaking apart each service reduces the overall number of branches
in the code, but increases duplication. Duplication can be taken
care of in follow-up commits while still keeping the clarity of
linear code.

Also expiriment with code that would allow the user to add or remove
systems. Still expirimental and not exposed in the API.
2015-03-08 17:29:10 -07:00

122 lines
2.4 KiB
Go

// Copyright 2015 Daniel Theophanes.
// Use of this source code is governed by a zlib-style
// license that can be found in the LICENSE file.package service
package service
import (
"errors"
"fmt"
"os"
"strings"
)
type newServiceFunc func(i Interface, c *Config) (Service, error)
type linuxSystem struct {
interactive bool
selectedName string
selectedNew newServiceFunc
}
func (ls linuxSystem) String() string {
return fmt.Sprintf("Linux %s", ls.selectedName)
}
func (ls linuxSystem) Interactive() bool {
return ls.interactive
}
type systemChoice interface {
Name() string
Detect() bool
Interactive() bool
New(i Interface, c *Config) (Service, error)
}
type linuxSystemChoice struct {
name string
detect func() bool
interactive func() bool
new func(i Interface, c *Config) (Service, error)
}
func (sc linuxSystemChoice) Name() string {
return sc.name
}
func (sc linuxSystemChoice) Detect() bool {
return sc.detect()
}
func (sc linuxSystemChoice) Interactive() bool {
return sc.interactive()
}
func (sc linuxSystemChoice) New(i Interface, c *Config) (Service, error) {
return sc.new(i, c)
}
var systemRegistry = []systemChoice{
linuxSystemChoice{
name: "systemd",
detect: isSystemd,
interactive: func() bool {
is, _ := isInteractive()
return is
},
new: newSystemdService,
},
linuxSystemChoice{
name: "Upstart",
detect: isUpstart,
interactive: func() bool {
is, _ := isInteractive()
return is
},
new: newUpstartService,
},
linuxSystemChoice{
name: "System-V",
detect: func() bool { return true },
interactive: func() bool {
is, _ := isInteractive()
return is
},
new: newSystemVService,
},
}
func newLinuxSystem() linuxSystem {
for _, choice := range systemRegistry {
if choice.Detect() == false {
continue
}
return linuxSystem{
interactive: choice.Interactive(),
selectedName: choice.Name(),
selectedNew: choice.New,
}
}
return linuxSystem{}
}
var system = newLinuxSystem()
var errNoServiceSystemDetected = errors.New("No service system detected.")
func newService(i Interface, c *Config) (Service, error) {
if system.selectedNew == nil {
return nil, errNoServiceSystemDetected
}
return system.selectedNew(i, c)
}
func isInteractive() (bool, error) {
// TODO: This is not true for user services.
return os.Getppid() != 1, nil
}
var tf = map[string]interface{}{
"cmd": func(s string) string {
return `"` + strings.Replace(s, `"`, `\"`, -1) + `"`
},
}