Initial commit: TaskPool React panel
- React frontend with route-level code splitting - Backend rebranded from Baihu to TaskPool - DB brand migration script and local compatibility
This commit is contained in:
@@ -0,0 +1,241 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"syscall"
|
||||
|
||||
"github.com/gofrs/flock"
|
||||
)
|
||||
|
||||
// ========== PID 文件管理 ==========
|
||||
|
||||
var fileLock *flock.Flock
|
||||
|
||||
func getPidFile() string {
|
||||
return filepath.Join(dataDir, "agent.pid")
|
||||
}
|
||||
|
||||
func getLockFile() string {
|
||||
return filepath.Join(dataDir, "agent.lock")
|
||||
}
|
||||
|
||||
// tryLock 尝试获取文件锁,确保只有一个实例运行
|
||||
func tryLock() bool {
|
||||
os.MkdirAll(dataDir, 0755)
|
||||
|
||||
fileLock = flock.New(getLockFile())
|
||||
locked, err := fileLock.TryLock()
|
||||
if err != nil || !locked {
|
||||
fileLock = nil
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// unlock 释放文件锁
|
||||
func unlock() {
|
||||
if fileLock != nil {
|
||||
fileLock.Unlock()
|
||||
fileLock = nil
|
||||
os.Remove(getLockFile())
|
||||
}
|
||||
}
|
||||
|
||||
func writePidFile() {
|
||||
os.MkdirAll(dataDir, 0755)
|
||||
pidFile := getPidFile()
|
||||
os.WriteFile(pidFile, []byte(strconv.Itoa(os.Getpid())), 0644)
|
||||
}
|
||||
|
||||
func readPidFile() int {
|
||||
pidFile := getPidFile()
|
||||
data, err := os.ReadFile(pidFile)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
pid, _ := strconv.Atoi(string(data))
|
||||
return pid
|
||||
}
|
||||
|
||||
func removePidFile() {
|
||||
os.Remove(getPidFile())
|
||||
}
|
||||
|
||||
// ========== 命令实现 ==========
|
||||
|
||||
func cmdStop() {
|
||||
pid := readPidFile()
|
||||
if pid == 0 {
|
||||
fmt.Println("Agent 未运行")
|
||||
return
|
||||
}
|
||||
|
||||
process, err := os.FindProcess(pid)
|
||||
if err != nil {
|
||||
fmt.Printf("找不到进程 %d\n", pid)
|
||||
removePidFile()
|
||||
return
|
||||
}
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
err = process.Kill()
|
||||
} else {
|
||||
err = process.Signal(syscall.SIGTERM)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("停止失败: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("Agent 已停止")
|
||||
removePidFile()
|
||||
}
|
||||
|
||||
func cmdStatus() {
|
||||
pid := readPidFile()
|
||||
if pid == 0 {
|
||||
fmt.Println("状态: 未运行")
|
||||
return
|
||||
}
|
||||
|
||||
if !isProcessRunning(pid) {
|
||||
fmt.Println("状态: 未运行")
|
||||
removePidFile()
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("状态: 运行中 (PID: %d)\n", pid)
|
||||
}
|
||||
|
||||
func isProcessRunning(pid int) bool {
|
||||
process, err := os.FindProcess(pid)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// Unix 系统发送信号 0 检查进程
|
||||
if runtime.GOOS != "windows" {
|
||||
err = process.Signal(syscall.Signal(0))
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// Windows 下 FindProcess 成功即表示进程存在
|
||||
return true
|
||||
}
|
||||
|
||||
func cmdInstall() {
|
||||
exePath, _ := os.Executable()
|
||||
exeDir := filepath.Dir(exePath)
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
installWindows(exePath, exeDir)
|
||||
} else {
|
||||
installLinux(exePath, exeDir)
|
||||
}
|
||||
}
|
||||
|
||||
func cmdUninstall() {
|
||||
if runtime.GOOS == "windows" {
|
||||
uninstallWindows()
|
||||
} else {
|
||||
uninstallLinux()
|
||||
}
|
||||
}
|
||||
|
||||
// ========== Linux systemd ==========
|
||||
|
||||
func installLinux(exePath, exeDir string) {
|
||||
serviceContent := fmt.Sprintf(`[Unit]
|
||||
Description=%s
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=%s
|
||||
ExecStart=%s run
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
`, ServiceDesc, exeDir, exePath)
|
||||
|
||||
servicePath := fmt.Sprintf("/etc/systemd/system/%s.service", ServiceName)
|
||||
if err := os.WriteFile(servicePath, []byte(serviceContent), 0644); err != nil {
|
||||
fmt.Printf("创建服务文件失败: %v\n", err)
|
||||
fmt.Println("请使用 sudo 运行")
|
||||
return
|
||||
}
|
||||
|
||||
// 重载 systemd
|
||||
exec.Command("systemctl", "daemon-reload").Run()
|
||||
exec.Command("systemctl", "enable", ServiceName).Run()
|
||||
|
||||
fmt.Printf("服务已安装: %s\n", servicePath)
|
||||
fmt.Println("使用以下命令管理服务:")
|
||||
fmt.Printf(" 启动: sudo systemctl start %s\n", ServiceName)
|
||||
fmt.Printf(" 停止: sudo systemctl stop %s\n", ServiceName)
|
||||
fmt.Printf(" 状态: sudo systemctl status %s\n", ServiceName)
|
||||
}
|
||||
|
||||
func uninstallLinux() {
|
||||
// 停止服务
|
||||
exec.Command("systemctl", "stop", ServiceName).Run()
|
||||
exec.Command("systemctl", "disable", ServiceName).Run()
|
||||
|
||||
servicePath := fmt.Sprintf("/etc/systemd/system/%s.service", ServiceName)
|
||||
if err := os.Remove(servicePath); err != nil {
|
||||
fmt.Printf("删除服务文件失败: %v\n", err)
|
||||
fmt.Println("请使用 sudo 运行")
|
||||
return
|
||||
}
|
||||
|
||||
exec.Command("systemctl", "daemon-reload").Run()
|
||||
fmt.Println("服务已卸载")
|
||||
}
|
||||
|
||||
// ========== Windows 服务 ==========
|
||||
|
||||
func installWindows(exePath, exeDir string) {
|
||||
// 使用 sc.exe 创建服务
|
||||
cmd := exec.Command("sc", "create", ServiceName,
|
||||
"binPath=", fmt.Sprintf(`"%s" run`, exePath),
|
||||
"start=", "auto",
|
||||
"DisplayName=", ServiceDesc)
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
fmt.Printf("创建服务失败: %v\n", err)
|
||||
fmt.Println("请以管理员身份运行")
|
||||
return
|
||||
}
|
||||
|
||||
// 设置服务描述
|
||||
exec.Command("sc", "description", ServiceName, ServiceDesc).Run()
|
||||
|
||||
fmt.Println("服务已安装")
|
||||
fmt.Println("使用以下命令管理服务:")
|
||||
fmt.Printf(" 启动: sc start %s\n", ServiceName)
|
||||
fmt.Printf(" 停止: sc stop %s\n", ServiceName)
|
||||
fmt.Printf(" 状态: sc query %s\n", ServiceName)
|
||||
}
|
||||
|
||||
func uninstallWindows() {
|
||||
// 停止服务
|
||||
exec.Command("sc", "stop", ServiceName).Run()
|
||||
|
||||
// 删除服务
|
||||
cmd := exec.Command("sc", "delete", ServiceName)
|
||||
if err := cmd.Run(); err != nil {
|
||||
fmt.Printf("删除服务失败: %v\n", err)
|
||||
fmt.Println("请以管理员身份运行")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("服务已卸载")
|
||||
}
|
||||
Reference in New Issue
Block a user