package main import ( "fmt" "html/template" "log" "net/http" "os/exec" "runtime" ) const ( serverName = "delemaco" // Server to ping macAddress = "b8:cb:29:a1:f3:88" // MAC address of the server port = "8080" // Port to listen on ) // StatusData holds data for the HTML template type StatusData struct { Server string Status string Color string IsTestMode bool } // Check if server is online func isServerOnline() bool { var cmd *exec.Cmd // macOS and Linux have slightly different ping commands if runtime.GOOS == "darwin" { cmd = exec.Command("ping", "-c", "1", "-W", "1000", serverName) } else { cmd = exec.Command("ping", "-c", "1", "-W", "1", serverName) } err := cmd.Run() return err == nil } // Send WOL packet func sendWakeOnLAN() error { log.Printf("Sending WOL packet to %s (%s)", serverName, macAddress) cmd := exec.Command("wakeonlan", macAddress) return cmd.Run() } // Shutdown server func shutdownServer() error { // Real shutdown command for Linux log.Printf("Sending shutdown command to %s", serverName) cmd := exec.Command("ssh", serverName, "sudo", "shutdown", "-h", "now") return cmd.Run() } // Handle the root route - show status func indexHandler(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.NotFound(w, r) return } online := isServerOnline() status := "Online" color := "#4caf50" // Material green if !online { status = "Offline" color = "#d32f2f" // Material red } data := StatusData{ Server: serverName, Status: status, Color: color, IsTestMode: runtime.GOOS == "darwin", } renderTemplate(w, data) } // Handle boot request func bootHandler(w http.ResponseWriter, r *http.Request) { if !isServerOnline() { // Boot the server using wakeonlan err := sendWakeOnLAN() if err != nil { log.Printf("Error booting server: %v", err) } // Display booting status data := StatusData{ Server: serverName, Status: "Booting", Color: "#607d8b", // Material blue-gray IsTestMode: runtime.GOOS == "darwin", } renderTemplate(w, data) } else { // Server is already online data := StatusData{ Server: serverName, Status: "Online", Color: "#4caf50", // Material green IsTestMode: runtime.GOOS == "darwin", } renderTemplate(w, data) } } // Handle shutdown request func shutdownHandler(w http.ResponseWriter, r *http.Request) { if isServerOnline() { // Shutdown the server err := shutdownServer() if err != nil { log.Printf("Error shutting down server: %v", err) } // Display shutting down status data := StatusData{ Server: serverName, Status: "Shutting down", Color: "#5d4037", // Material brown IsTestMode: runtime.GOOS == "darwin", } renderTemplate(w, data) } else { // Server is already offline data := StatusData{ Server: serverName, Status: "Offline", Color: "#d32f2f", // Material red IsTestMode: runtime.GOOS == "darwin", } renderTemplate(w, data) } } // Render the HTML template func renderTemplate(w http.ResponseWriter, data StatusData) { tmpl, err := template.New("status").Parse(` Server Status: {{.Server}}

{{.Status}}

Server: {{.Server}}
{{if .IsTestMode}}
Running on macOS in test mode. Wake-on-LAN packets are sent, but remote shutdown is simulated.
{{end}}
`) if err != nil { http.Error(w, "Failed to load template", http.StatusInternalServerError) log.Printf("Template error: %v", err) return } err = tmpl.Execute(w, data) if err != nil { http.Error(w, "Failed to render template", http.StatusInternalServerError) log.Printf("Template render error: %v", err) } } func main() { // Register route handlers http.HandleFunc("/", indexHandler) http.HandleFunc("/boot", bootHandler) http.HandleFunc("/shutdown", shutdownHandler) // Start the server listenAddr := fmt.Sprintf(":%s", port) log.Printf("Starting WOL Server on http://localhost%s", listenAddr) if runtime.GOOS == "darwin" { log.Println("Running on macOS in test mode - remote shutdown commands will be simulated") } if err := http.ListenAndServe(listenAddr, nil); err != nil { log.Fatalf("Server failed to start: %v", err) } }