diff --git a/internal/native/native.go b/internal/native/native.go index 642f989..a8b7b55 100644 --- a/internal/native/native.go +++ b/internal/native/native.go @@ -11,8 +11,8 @@ import ( ) const ( - BaseDir = "/opt/fw" - Symlink = "/opt/wallarm" + BaseDir = "/opt/fw" + DeployTo = "/opt/wallarm" // setup.sh hardcodes this, deploy here then move ) func installerURL() string { @@ -31,46 +31,15 @@ func InstallNode(node state.Node, apiToken, apiHost, labels string) error { instanceDir := filepath.Join(BaseDir, node.Name, "wallarm") installerPath := filepath.Join(BaseDir, "wallarm-aio.sh") - // 1. Per-instance NGINX: copy binary, write config, start - nginxDir := filepath.Join(instanceDir, "nginx") - copyNginx(instanceDir) + // 1. Prepare clean /opt/wallarm for this deployment + os.RemoveAll(DeployTo) + os.MkdirAll(DeployTo, 0755) - // Write nginx.conf for this instance - port := "80" - if idx := strings.LastIndex(node.Address, ":"); idx != -1 { - port = node.Address[idx+1:] - } - nginxConf := filepath.Join(nginxDir, "conf", "nginx.conf") - os.MkdirAll(filepath.Dir(nginxConf), 0755) - os.WriteFile(nginxConf, []byte(fmt.Sprintf(` -worker_processes auto; -pid %s/nginx.pid; -error_log %s/error.log; -events { worker_connections 10240; } -http { - access_log %s/access.log; - server { - listen %s; - server_name _; - allow 127.0.0.0/8; - deny all; - wallarm_mode off; - access_log off; - location /wallarm-status { wallarm_status on; } - } -} -`, nginxDir, nginxDir, nginxDir, port)), 0644) + // 2. Per-instance NGINX into /opt/wallarm + copyNginx(DeployTo) + startNginx(DeployTo, node) - // Start NGINX for this instance - nginxBin := filepath.Join(nginxDir, "sbin", "nginx") - startCmd := exec.Command(nginxBin, "-c", nginxConf, "-p", nginxDir) - startCmd.Dir = nginxDir - if out, err := startCmd.CombinedOutput(); err != nil { - fmt.Printf("[%s] NGINX start warning: %v\n%s\n", node.Name, err, string(out)) - } - fmt.Printf("[%s] NGINX started on port %s\n", node.Name, port) - - // 2. Download AIO once + // 3. Download AIO once if _, err := os.Stat(installerPath); os.IsNotExist(err) { fmt.Printf("[%s] Downloading installer...\n", node.Name) cmd := exec.Command("curl", "-fsSL", "-o", installerPath, installerURL()) @@ -80,28 +49,22 @@ http { os.Chmod(installerPath, 0755) } - // 3. Extract AIO to instance + // 4. Extract AIO to /opt/wallarm fmt.Printf("[%s] Extracting...\n", node.Name) - cmd := exec.Command("bash", installerPath, "--noexec", "--keep", "--target", instanceDir, "--noprogress", "--accept") + cmd := exec.Command("bash", installerPath, "--noexec", "--keep", "--target", DeployTo, "--noprogress", "--accept") if out, err := cmd.CombinedOutput(); err != nil { return fmt.Errorf("extract: %w\n%s", err, string(out)) } - // 4. Patch setup.sh to use instance path (bypasses /opt/wallarm hardcoding) - setupPath := filepath.Join(instanceDir, "setup.sh") - exec.Command("sed", "-i", - fmt.Sprintf("s|/opt/wallarm|%s|g", instanceDir), - setupPath).Run() - - // 5. Run setup.sh + // 5. Run setup.sh natively fmt.Printf("[%s] Running setup...\n", node.Name) - cmd = exec.Command("bash", filepath.Join(instanceDir, "setup.sh"), + cmd = exec.Command("bash", filepath.Join(DeployTo, "setup.sh"), "--batch", "--token", apiToken, "--cloud", cloudFromHost(apiHost), "--custom-ngx-build", ) - cmd.Dir = instanceDir + cmd.Dir = DeployTo - logFile, _ := os.Create(filepath.Join(instanceDir, "install.log")) + logFile, _ := os.Create(filepath.Join(DeployTo, "install.log")) if logFile != nil { cmd.Stdout = logFile cmd.Stderr = logFile @@ -111,7 +74,7 @@ http { logFile.Close() } if runErr != nil { - if data, _ := os.ReadFile(filepath.Join(instanceDir, "install.log")); len(data) > 0 { + if data, _ := os.ReadFile(filepath.Join(DeployTo, "install.log")); len(data) > 0 { lines := strings.Split(string(data), "\n") s := len(lines) - 5 if s < 0 { @@ -122,16 +85,22 @@ http { return fmt.Errorf("setup failed: %v", runErr) } - fmt.Printf("[%s] Done.\n", node.Name) + // 6. Move /opt/wallarm → /opt/fw/{name}/wallarm + os.MkdirAll(BaseDir+"/"+node.Name, 0755) + os.RemoveAll(instanceDir) + if err := os.Rename(DeployTo, instanceDir); err != nil { + return fmt.Errorf("move to instance dir: %w", err) + } + + fmt.Printf("[%s] Done. Installed to %s\n", node.Name, instanceDir) return nil } -func copyNginx(instanceDir string) { - dst := filepath.Join(instanceDir, "nginx", "sbin", "nginx") +func copyNginx(dir string) { + dst := filepath.Join(dir, "nginx", "sbin", "nginx") if _, err := os.Stat(dst); err == nil { return } - fmt.Println("Installing NGINX per instance...") os.MkdirAll(filepath.Dir(dst), 0755) if path, err := exec.LookPath("nginx"); err == nil { exec.Command("cp", path, dst).Run() @@ -158,11 +127,45 @@ func cloudFromHost(host string) string { return "EU" } -func CreateNodesDir() error { return os.MkdirAll(BaseDir, 0755) } -func GenerateSystemdTemplate() error { return nil } -func RemoveNode(name string) error { - exec.Command("systemctl", "stop", "wallarm-node@"+name).Run() - exec.Command("systemctl", "disable", "wallarm-node@"+name).Run() - return nil -} +func CreateNodesDir() error { return os.MkdirAll(BaseDir, 0755) } +func GenerateSystemdTemplate() error { return nil } +func RemoveNode(name string) error { return nil } func Status(name string) (string, error) { return "", nil } + +func startNginx(dir string, node state.Node) { + nginxDir := filepath.Join(dir, "nginx") + port := "80" + if idx := strings.LastIndex(node.Address, ":"); idx != -1 { + port = node.Address[idx+1:] + } + confDir := filepath.Join(nginxDir, "conf") + os.MkdirAll(confDir, 0755) + confPath := filepath.Join(confDir, "nginx.conf") + os.WriteFile(confPath, []byte(fmt.Sprintf(` +worker_processes auto; +pid %s/nginx.pid; +error_log %s/error.log; +events { worker_connections 10240; } +http { + access_log %s/access.log; + server { + listen %s; + server_name _; + allow 127.0.0.0/8; + deny all; + wallarm_mode off; + access_log off; + location /wallarm-status { wallarm_status on; } + } +} +`, nginxDir, nginxDir, nginxDir, port)), 0644) + + bin := filepath.Join(nginxDir, "sbin", "nginx") + cmd := exec.Command(bin, "-c", confPath, "-p", nginxDir) + cmd.Dir = nginxDir + if out, err := cmd.CombinedOutput(); err != nil { + fmt.Printf("[%s] NGINX start: %v\n%s\n", node.Name, err, string(out)) + } else { + fmt.Printf("[%s] NGINX started on port %s\n", node.Name, port) + } +}