gitee.com/quant1x/gox@v1.21.2/daemon/daemon_linux_upstart.go (about) 1 // Copyright 2020 The Go Authors. All rights reserved. 2 // Use of this source code is governed by 3 // license that can be found in the LICENSE file. 4 5 package daemon 6 7 import ( 8 "os" 9 "os/exec" 10 "regexp" 11 "strings" 12 "text/template" 13 ) 14 15 // upstartRecord - standard record (struct) for linux upstart version of daemon package 16 type upstartRecord struct { 17 name string 18 description string 19 kind Kind 20 dependencies []string 21 } 22 23 // Standard service path for systemV daemons 24 func (linux *upstartRecord) servicePath() string { 25 return "/etc/init/" + linux.name + ".conf" 26 } 27 28 // Is a service installed 29 func (linux *upstartRecord) isInstalled() bool { 30 31 if _, err := os.Stat(linux.servicePath()); err == nil { 32 return true 33 } 34 35 return false 36 } 37 38 // Check service is running 39 func (linux *upstartRecord) checkRunning() (string, bool) { 40 output, err := exec.Command("status", linux.name).Output() 41 if err == nil { 42 if matched, err := regexp.MatchString(linux.name+" start/running", string(output)); err == nil && matched { 43 reg := regexp.MustCompile("process ([0-9]+)") 44 data := reg.FindStringSubmatch(string(output)) 45 if len(data) > 1 { 46 return "Service (pid " + data[1] + ") is running...", true 47 } 48 return "Service is running...", true 49 } 50 } 51 52 return "Service is stopped", false 53 } 54 55 // Install the service 56 func (linux *upstartRecord) Install(args ...string) (string, error) { 57 installAction := "Install " + linux.description + ":" 58 59 if ok, err := checkPrivileges(); !ok { 60 return installAction + failed, err 61 } 62 63 srvPath := linux.servicePath() 64 65 if linux.isInstalled() { 66 return installAction + failed, ErrAlreadyInstalled 67 } 68 69 file, err := os.Create(srvPath) 70 if err != nil { 71 return installAction + failed, err 72 } 73 defer file.Close() 74 75 execPatch, err := executablePath(linux.name) 76 if err != nil { 77 return installAction + failed, err 78 } 79 80 templ, err := template.New("upstatConfig").Parse(upstatConfig) 81 if err != nil { 82 return installAction + failed, err 83 } 84 85 if err := templ.Execute( 86 file, 87 &struct { 88 Name, Description, Path, Args string 89 }{linux.name, linux.description, execPatch, strings.Join(args, " ")}, 90 ); err != nil { 91 return installAction + failed, err 92 } 93 94 if err := os.Chmod(srvPath, 0755); err != nil { 95 return installAction + failed, err 96 } 97 98 return installAction + success, nil 99 } 100 101 // Remove the service 102 func (linux *upstartRecord) Remove() (string, error) { 103 removeAction := "Removing " + linux.description + ":" 104 105 if ok, err := checkPrivileges(); !ok { 106 return removeAction + failed, err 107 } 108 109 if !linux.isInstalled() { 110 return removeAction + failed, ErrNotInstalled 111 } 112 113 if err := os.Remove(linux.servicePath()); err != nil { 114 return removeAction + failed, err 115 } 116 117 return removeAction + success, nil 118 } 119 120 // Start the service 121 func (linux *upstartRecord) Start() (string, error) { 122 startAction := "Starting " + linux.description + ":" 123 124 if ok, err := checkPrivileges(); !ok { 125 return startAction + failed, err 126 } 127 128 if !linux.isInstalled() { 129 return startAction + failed, ErrNotInstalled 130 } 131 132 if _, ok := linux.checkRunning(); ok { 133 return startAction + failed, ErrAlreadyRunning 134 } 135 136 if err := exec.Command("start", linux.name).Run(); err != nil { 137 return startAction + failed, err 138 } 139 140 return startAction + success, nil 141 } 142 143 // Stop the service 144 func (linux *upstartRecord) Stop() (string, error) { 145 stopAction := "Stopping " + linux.description + ":" 146 147 if ok, err := checkPrivileges(); !ok { 148 return stopAction + failed, err 149 } 150 151 if !linux.isInstalled() { 152 return stopAction + failed, ErrNotInstalled 153 } 154 155 if _, ok := linux.checkRunning(); !ok { 156 return stopAction + failed, ErrAlreadyStopped 157 } 158 159 if err := exec.Command("stop", linux.name).Run(); err != nil { 160 return stopAction + failed, err 161 } 162 163 return stopAction + success, nil 164 } 165 166 // Status - Get service status 167 func (linux *upstartRecord) Status() (string, error) { 168 169 if ok, err := checkPrivileges(); !ok { 170 return "", err 171 } 172 173 if !linux.isInstalled() { 174 return statNotInstalled, ErrNotInstalled 175 } 176 177 statusAction, _ := linux.checkRunning() 178 179 return statusAction, nil 180 } 181 182 // Run - Run service 183 func (linux *upstartRecord) Run(e Executable) (string, error) { 184 runAction := "Running " + linux.description + ":" 185 e.Run() 186 return runAction + " completed.", nil 187 } 188 189 // GetTemplate - gets service config template 190 func (linux *upstartRecord) GetTemplate() string { 191 return upstatConfig 192 } 193 194 // SetTemplate - sets service config template 195 func (linux *upstartRecord) SetTemplate(tplStr string) error { 196 upstatConfig = tplStr 197 return nil 198 } 199 200 var upstatConfig = `# {{.Name}} {{.Description}} 201 202 description "{{.Description}}" 203 author "Pichu Chen <pichu@tih.tw>" 204 205 start on runlevel [2345] 206 stop on runlevel [016] 207 208 respawn 209 #kill timeout 5 210 211 exec {{.Path}} {{.Args}} >> /var/log/{{.Name}}.log 2>> /var/log/{{.Name}}.err 212 `