acme-mana/main.go
2024-10-10 17:05:11 +08:00

275 lines
5.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"fmt"
"log"
"net"
"os"
"os/exec"
"path/filepath"
"strconv"
"syscall"
)
func main() {
//config := src.GetAppConfig()
//fmt.Println(config)
//src.Apply(config.Domains[0])
//fmt.Println(os.Getwd())
//err := os.MkdirAll("cert\\abc", 0777)
//if err != nil {
// fmt.Println(err)
//}
fmt.Println("start()")
start()
}
const pidFile = "acme-mana.pid"
const socketFile = "acme-mana.sock"
func start() {
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 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: 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)
//}
initSocket()
}
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
}
err = process.Signal(syscall.Signal(0))
log.Println("Signal result:", err)
return err == nil
}
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
}
func initSocket() {
// 删除旧的 socket 文件
if _, err := os.Stat(socketFile); err == nil {
os.Remove(socketFile)
}
listener, err := net.Listen("unix", socketFile)
if err != nil {
log.Fatalf("Failed to listen on socket: %v", err)
}
defer listener.Close()
for {
log.Println("Waiting for connections...")
conn, err := listener.Accept()
if err != nil {
log.Printf("Failed to accept connection: %v", err)
continue
}
go handleConnection(conn)
}
}
func handleConnection(conn net.Conn) {
defer conn.Close()
buf := make([]byte, 1024)
n, err := conn.Read(buf)
if err != nil {
log.Printf("Failed to read command: %v", err)
return
}
command := string(buf[:n])
log.Printf("Received command: %s", command)
// 在这里处理接收到的命令
switch command {
case "stop":
onStop()
default:
onCommand(command)
}
}
func onStop() {
log.Println("Stopping daemon...")
os.Remove(pidFile)
log.Println("Remove PID File...")
os.Remove(socketFile)
log.Println("Remove Socket File...")
os.Exit(0)
}
func onCommand(command string) {
}