package deploy import ( "fmt" "os" "os/exec" "path/filepath" "strings" ) // StartCloudflaredTunnel launches cloudflared pointing at serverURL (background). func StartCloudflaredTunnel(serverURL string) (string, error) { serverURL = strings.TrimSpace(serverURL) if serverURL == "" { return "", fmt.Errorf("server URL required") } checkCmd := exec.Command("cloudflared", "--version") if err := checkCmd.Run(); err != nil { downloadCmd := exec.Command("powershell", "-Command", "Invoke-WebRequest -Uri https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-windows-amd64.exe -OutFile $env:TEMP\\cloudflared.exe") if output, dlErr := downloadCmd.CombinedOutput(); dlErr != nil { return string(output), fmt.Errorf("cloudflared not found and download failed: %w", dlErr) } src := filepath.Join(os.Getenv("TEMP"), "cloudflared.exe") dst := filepath.Join(os.Getenv("SYSTEMROOT"), "System32", "cloudflared.exe") _ = exec.Command("copy", "/Y", src, dst).Run() } tunnelCmd := exec.Command("cloudflared", "tunnel", "--url", serverURL) if err := tunnelCmd.Start(); err != nil { return "", fmt.Errorf("failed to start cloudflared: %w", err) } return fmt.Sprintf("cloudflared tunnel started (pid %d) -> %s", tunnelCmd.Process.Pid, serverURL), nil }