From f9549a10bb22603b75b45edc808205f0acc51318 Mon Sep 17 00:00:00 2001 From: Lorenzo Iovino Date: Mon, 21 Apr 2025 22:08:09 +0200 Subject: [PATCH] changed in go --- .github/workflows/build.yml | 120 +++++++++++ README.md | 149 ++++++++++++- delemaco.sh | 61 ------ main.go | 417 ++++++++++++++++++++++++++++++++++++ shutdown-delemaco.sh | 62 ------ wol-delemaco.sh | 62 ------ 6 files changed, 684 insertions(+), 187 deletions(-) create mode 100644 .github/workflows/build.yml delete mode 100644 delemaco.sh create mode 100644 main.go delete mode 100644 shutdown-delemaco.sh delete mode 100644 wol-delemaco.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..d830900 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,120 @@ +name: Build and Release + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build: + name: Cross-compile for Raspberry Pi + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '1.20' + + - name: Build for ARM (Pi Zero, Pi 1 - ARMv6) + run: | + GOOS=linux GOARCH=arm GOARM=6 go build -ldflags="-s -w" -o wol-server-arm6 + + - name: Create systemd service file + run: | + cat > wol-server.service << 'EOL' + [Unit] + Description=WOL Server Go Application + After=network.target + + [Service] + User=pi + WorkingDirectory=/home/pi/wol-server + ExecStart=/home/pi/wol-server/wol-server + Restart=always + + [Install] + WantedBy=multi-user.target + EOL + + - name: Create deployment script + run: | + cat > deploy.sh << 'EOL' + #!/bin/bash + + # Detect Raspberry Pi model and use the appropriate binary + MODEL=$(cat /proc/cpuinfo | grep "Model" | sed 's/Model\s*:\s*//g') + echo "Detected model: $MODEL" + + # Select the right binary based on processor architecture + ARCH=$(uname -m) + echo "Architecture: $ARCH" + + if [[ "$ARCH" == "aarch64" ]]; then + echo "Using ARM64 binary" + cp wol-server-arm64 wol-server + elif [[ "$ARCH" == "armv7l" ]]; then + echo "Using ARMv7 binary" + cp wol-server-arm7 wol-server + else + echo "Using ARMv6 binary" + cp wol-server-arm6 wol-server + fi + + echo "Creating directory..." + mkdir -p ~/wol-server + + echo "Copying application..." + cp wol-server ~/wol-server/ + chmod +x ~/wol-server/wol-server + + echo "Installing service..." + sudo cp wol-server.service /etc/systemd/system/ + sudo systemctl daemon-reload + sudo systemctl enable wol-server + sudo systemctl restart wol-server + + echo "Deployment complete!" + echo "Service status:" + sudo systemctl status wol-server + EOL + + chmod +x deploy.sh + + - name: Create archive for each platform + run: | + # ARMv6 package + mkdir -p armv6-package + cp wol-server-arm6 armv6-package/wol-server-arm6 + cp wol-server.service armv6-package/ + cp deploy.sh armv6-package/ + tar -czf wol-server-armv6.tar.gz -C armv6-package . + + # All-in-one package + mkdir -p all-package + cp wol-server-arm6 all-package/ + cp wol-server.service all-package/ + cp deploy.sh all-package/ + tar -czf wol-server-all.tar.gz -C all-package . + + - name: Create Release + id: create_release + uses: softprops/action-gh-release@v1 + if: github.ref == 'refs/heads/main' + with: + tag_name: v${{ github.run_number }} + name: Release v${{ github.run_number }} + draft: false + prerelease: false + files: | + wol-server-arm6 + wol-server.service + deploy.sh + wol-server-armv6.tar.gz + wol-server-all.tar.gz + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index 1dc4058..52eeac9 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,147 @@ -# wol-delemaco -Script to boot delemaco +![Server Status Screenshot](https://placeholder-for-screenshot.png) + +## Features + +- **Status Monitoring**: Real-time status checks to determine if your server is online or offline +- **Wake-on-LAN**: Boot your server remotely with the click of a button +- **Remote Shutdown**: Safely shut down your server when it's not needed +- **Responsive UI**: Simple, mobile-friendly interface with color-coded status indicators +- **Lightweight**: Built with Go for minimal resource usage, perfect for Raspberry Pi Zero + +## Requirements + +- Raspberry Pi (Zero, 2, 3, 4, etc.) +- Go (version 1.16 or higher) +- wakeonlan utility +- SSH access to the target server (for shutdown functionality) +- Target server configured for Wake-on-LAN + +## Installation + +### 1. Install Dependencies + +```bash +sudo apt update +sudo apt install golang-go wakeonlan +``` + +### 2. Clone the Repository + +```bash +git clone https://github.com/yourusername/wol-server.git +cd wol-server +``` + +### 3. Configure the Application + +Edit the constants in `main.go` to match your server: + +```go +const ( + serverName = "yourserver" // Hostname or IP address of your server + macAddress = "xx:xx:xx:xx:xx:xx" // MAC address of your server's network interface + port = "8080" // Port to run the web application on +) +``` + +### 4. Build the Application + +```bash +go build -o wol-server +``` + +### 5. Set Up as a System Service + +Create a systemd service file: + +```bash +sudo nano /etc/systemd/system/wol-server.service +``` + +Add the following content (adjust paths if needed): + +``` +[Unit] +Description=WOL Server Go Application +After=network.target + +[Service] +User=pi +WorkingDirectory=/home/pi/wol-server +ExecStart=/home/pi/wol-server/wol-server +Restart=always + +[Install] +WantedBy=multi-user.target +``` + +Enable and start the service: + +```bash +sudo systemctl enable wol-server +sudo systemctl start wol-server +``` + +## SSH Configuration for Remote Shutdown + +For the shutdown functionality to work, you need to set up password-less SSH: + +1. Generate an SSH key on your Raspberry Pi: + ```bash + ssh-keygen -t rsa + ``` + +2. Copy the key to your target server: + ```bash + ssh-copy-id user@yourserver + ``` + +3. Configure sudo on the target server to allow password-less shutdown: + ```bash + # On the target server, run: + sudo visudo + + # Add this line (replacing 'user' with your username): + user ALL=(ALL) NOPASSWD: /sbin/shutdown + ``` + +## Usage + +Access the web interface by navigating to `http://raspberry-pi-ip:8080` in your browser. + +The interface provides: + +- Current server status (Online/Offline) +- Boot button - sends a Wake-on-LAN magic packet to your server +- Shutdown button - safely shuts down your server via SSH +- Refresh button - manually updates the status display + +## Troubleshooting + +- **Server won't boot**: + - Verify that Wake-on-LAN is enabled in your server's BIOS/UEFI + - Confirm the MAC address is correct + - Check if your router blocks Wake-on-LAN packets + +- **Shutdown doesn't work**: + - Verify SSH key setup + - Check sudo configuration on target server + - Test manual SSH command: `ssh user@server sudo shutdown -h now` + +- **Web interface not accessible**: + - Ensure the service is running: `sudo systemctl status wol-server` + - Check for firewall rules blocking port 8080 + - Verify the Raspberry Pi is connected to the network + +## Contributing + +Contributions are welcome! Please feel free to submit a Pull Request. + +## License + +This project is licensed under the MIT License - see the LICENSE file for details. + +## Acknowledgments + +- Inspired by the need for a simple, lightweight server power management tool +- Thanks to the Go community for the excellent standard library that makes web development straightforward diff --git a/delemaco.sh b/delemaco.sh deleted file mode 100644 index 0777e00..0000000 --- a/delemaco.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash - -# Configuration -SERVER="delemaco" # Server to ping -echo "Content-type: text/html" -echo -# Function to ping the server and generate HTML output -generate_html() { - local server=$1 - - # Ping the server (send 1 packet and wait for 1 second) - ping -c 1 -W 1 "$server" > /dev/null 2>&1 - - if [ $? -eq 0 ]; then - status="Online" - color="green" - else - status="Offline" - color="red" - fi - - # Generate HTML content - HTML_CONTENT=$(cat < - - - - - Server Status - - - -
- Server $server is currently $status. -
- - -EOL -) - echo "$HTML_CONTENT" -} - -# Run the function and save the output to a variable -HTML_OUTPUT=$(generate_html "$SERVER") - -# Print the HTML content -echo "$HTML_OUTPUT" diff --git a/main.go b/main.go new file mode 100644 index 0000000..affeb98 --- /dev/null +++ b/main.go @@ -0,0 +1,417 @@ +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) + } +} diff --git a/shutdown-delemaco.sh b/shutdown-delemaco.sh deleted file mode 100644 index f77964d..0000000 --- a/shutdown-delemaco.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash - -SERVER="delemaco" # Server to ping - -echo "Content-type: text/html" -echo -# Function to ping the server and generate HTML output -generate_html() { - local server=$1 - - # Ping the server (send 1 packet and wait for 1 second) - ping -c 1 -W 1 "$server" > /dev/null 2>&1 - if [ $? -eq 0 ]; then - status="Shutdown" - color="gray" - sudo shutdown - else - status="Offline" - color="red" - fi - - - # Generate HTML content - HTML_CONTENT=$(cat < - - - - - Server Status - - - -
- Server $server is currently $status. -
- - -EOL -) - echo "$HTML_CONTENT" -} - -# Run the function and save the output to a variable -HTML_OUTPUT=$(generate_html "$SERVER") - -# Print the HTML content -echo "$HTML_OUTPUT" diff --git a/wol-delemaco.sh b/wol-delemaco.sh deleted file mode 100644 index ff464a1..0000000 --- a/wol-delemaco.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash - -SERVER="delemaco" # Server to ping - -echo "Content-type: text/html" -echo -# Function to ping the server and generate HTML output -generate_html() { - local server=$1 - - # Ping the server (send 1 packet and wait for 1 second) - ping -c 1 -W 1 "$server" > /dev/null 2>&1 - if [ $? -eq 0 ]; then - status="Online" - color="green" - else - status="Booting" - color="gray" - wakeonlan b8:cb:29:a1:f3:88 - fi - - - # Generate HTML content - HTML_CONTENT=$(cat < - - - - - Server Status - - - -
- Server $server is currently $status. -
- - -EOL -) - echo "$HTML_CONTENT" -} - -# Run the function and save the output to a variable -HTML_OUTPUT=$(generate_html "$SERVER") - -# Print the HTML content -echo "$HTML_OUTPUT"