1 Star 0 Fork 0

baetyl / service

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
service_aix.go 5.24 KB
一键复制 编辑 原始数据 按行查看 历史
//+build aix
// 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
import (
"bytes"
"errors"
"fmt"
"os"
"os/exec"
"os/signal"
"regexp"
"strconv"
"strings"
"syscall"
"text/template"
"time"
)
const maxPathSize = 32 * 1024
const version = "aix-ssrc"
type aixSystem struct{}
func (aixSystem) String() string {
return version
}
func (aixSystem) Detect() bool {
return true
}
func (aixSystem) Interactive() bool {
return interactive
}
func (aixSystem) New(i Interface, c *Config) (Service, error) {
s := &aixService{
i: i,
Config: c,
}
return s, nil
}
func getArgsFromPid(pid int) string {
cmd := exec.Command("ps", "-o", "args", "-p", strconv.Itoa(pid))
var out bytes.Buffer
cmd.Stdout = &out
if err := cmd.Run(); err == nil {
lines := strings.Split(out.String(), "\n")
if len(lines) > 1 {
return strings.TrimSpace(lines[1])
}
}
return ""
}
func init() {
ChooseSystem(aixSystem{})
}
var interactive = false
func init() {
var err error
interactive, err = isInteractive()
if err != nil {
panic(err)
}
}
func isInteractive() (bool, error) {
// The parent process of a service process should be srcmstr.
return getArgsFromPid(os.Getppid()) != "/usr/sbin/srcmstr", nil
}
type aixService struct {
i Interface
*Config
}
func (s *aixService) String() string {
if len(s.DisplayName) > 0 {
return s.DisplayName
}
return s.Name
}
func (s *aixService) Platform() string {
return version
}
func (s *aixService) template() *template.Template {
functions := template.FuncMap{
"bool": func(v bool) string {
if v {
return "true"
}
return "false"
},
}
customConfig := s.Option.string(optionSysvScript, "")
if customConfig != "" {
return template.Must(template.New("").Funcs(functions).Parse(customConfig))
} else {
return template.Must(template.New("").Funcs(functions).Parse(svcConfig))
}
}
func (s *aixService) configPath() (cp string, err error) {
cp = "/etc/rc.d/init.d/" + s.Config.Name
return
}
func (s *aixService) Install() error {
// install service
path, err := s.execPath()
if err != nil {
return err
}
err = run("mkssys", "-s", s.Name, "-p", path, "-u", "0", "-R", "-Q", "-S", "-n", "15", "-f", "9", "-d", "-w", "30")
if err != nil {
return err
}
// write start script
confPath, err := s.configPath()
if err != nil {
return err
}
_, err = os.Stat(confPath)
if err == nil {
return fmt.Errorf("Init already exists: %s", confPath)
}
f, err := os.Create(confPath)
if err != nil {
return err
}
defer f.Close()
var to = &struct {
*Config
Path string
}{
s.Config,
path,
}
err = s.template().Execute(f, to)
if err != nil {
return err
}
if err = os.Chmod(confPath, 0755); err != nil {
return err
}
rcd := "/etc/rc"
if _, err = os.Stat("/etc/rc.d/rc2.d"); err == nil {
rcd = "/etc/rc.d/rc"
}
for _, i := range [...]string{"2", "3"} {
if err = os.Symlink(confPath, rcd+i+".d/S50"+s.Name); err != nil {
continue
}
if err = os.Symlink(confPath, rcd+i+".d/K02"+s.Name); err != nil {
continue
}
}
return nil
}
func (s *aixService) Uninstall() error {
s.Stop()
err := run("rmssys", "-s", s.Name)
if err != nil {
return err
}
confPath, err := s.configPath()
if err != nil {
return err
}
return os.Remove(confPath)
}
func (s *aixService) Status() (Status, error) {
exitCode, out, err := runWithOutput("lssrc", "-s", s.Name)
if exitCode == 0 && err != nil {
if !strings.Contains(err.Error(), "failed with stderr") {
return StatusUnknown, err
}
}
re := regexp.MustCompile(`\s+` + s.Name + `\s+(\w+\s+)?(\d+\s+)?(\w+)`)
matches := re.FindStringSubmatch(out)
if len(matches) == 4 {
status := string(matches[3])
if status == "inoperative" {
return StatusStopped, nil
} else if status == "active" {
return StatusRunning, nil
} else {
fmt.Printf("Got unknown service status %s\n", status)
return StatusUnknown, err
}
}
confPath, err := s.configPath()
if err != nil {
return StatusUnknown, err
}
if _, err = os.Stat(confPath); err == nil {
return StatusStopped, nil
}
return StatusUnknown, ErrNotInstalled
}
func (s *aixService) GetPid() (uint32, error) {
return 0, errors.New("not implemented yet")
}
func (s *aixService) Start() error {
return run("startsrc", "-s", s.Name)
}
func (s *aixService) Stop() error {
return run("stopsrc", "-s", s.Name)
}
func (s *aixService) Restart() error {
err := s.Stop()
if err != nil {
return err
}
time.Sleep(50 * time.Millisecond)
return s.Start()
}
func (s *aixService) Run() error {
var err error
err = s.i.Start(s)
if err != nil {
return err
}
s.Option.funcSingle(optionRunWait, func() {
var sigChan = make(chan os.Signal, 3)
signal.Notify(sigChan, syscall.SIGTERM, os.Interrupt)
<-sigChan
})()
return s.i.Stop(s)
}
func (s *aixService) Logger(errs chan<- error) (Logger, error) {
if interactive {
return ConsoleLogger, nil
}
return s.SystemLogger(errs)
}
func (s *aixService) SystemLogger(errs chan<- error) (Logger, error) {
return newSysLogger(s.Name, errs)
}
var svcConfig = `#!/bin/ksh
case "$1" in
start )
startsrc -s {{.Name}}
;;
stop )
stopsrc -s {{.Name}}
;;
* )
echo "Usage: $0 (start | stop)"
exit 1
esac
`
1
https://gitee.com/baetyl/service.git
git@gitee.com:baetyl/service.git
baetyl
service
service
master

搜索帮助