272 lines
5.1 KiB
Go
272 lines
5.1 KiB
Go
package src
|
||
|
||
import (
|
||
"log"
|
||
"net"
|
||
"os"
|
||
"os/exec"
|
||
"path"
|
||
"path/filepath"
|
||
"strconv"
|
||
"syscall"
|
||
)
|
||
|
||
var stdout *os.File
|
||
var stderr *os.File
|
||
|
||
// Start 启动/*
|
||
func Start() {
|
||
initLog()
|
||
log.Println("Run Acme Mana...")
|
||
args := os.Args
|
||
if len(args) <= 1 {
|
||
daemonStart()
|
||
return
|
||
}
|
||
command := args[1]
|
||
switch command {
|
||
case "start":
|
||
daemonStart()
|
||
case "stop":
|
||
daemonStop()
|
||
case "status":
|
||
daemonStatus()
|
||
case "-s":
|
||
daemonCommand()
|
||
default:
|
||
log.Fatalf("Unknown command: %s", command)
|
||
}
|
||
}
|
||
|
||
/*
|
||
初始化日志文件
|
||
*/
|
||
func initLog() {
|
||
pwd, err := os.Getwd()
|
||
if err != nil {
|
||
log.Fatalf("Failed to get current working directory: %v", err)
|
||
}
|
||
dir := path.Join(pwd, "log")
|
||
_, err = os.Stat(dir)
|
||
if os.IsNotExist(err) {
|
||
err := os.Mkdir(dir, 0777)
|
||
if err != nil {
|
||
log.Fatalf("Failed to create directory: %v", err)
|
||
}
|
||
}
|
||
outFile, err := os.OpenFile(path.Join(dir, "out.log"), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
|
||
defer outFile.Close()
|
||
stdout = outFile
|
||
|
||
errFile, err := os.OpenFile(path.Join(dir, "err.log"), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
|
||
defer stderr.Close()
|
||
stderr = errFile
|
||
}
|
||
|
||
/*
|
||
守护进程启动
|
||
*/
|
||
func daemonStart() {
|
||
isDaemon := os.Getenv("GO_DAEMON")
|
||
log.Println("Run Daemon, DAEMON Is " + isDaemon)
|
||
if isDaemon != "1" {
|
||
// 直接启动
|
||
if isRunning() {
|
||
log.Println("Daemon is already running.")
|
||
return
|
||
}
|
||
|
||
path, err := os.Executable()
|
||
if err != nil {
|
||
log.Fatalf("Failed to get executable path: %v", err)
|
||
}
|
||
cmd := exec.Cmd{
|
||
Path: path,
|
||
Args: os.Args,
|
||
Dir: filepath.Dir(path),
|
||
Env: append(os.Environ(), "GO_DAEMON=1"),
|
||
//Stdin: os.Stdin,
|
||
Stdout: stdout,
|
||
Stderr: stderr,
|
||
//Stdin: os.Stdin,
|
||
//Stdout: os.Stdout,
|
||
//Stderr: os.Stderr,
|
||
SysProcAttr: &syscall.SysProcAttr{},
|
||
}
|
||
|
||
//cmd := exec.Command(os.Args[0])
|
||
//cmd.Env = append(os.Environ(), "GO_DAEMON=1")
|
||
//cmd.Stdout = os.Stdout
|
||
//cmd.Stderr = os.Stderr
|
||
//cmd.SysProcAttr = &syscall.SysProcAttr{}
|
||
log.Println("Starting daemon...")
|
||
log.Println(cmd)
|
||
err = cmd.Start()
|
||
if err != nil {
|
||
log.Fatalf("Failed to start daemon: %v", err)
|
||
}
|
||
err = os.WriteFile(PidFile, []byte(strconv.Itoa(cmd.Process.Pid)), 0644)
|
||
if err != nil {
|
||
log.Fatalf("Failed to write PID file: %v", err)
|
||
}
|
||
log.Printf("Daemon started with PID: %d", cmd.Process.Pid)
|
||
os.Exit(0)
|
||
|
||
} else {
|
||
// 子进程
|
||
doTask()
|
||
}
|
||
|
||
}
|
||
|
||
/*
|
||
守护进程停止
|
||
*/
|
||
func daemonStop() {
|
||
//pid, err := readPID()
|
||
//if err != nil {
|
||
// log.Fatalf("Failed to stop daemon: %v", err)
|
||
//}
|
||
//
|
||
//process, err := os.FindProcess(pid)
|
||
//if err != nil {
|
||
// log.Fatalf("Failed to find process: %v", err)
|
||
//}
|
||
//
|
||
//err = process.Signal(syscall.SIGTERM)
|
||
//if err != nil {
|
||
// log.Fatalf("Failed to stop process: %v", err)
|
||
//}
|
||
//
|
||
//os.Remove(PidFile)
|
||
//os.Remove(SocketFile)
|
||
//log.Println("Daemon stopped.")
|
||
sendCommand("stop")
|
||
}
|
||
|
||
/*
|
||
守护进程状态
|
||
*/
|
||
func daemonStatus() {
|
||
if isRunning() {
|
||
log.Println("Daemon is running.")
|
||
} else {
|
||
log.Println("Daemon is not running.")
|
||
}
|
||
}
|
||
|
||
/*
|
||
守护进程接收名称
|
||
*/
|
||
func daemonCommand() {
|
||
log.Println("Sending command...")
|
||
//pid, err := readPID()
|
||
//if err != nil {
|
||
// log.Fatalf("Failed to send command: %v", err)
|
||
//}
|
||
//
|
||
//_, err = os.FindProcess(pid)
|
||
//if err != nil {
|
||
// log.Fatalf("Failed to find process: %v", err)
|
||
//}
|
||
//if len(os.Args) < 3 {
|
||
// log.Fatalf("No command specified")
|
||
//}
|
||
command := os.Args[2]
|
||
sendCommand(command)
|
||
|
||
}
|
||
|
||
/*
|
||
发送命令
|
||
*/
|
||
func sendCommand(command string) {
|
||
conn, err := net.Dial("unix", SocketFile)
|
||
if err != nil {
|
||
log.Fatalf("Failed to connect to daemon: %v", err)
|
||
}
|
||
defer func(conn net.Conn) {
|
||
err := conn.Close()
|
||
if err != nil {
|
||
log.Fatalf("Failed to close connection: %v", err)
|
||
}
|
||
}(conn)
|
||
|
||
_, err = conn.Write([]byte(command))
|
||
if err != nil {
|
||
log.Fatalf("Failed to send command: %v", err)
|
||
}
|
||
|
||
log.Printf("Sending command '%s' to daemon with PID: %d", command, 0)
|
||
}
|
||
|
||
/*
|
||
*
|
||
业务进程执行任务
|
||
*/
|
||
func doTask() {
|
||
// 示例:每隔10秒打印一条日志
|
||
//for {
|
||
// log.Println("Daemon is running...")
|
||
// time.Sleep(10 * time.Second)
|
||
//}
|
||
|
||
// 监听主进程下发的指令
|
||
go InitSocket()
|
||
|
||
// 监听HTTP请求
|
||
go InitHttpServer("0.0.0.0", 10000)
|
||
|
||
// 自动执行域名证书更新
|
||
go AutoRefreshCert()
|
||
|
||
// 阻止退出
|
||
select {}
|
||
}
|
||
|
||
/*
|
||
*
|
||
是否已启动
|
||
*/
|
||
func isRunning() bool {
|
||
log.Println("Checking if daemon is running...")
|
||
pid, err := readPID()
|
||
if err != nil {
|
||
return false
|
||
}
|
||
|
||
process, err := os.FindProcess(pid)
|
||
log.Println("Found process:", process)
|
||
if err != nil {
|
||
log.Println("Failed to find process:", err)
|
||
return false
|
||
}
|
||
return true
|
||
//err = process.Signal(syscall.Signal(0))
|
||
//log.Println("Signal result:", err)
|
||
//return err == nil
|
||
}
|
||
|
||
/*
|
||
*
|
||
读取PID文件
|
||
*/
|
||
func readPID() (int, error) {
|
||
log.Println("Reading PID file...")
|
||
data, err := os.ReadFile(PidFile)
|
||
if err != nil {
|
||
log.Println("Failed to read PID file:", err)
|
||
return 0, err
|
||
}
|
||
log.Println("PID file content:", string(data))
|
||
|
||
pid, err := strconv.Atoi(string(data))
|
||
if err != nil {
|
||
log.Println("Failed to parse PID:", err)
|
||
return 0, err
|
||
}
|
||
log.Println("PID:", pid)
|
||
|
||
return pid, nil
|
||
}
|