daemon
This commit is contained in:
		
							parent
							
								
									b6dd3a71d8
								
							
						
					
					
						commit
						35cc5d360b
					
				
							
								
								
									
										265
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										265
									
								
								main.go
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -1,17 +1,274 @@
 | 
			
		|||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"acme-mana/src"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"log"
 | 
			
		||||
	"net"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/exec"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"syscall"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	config := src.GetAppConfig()
 | 
			
		||||
	fmt.Println(config)
 | 
			
		||||
	src.Apply(config.Domains[0])
 | 
			
		||||
	//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) {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,6 +15,8 @@ import (
 | 
			
		|||
	"path/filepath"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Apply 申请证书
 | 
			
		||||
// domain: 申请的域名
 | 
			
		||||
func Apply(domain Domain) {
 | 
			
		||||
	email, hosts, name := domain.Email, domain.Host, domain.Name
 | 
			
		||||
	privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
 | 
			
		||||
| 
						 | 
				
			
			@ -29,7 +31,6 @@ func Apply(domain Domain) {
 | 
			
		|||
 | 
			
		||||
	config := lego.NewConfig(&acmeUser)
 | 
			
		||||
 | 
			
		||||
	// A client facilitates communication with the CA server.
 | 
			
		||||
	client, err := lego.NewClient(config)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatal(err)
 | 
			
		||||
| 
						 | 
				
			
			@ -80,6 +81,7 @@ func Apply(domain Domain) {
 | 
			
		|||
	saveCertFile(cert, name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// saveCertFile 保存证书文件
 | 
			
		||||
func saveCertFile(cert *certificate.Resource, name string) {
 | 
			
		||||
	dir := GetAppConfig().CertDir
 | 
			
		||||
	dir = filepath.Join(dir, name)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user