From 0923268bb20d8e7959e6ec819260c475f0bc993b Mon Sep 17 00:00:00 2001 From: ZhuoQinghui <1302344380@qq.com> Date: Mon, 14 Oct 2024 15:50:15 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.go | 289 +----------------------------------------------- src/command.go | 82 ++++++++++++++ src/daemon.go | 269 ++++++++++++++++++++++++++++++++++++++++++++ src/http.go | 1 + src/task.go | 1 + src/variable.go | 3 + 6 files changed, 358 insertions(+), 287 deletions(-) create mode 100644 src/command.go create mode 100644 src/daemon.go create mode 100644 src/http.go create mode 100644 src/task.go diff --git a/main.go b/main.go index f597211..60762d4 100644 --- a/main.go +++ b/main.go @@ -1,15 +1,8 @@ package main import ( + "acme-mana/src" "fmt" - "log" - "net" - "os" - "os/exec" - "path" - "path/filepath" - "strconv" - "syscall" ) func main() { @@ -22,283 +15,5 @@ func main() { // fmt.Println(err) //} fmt.Println("start()") - start() -} - -const pidFile = "acme-mana.pid" -const socketFile = "acme-mana.sock" - -var stdout *os.File -var stderr *os.File - -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) - //} - 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 - } - return true - //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) { - + src.Start() } diff --git a/src/command.go b/src/command.go new file mode 100644 index 0000000..6ba53d3 --- /dev/null +++ b/src/command.go @@ -0,0 +1,82 @@ +package src + +import ( + "log" + "net" + "os" +) + +/* +* +初始化Socket +*/ +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(PidFile) + log.Println("Remove Socket File...") + os.Exit(0) +} + +/* +收到命令 +*/ +func onCommand(command string) { + +} diff --git a/src/daemon.go b/src/daemon.go new file mode 100644 index 0000000..600dc48 --- /dev/null +++ b/src/daemon.go @@ -0,0 +1,269 @@ +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请求 + + // 自动执行域名证书更新 + + // 阻止退出 + 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 +} diff --git a/src/http.go b/src/http.go new file mode 100644 index 0000000..c6d5f54 --- /dev/null +++ b/src/http.go @@ -0,0 +1 @@ +package src diff --git a/src/task.go b/src/task.go new file mode 100644 index 0000000..c6d5f54 --- /dev/null +++ b/src/task.go @@ -0,0 +1 @@ +package src diff --git a/src/variable.go b/src/variable.go index 99c63e4..cfa704e 100644 --- a/src/variable.go +++ b/src/variable.go @@ -1,5 +1,8 @@ package src +const PidFile = "acme-mana.pid" +const SocketFile = "acme-mana.sock" + var appConfig AppConfig = ReadConfig() func GetAppConfig() AppConfig {