Files
warewulf/cmd/warewulfd/warewulfd.go
2020-10-29 19:23:56 -07:00

116 lines
3.0 KiB
Go

package main
import (
"fmt"
"io"
"os"
"path"
"strconv"
"strings"
"github.com/hpcng/warewulf/internal/pkg/assets"
"net/http"
)
const LocalStateDir = "/var/warewulf"
func ipxe(w http.ResponseWriter, req *http.Request) {
url := strings.Split(req.URL.Path, "/")
if url[2] == "" {
fmt.Printf("ERROR: Bad iPXE request from %s\n", req.RemoteAddr)
return
}
node := assets.FindByHwaddr(url[2])
if node.HostName != "" {
fmt.Printf("IPXE: %15s: hwaddr=%s\n", node.Fqdn, url[2])
fmt.Fprintf(w, "#!ipxe\n")
fmt.Fprintf(w, "echo Now booting Warewulf - v4 Proof of Concept\n")
fmt.Fprintf(w, "set base http://192.168.1.1:9873/\n")
fmt.Fprintf(w, "kernel ${base}/files/kernel/%s crashkernel=no quiet\n", url[2])
fmt.Fprintf(w, "initrd ${base}/files/vnfs/%s\n", url[2])
fmt.Fprintf(w, "initrd ${base}/files/kmods/%s\n", url[2])
fmt.Fprintf(w, "initrd ${base}/files/overlay/%s\n", url[2])
fmt.Fprintf(w, "boot\n")
} else {
fmt.Printf("ERROR: iPXE request from unknown Node (hwaddr=%s)\n", url[2])
}
return
}
func files(w http.ResponseWriter, req *http.Request) {
url := strings.Split(req.URL.Path, "/")
node := assets.FindByHwaddr(url[3])
fmt.Printf("GET: %15s: %s\n", node.Fqdn, req.URL.Path)
if url[2] == "kernel" {
if node.KernelVersion != "" {
kernelFile := fmt.Sprintf("%s/provision/kernels/vmlinuz-%s", LocalStateDir, node.KernelVersion)
sendFile(w, kernelFile, node.Fqdn)
}
} else if url[2] == "kmods" {
if node.KernelVersion != "" {
kmodsFile := fmt.Sprintf("%s/provision/kernels/kmods-%s.img", LocalStateDir, node.KernelVersion)
sendFile(w, kmodsFile, node.Fqdn)
}
} else if url[2] == "vnfs" {
if node.Vnfs != "" {
vnfsFile := fmt.Sprintf("%s/provision/bases/%s.img.gz", LocalStateDir, path.Base(node.Vnfs))
sendFile(w, vnfsFile, node.Fqdn)
}
} else if url[2] == "overlay" {
if node.Overlay!= "" {
overlayFile := fmt.Sprintf("%s/provision/overlays/%s.img", LocalStateDir, node.Fqdn)
sendFile(w, overlayFile, node.Fqdn)
}
}
return
}
func sendFile(w http.ResponseWriter, filename string, sendto string) {
fmt.Printf("SEND: %15s: %s\n", sendto, filename)
fd, err := os.Open(filename)
if err != nil {
fmt.Println("ERROR: %s\n", err)
return
}
FileHeader := make([]byte, 512)
fd.Read(FileHeader)
FileContentType := http.DetectContentType(FileHeader)
FileStat, _ := fd.Stat()
FileSize := strconv.FormatInt(FileStat.Size(), 10)
w.Header().Set("Content-Disposition", "attachment; filename=kernel")
w.Header().Set("Content-Type", FileContentType)
w.Header().Set("Content-Length", FileSize)
fd.Seek(0, 0)
io.Copy(w, fd)
}
func main() {
http.HandleFunc("/ipxe/", ipxe)
http.HandleFunc("/files/", files)
http.ListenAndServe(":9873", nil)
}