From f50ee83e11507cab835cf57fc1d3f5c30ff1b1fa Mon Sep 17 00:00:00 2001 From: iluobei Date: Thu, 2 Apr 2026 23:23:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=87=8F=E5=B0=91=E4=B8=8E=E4=B8=BB=E6=8E=A7?= =?UTF-8?q?=E6=96=AD=E5=BC=80=E6=97=B6=E7=9A=84=E9=87=8D=E8=AF=95=E9=A2=91?= =?UTF-8?q?=E7=8E=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 41 +++++++++++++++++++++ cmd/mmw-agent/main.go | 17 ++++++++- internal/handler/manage.go | 75 +++++++++++++++++++------------------- 3 files changed, 94 insertions(+), 39 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c94c87d --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# ---> Go +# If you prefer the allow list template instead of the deny list, see community template: +# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore +# +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +# Go workspace file +go.work +go.work.sum + +# env file +.env + +traffic-info-* +.claude +build + +internal/web/dist +data/* +.vscode +VERSION.md +miaomiaowu.db +miaomiaowux-frontend/.vite +.idea +VALIDATION_INTEGRATION_PLAN.md +*.md + diff --git a/cmd/mmw-agent/main.go b/cmd/mmw-agent/main.go index d61c9c2..6242136 100644 --- a/cmd/mmw-agent/main.go +++ b/cmd/mmw-agent/main.go @@ -17,14 +17,27 @@ import ( func main() { configPath := flag.String("config", "", "Path to config file") + configPathShort := flag.String("c", "", "Path to config file (shorthand)") flag.Parse() + // -c takes effect if -config is not set + cfgFile := *configPath + if cfgFile == "" { + cfgFile = *configPathShort + } + // Default to config.yaml in working directory + if cfgFile == "" { + if _, err := os.Stat("config.yaml"); err == nil { + cfgFile = "config.yaml" + } + } + // Load configuration var cfg *config.Config var err error - if *configPath != "" { - cfg, err = config.Load(*configPath) + if cfgFile != "" { + cfg, err = config.Load(cfgFile) if err != nil { log.Fatalf("Failed to load config: %v", err) } diff --git a/internal/handler/manage.go b/internal/handler/manage.go index 39f9372..9c6375d 100644 --- a/internal/handler/manage.go +++ b/internal/handler/manage.go @@ -11,6 +11,7 @@ import ( "os/exec" "path/filepath" "strings" + "sync/atomic" "time" "mmw-agent/internal/config" @@ -20,6 +21,8 @@ import ( "github.com/xtls/xray-core/infra/conf" ) +var nginxInstalling atomic.Bool + // ManageHandler handles management API requests for child servers type ManageHandler struct { configToken string @@ -163,7 +166,14 @@ func (h *ManageHandler) getXrayStatus() *ServiceStatus { func (h *ManageHandler) getNginxStatus() *ServiceStatus { status := &ServiceStatus{} + // Check PATH first, then compiled install path nginxPath, err := exec.LookPath("nginx") + if err != nil { + if _, statErr := os.Stat("/usr/local/nginx/sbin/nginx"); statErr == nil { + nginxPath = "/usr/local/nginx/sbin/nginx" + err = nil + } + } if err == nil { status.Installed = true cmd := exec.Command(nginxPath, "-v") @@ -173,6 +183,10 @@ func (h *ManageHandler) getNginxStatus() *ServiceStatus { } } + if nginxInstalling.Load() { + status.Version = "安装中..." + } + // Check systemctl first cmd := exec.Command("systemctl", "is-active", "nginx") output, _ := cmd.Output() @@ -716,37 +730,35 @@ func (h *ManageHandler) HandleNginxInstall(w http.ResponseWriter, r *http.Reques return } - log.Printf("[Manage] Installing Nginx...") - - var cmd *exec.Cmd - if _, err := exec.LookPath("apt-get"); err == nil { - cmd = exec.Command("bash", "-c", "apt-get update && apt-get install -y nginx") - } else if _, err := exec.LookPath("yum"); err == nil { - cmd = exec.Command("bash", "-c", "yum install -y nginx") - } else if _, err := exec.LookPath("dnf"); err == nil { - cmd = exec.Command("bash", "-c", "dnf install -y nginx") - } else { - writeError(w, http.StatusInternalServerError, "No supported package manager found") + if nginxInstalling.Load() { + writeError(w, http.StatusConflict, "Nginx installation already in progress") return } - var stdout, stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr + log.Printf("[Manage] Starting Nginx installation (async)...") + nginxInstalling.Store(true) - err := cmd.Run() - if err != nil { - log.Printf("[Manage] Nginx installation failed: %v, stderr: %s", err, stderr.String()) - writeError(w, http.StatusInternalServerError, fmt.Sprintf("Installation failed: %v", err)) - return - } + go func() { + defer nginxInstalling.Store(false) - log.Printf("[Manage] Nginx installed successfully") + cmd := exec.Command("bash", "-c", + `curl -fsSL https://raw.githubusercontent.com/iluobei/miaomiaowuX/main/install-nginx.sh | bash`) + cmd.Env = os.Environ() + + var stdout, stderr bytes.Buffer + cmd.Stdout = &stdout + cmd.Stderr = &stderr + + if err := cmd.Run(); err != nil { + log.Printf("[Manage] Nginx installation failed: %v, stderr: %s", err, stderr.String()) + return + } + log.Printf("[Manage] Nginx installed successfully") + }() writeJSON(w, http.StatusOK, map[string]interface{}{ "success": true, - "message": "Nginx installed successfully", - "output": stdout.String(), + "message": "Nginx installation started, please check status later", }) } @@ -764,19 +776,9 @@ func (h *ManageHandler) HandleNginxRemove(w http.ResponseWriter, r *http.Request log.Printf("[Manage] Removing Nginx...") - exec.Command("systemctl", "stop", "nginx").Run() - - var cmd *exec.Cmd - if _, err := exec.LookPath("apt-get"); err == nil { - cmd = exec.Command("bash", "-c", "apt-get remove -y nginx nginx-common") - } else if _, err := exec.LookPath("yum"); err == nil { - cmd = exec.Command("bash", "-c", "yum remove -y nginx") - } else if _, err := exec.LookPath("dnf"); err == nil { - cmd = exec.Command("bash", "-c", "dnf remove -y nginx") - } else { - writeError(w, http.StatusInternalServerError, "No supported package manager found") - return - } + cmd := exec.Command("bash", "-c", + `curl -fsSL https://raw.githubusercontent.com/iluobei/miaomiaowuX/main/uninstall-nginx.sh | bash -s -- -y`) + cmd.Env = os.Environ() var stdout, stderr bytes.Buffer cmd.Stdout = &stdout @@ -794,7 +796,6 @@ func (h *ManageHandler) HandleNginxRemove(w http.ResponseWriter, r *http.Request writeJSON(w, http.StatusOK, map[string]interface{}{ "success": true, "message": "Nginx removed successfully", - "output": stdout.String(), }) }