agent/util/daemon/daemon_linux.go (55 lines of code) (raw):
package daemon
import (
"context"
"os"
"syscall"
"time"
"github.com/aliyun/aliyun_assist_client/agent/util/systemdutil"
"github.com/aliyun/aliyun_assist_client/common/executil"
"github.com/aliyun/aliyun_assist_client/thirdparty/sirupsen/logrus"
)
// Daemonize runs this program as daemon.
// Traditional unix's fork-style way would be dangerous to damonize Go program
// since it may break states of underlying runtime scheduler of goroutines. Thus
// simple initiate another process of this program with special setting.
func Daemonize() error {
executablePath := os.Args[0]
cmd := executil.Command(executablePath)
cmd.Stdin = nil
cmd.Stdout = nil
cmd.Stderr = nil
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
Pgid: 0,
}
err := cmd.Start()
if err != nil {
return err
}
cmd.Process.Release()
os.Exit(0)
return nil
}
const (
AssistDaemonUnit = "AssistDaemon.service"
)
func OperateAssistDaemon(logger logrus.FieldLogger, v any) {
if !systemdutil.IsRunningSystemd() {
return
}
var active, ok bool
if active, ok = v.(bool); !ok {
return
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
if active {
if res, err := systemdutil.StartUnit(ctx, AssistDaemonUnit); err != nil {
logger.WithError(err).Errorf("Start %s unit failed", AssistDaemonUnit)
} else {
logger.Infof("Start %s unit: %s", AssistDaemonUnit, res)
}
} else {
if res, err := systemdutil.StopUnit(ctx, AssistDaemonUnit); err != nil {
logger.WithError(err).Errorf("Stop %s unit failed", AssistDaemonUnit)
} else {
logger.Infof("Stop %s unit: %s", AssistDaemonUnit, res)
}
}
}