From 1166804cbc514570610bf384eb10ff38db7c5f32 Mon Sep 17 00:00:00 2001 From: SteelPhase Date: Thu, 16 Aug 2018 18:04:58 -0400 Subject: [PATCH] update upstart script --- service.go | 21 +++++++++-- service_upstart_linux.go | 81 +++++++++++++++++++++++++++++----------- 2 files changed, 78 insertions(+), 24 deletions(-) diff --git a/service.go b/service.go index af90204..a4d5f28 100644 --- a/service.go +++ b/service.go @@ -75,12 +75,26 @@ const ( optionUserServiceDefault = false optionSessionCreate = "SessionCreate" optionSessionCreateDefault = false + optionLogOutput = "LogOutput" + optionLogOutputDefault = false optionRunWait = "RunWait" optionReloadSignal = "ReloadSignal" optionPIDFile = "PIDFile" ) +// Status represents service status as an interger value +type Status int + +// Status of service represented as an integer +const ( + StatusNotImplemented Status = iota + StatusUnknown + StatusError + StatusRunning + StatusStopped +) + // Config provides the setup for a Service. The Name field is required. type Config struct { Name string // Required name of the service. No spaces suggested. @@ -108,9 +122,10 @@ type Config struct { // - UserService bool (false) - Install as a current user service. // - 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. - // - PIDFile string () [/run/prog.pid] - Location of the PID file. + // - RunWait func() (wait for SIGNAL) - Do not install signal but wait for this function to return. + // - ReloadSignal string () [USR1, ...] - Signal to send on reaload. + // - PIDFile string () [/run/prog.pid] - Location of the PID file. + // - LogOutput bool (false) - Redirect StdErr & StdOut to files. Option KeyValue } diff --git a/service_upstart_linux.go b/service_upstart_linux.go index 4ec01ab..6715955 100644 --- a/service_upstart_linux.go +++ b/service_upstart_linux.go @@ -68,26 +68,11 @@ func (s *upstart) configPath() (cp string, err error) { func (s *upstart) hasKillStanza() bool { defaultValue := true - - out, err := exec.Command("/sbin/init", "--version").Output() - if err != nil { + version := s.getUpstartVersion() + if version == nil { return defaultValue } - re := regexp.MustCompile(`init \(upstart (\d+.\d+.\d+)\)`) - matches := re.FindStringSubmatch(string(out)) - if len(matches) != 2 { - return defaultValue - } - - version := make([]int, 3) - for idx, vStr := range strings.Split(matches[1], ".") { - version[idx], err = strconv.Atoi(vStr) - if err != nil { - return defaultValue - } - } - maxVersion := []int{0, 6, 5} if versionAtMost(version, maxVersion) { return false @@ -96,6 +81,43 @@ func (s *upstart) hasKillStanza() bool { return defaultValue } +func (s *upstart) hasSetUIDStanza() bool { + defaultValue := true + version := s.getUpstartVersion() + if version == nil { + return defaultValue + } + + maxVersion := []int{1, 4, 0} + if versionAtMost(version, maxVersion) { + return false + } + + return defaultValue +} + +func (s *upstart) getUpstartVersion() []int { + out, err := exec.Command("/sbin/init", "--version").Output() + if err != nil { + return nil + } + + re := regexp.MustCompile(`init \(upstart (\d+.\d+.\d+)\)`) + matches := re.FindStringSubmatch(string(out)) + if len(matches) != 2 { + return nil + } + + version := make([]int, 3) + for idx, vStr := range strings.Split(matches[1], ".") { + version[idx], err = strconv.Atoi(vStr) + if err != nil { + return nil + } + } + return version +} + func versionAtMost(version, max []int) bool { for idx, m := range max { v := version[idx] @@ -133,12 +155,16 @@ func (s *upstart) Install() error { var to = &struct { *Config - Path string - HasKillStanza bool + Path string + HasKillStanza bool + HasSetUIDStanza bool + LogOutput bool }{ s.Config, path, s.hasKillStanza(), + s.hasSetUIDStanza(), + s.Option.bool(optionLogOutput, optionLogOutputDefault), } return s.template().Execute(f, to) @@ -209,7 +235,7 @@ const upstartScript = `# {{.Description}} start on filesystem or runlevel [2345] stop on runlevel [!2345] -{{if .UserName}}setuid {{.UserName}}{{end}} +{{if and .UserName .HasSetUIDStanza}}setuid {{.UserName}}{{end}} respawn respawn limit 10 5 @@ -222,5 +248,18 @@ pre-start script end script # Start -exec {{.Path}}{{range .Arguments}} {{.|cmd}}{{end}} +script + {{if .LogOutput}} + stdout_log="/var/log/{{.Name}}.out" + stderr_log="/var/log/{{.Name}}.err" + {{end}} + + if [ -f "/etc/sysconfig/{{.Name}}" ]; then + set -a + source /etc/sysconfig/{{.Name}} + set +a + fi + + exec {{if and .UserName (not .HasSetUIDStanza)}}sudo -E -u {{.UserName}} {{end}}{{.Path}}{{range .Arguments}} {{.|cmd}}{{end}}{{if .LogOutput}} >> $stdout_log 2>> $stderr_log{{end}} +end script `