Add System-V support

This commit is contained in:
Julien Vehent
2014-04-21 09:09:51 -04:00
parent 8858ef8413
commit 6c04ccb76d
+150 -4
View File
@@ -1,6 +1,7 @@
package service
import (
"bufio"
"fmt"
"log/syslog"
"os"
@@ -12,13 +13,17 @@ import (
)
const (
initUpstart = initFlavor(iota)
initSystemV = initFlavor(iota)
initUpstart
initSystemd
)
func newService(name, displayName, description string) (Service, error) {
flavor := initUpstart
if _, err := os.Stat("/run/systemd/system"); err == nil {
flavor := initSystemV
if isUpstart() {
flavor = initUpstart
}
if isSystemd() {
flavor = initSystemd
}
s := &linuxService{
@@ -37,6 +42,32 @@ func newService(name, displayName, description string) (Service, error) {
return s, nil
}
func isUpstart() bool {
f, err := os.Open("/etc/lsb-release")
if err != nil {
return false
}
defer f.Close()
r := bufio.NewReader(f)
scanner := bufio.NewScanner(r)
for scanner.Scan() {
if scanner.Text() == "DISTRIB_ID=Ubuntu" {
return true
}
}
if err := scanner.Err(); err != nil {
return false
}
return false
}
func isSystemd() bool {
if _, err := os.Stat("/run/systemd/system"); err == nil {
return true
}
return false
}
type linuxService struct {
flavor initFlavor
name, displayName, description string
@@ -47,6 +78,8 @@ type initFlavor uint8
func (f initFlavor) String() string {
switch f {
case initSystemV:
return "System-V"
case initUpstart:
return "Upstart"
case initSystemd:
@@ -58,6 +91,8 @@ func (f initFlavor) String() string {
func (f initFlavor) ConfigPath(name string) string {
switch f {
case initSystemV:
return "/etc/init.d/" + name
case initUpstart:
return "/etc/init/" + name + ".conf"
case initSystemd:
@@ -70,6 +105,8 @@ func (f initFlavor) ConfigPath(name string) string {
func (f initFlavor) GetTemplate() *template.Template {
var templ string
switch f {
case initSystemV:
templ = systemVScript
case initUpstart:
templ = upstartScript
case initSystemd:
@@ -107,11 +144,26 @@ func (s *linuxService) Install() error {
}
err = s.flavor.GetTemplate().Execute(f, to)
if err != nil {
return err
}
if s.flavor == initSystemV {
if err = os.Chmod(confPath, 0755); err != nil {
return err
}
for _, i := range [...]string{"2", "3", "4", "5"} {
if err = os.Symlink(confPath, "/etc/rc"+i+".d/S50"+s.name); err != nil {
continue
}
}
for _, i := range [...]string{"0", "1", "6"} {
if err = os.Symlink(confPath, "/etc/rc"+i+".d/K02"+s.name); err != nil {
continue
}
}
}
if s.flavor == initSystemd {
return exec.Command("systemctl", "daemon-reload").Run()
}
@@ -165,6 +217,100 @@ func (s *linuxService) Info(format string, a ...interface{}) error {
return s.logger.Info(fmt.Sprintf(format, a...))
}
const systemVScript = `#!/bin/sh
# For RedHat and cousins:
# chkconfig: - 99 01
# description: {{.Description}}
# processname: {{.Path}}
### BEGIN INIT INFO
# Provides: {{.Path}}
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: {{.Display}}
# Description: {{.Description}}
### END INIT INFO
cmd="{{.Path}}"
name=$(basename $0)
pid_file="/var/run/$name.pid"
stdout_log="/var/log/$name.log"
stderr_log="/var/log/$name.err"
get_pid() {
cat "$pid_file"
}
is_running() {
[ -f "$pid_file" ] && ps $(get_pid) > /dev/null 2>&1
}
case "$1" in
start)
if is_running; then
echo "Already started"
else
echo "Starting $name"
$cmd >> "$stdout_log" 2>> "$stderr_log" &
echo $! > "$pid_file"
if ! is_running; then
echo "Unable to start, see $stdout_log and $stderr_log"
exit 1
fi
fi
;;
stop)
if is_running; then
echo -n "Stopping $name.."
kill $(get_pid)
for i in {1..10}
do
if ! is_running; then
break
fi
echo -n "."
sleep 1
done
echo
if is_running; then
echo "Not stopped; may still be shutting down or shutdown may have failed"
exit 1
else
echo "Stopped"
if [ -f "$pid_file" ]; then
rm "$pid_file"
fi
fi
else
echo "Not running"
fi
;;
restart)
$0 stop
if is_running; then
echo "Unable to stop, will not attempt to start"
exit 1
fi
$0 start
;;
status)
if is_running; then
echo "Running"
else
echo "Stopped"
exit 1
fi
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
exit 0`
const upstartScript = `# {{.Description}}
description "{{.Display}}"