2 Star 2 Fork 7

王布衣 / gox

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
daemon_linux_systemv.go 7.05 KB
一键复制 编辑 原始数据 按行查看 历史
王布衣 提交于 2023-07-20 08:32 . 新增daemon工具库
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by
// license that can be found in the LICENSE file.
package daemon
import (
"os"
"os/exec"
"regexp"
"strings"
"text/template"
)
// systemVRecord - standard record (struct) for linux systemV version of daemon package
type systemVRecord struct {
name string
description string
kind Kind
dependencies []string
}
// Standard service path for systemV daemons
func (linux *systemVRecord) servicePath() string {
return "/etc/init.d/" + linux.name
}
// Is a service installed
func (linux *systemVRecord) isInstalled() bool {
if _, err := os.Stat(linux.servicePath()); err == nil {
return true
}
return false
}
// Check service is running
func (linux *systemVRecord) checkRunning() (string, bool) {
output, err := exec.Command("service", linux.name, "status").Output()
if err == nil {
if matched, err := regexp.MatchString(linux.name, string(output)); err == nil && matched {
reg := regexp.MustCompile("pid ([0-9]+)")
data := reg.FindStringSubmatch(string(output))
if len(data) > 1 {
return "Service (pid " + data[1] + ") is running...", true
}
return "Service is running...", true
}
}
return "Service is stopped", false
}
// Install the service
func (linux *systemVRecord) Install(args ...string) (string, error) {
installAction := "Install " + linux.description + ":"
if ok, err := checkPrivileges(); !ok {
return installAction + failed, err
}
srvPath := linux.servicePath()
if linux.isInstalled() {
return installAction + failed, ErrAlreadyInstalled
}
file, err := os.Create(srvPath)
if err != nil {
return installAction + failed, err
}
defer file.Close()
execPatch, err := executablePath(linux.name)
if err != nil {
return installAction + failed, err
}
templ, err := template.New("systemVConfig").Parse(systemVConfig)
if err != nil {
return installAction + failed, err
}
if err := templ.Execute(
file,
&struct {
Name, Description, Path, Args string
}{linux.name, linux.description, execPatch, strings.Join(args, " ")},
); err != nil {
return installAction + failed, err
}
if err := os.Chmod(srvPath, 0755); err != nil {
return installAction + failed, err
}
for _, i := range [...]string{"2", "3", "4", "5"} {
if err := os.Symlink(srvPath, "/etc/rc"+i+".d/S87"+linux.name); err != nil {
continue
}
}
for _, i := range [...]string{"0", "1", "6"} {
if err := os.Symlink(srvPath, "/etc/rc"+i+".d/K17"+linux.name); err != nil {
continue
}
}
return installAction + success, nil
}
// Remove the service
func (linux *systemVRecord) Remove() (string, error) {
removeAction := "Removing " + linux.description + ":"
if ok, err := checkPrivileges(); !ok {
return removeAction + failed, err
}
if !linux.isInstalled() {
return removeAction + failed, ErrNotInstalled
}
if err := os.Remove(linux.servicePath()); err != nil {
return removeAction + failed, err
}
for _, i := range [...]string{"2", "3", "4", "5"} {
if err := os.Remove("/etc/rc" + i + ".d/S87" + linux.name); err != nil {
continue
}
}
for _, i := range [...]string{"0", "1", "6"} {
if err := os.Remove("/etc/rc" + i + ".d/K17" + linux.name); err != nil {
continue
}
}
return removeAction + success, nil
}
// Start the service
func (linux *systemVRecord) Start() (string, error) {
startAction := "Starting " + linux.description + ":"
if ok, err := checkPrivileges(); !ok {
return startAction + failed, err
}
if !linux.isInstalled() {
return startAction + failed, ErrNotInstalled
}
if _, ok := linux.checkRunning(); ok {
return startAction + failed, ErrAlreadyRunning
}
if err := exec.Command("service", linux.name, "start").Run(); err != nil {
return startAction + failed, err
}
return startAction + success, nil
}
// Stop the service
func (linux *systemVRecord) Stop() (string, error) {
stopAction := "Stopping " + linux.description + ":"
if ok, err := checkPrivileges(); !ok {
return stopAction + failed, err
}
if !linux.isInstalled() {
return stopAction + failed, ErrNotInstalled
}
if _, ok := linux.checkRunning(); !ok {
return stopAction + failed, ErrAlreadyStopped
}
if err := exec.Command("service", linux.name, "stop").Run(); err != nil {
return stopAction + failed, err
}
return stopAction + success, nil
}
// Status - Get service status
func (linux *systemVRecord) Status() (string, error) {
if ok, err := checkPrivileges(); !ok {
return "", err
}
if !linux.isInstalled() {
return statNotInstalled, ErrNotInstalled
}
statusAction, _ := linux.checkRunning()
return statusAction, nil
}
// Run - Run service
func (linux *systemVRecord) Run(e Executable) (string, error) {
runAction := "Running " + linux.description + ":"
e.Run()
return runAction + " completed.", nil
}
// GetTemplate - gets service config template
func (linux *systemVRecord) GetTemplate() string {
return systemVConfig
}
// SetTemplate - sets service config template
func (linux *systemVRecord) SetTemplate(tplStr string) error {
systemVConfig = tplStr
return nil
}
var systemVConfig = `#! /bin/sh
#
# /etc/rc.d/init.d/{{.Name}}
#
# Starts {{.Name}} as a daemon
#
# chkconfig: 2345 87 17
# description: Starts and stops a single {{.Name}} instance on this system
### BEGIN INIT INFO
# Provides: {{.Name}}
# Required-Start: $network $named
# Required-Stop: $network $named
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: This service manages the {{.Description}}.
# Description: {{.Description}}
### END INIT INFO
#
# Source function library.
#
if [ -f /etc/rc.d/init.d/functions ]; then
. /etc/rc.d/init.d/functions
fi
exec="{{.Path}}"
servname="{{.Description}}"
proc="{{.Name}}"
pidfile="/var/run/$proc.pid"
lockfile="/var/lock/subsys/$proc"
stdoutlog="/var/log/$proc.log"
stderrlog="/var/log/$proc.err"
[ -d $(dirname $lockfile) ] || mkdir -p $(dirname $lockfile)
[ -e /etc/sysconfig/$proc ] && . /etc/sysconfig/$proc
start() {
[ -x $exec ] || exit 5
if [ -f $pidfile ]; then
if ! [ -d "/proc/$(cat $pidfile)" ]; then
rm $pidfile
if [ -f $lockfile ]; then
rm $lockfile
fi
fi
fi
if ! [ -f $pidfile ]; then
printf "Starting $servname:\t"
echo "$(date)" >> $stdoutlog
$exec {{.Args}} >> $stdoutlog 2>> $stderrlog &
echo $! > $pidfile
touch $lockfile
success
echo
else
# failure
echo
printf "$pidfile still exists...\n"
exit 7
fi
}
stop() {
echo -n $"Stopping $servname: "
killproc -p $pidfile $proc
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
stop
start
}
rh_status() {
status -p $pidfile $proc
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart)
$1
;;
status)
rh_status
;;
*)
echo $"Usage: $0 {start|stop|status|restart}"
exit 2
esac
exit $?
`
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/quant1x/gox.git
git@gitee.com:quant1x/gox.git
quant1x
gox
gox
v1.21.2

搜索帮助

344bd9b3 5694891 D2dac590 5694891