Add boot image management with ISO extraction and serving
Upload Proxmox ISOs via API or dashboard UI, extract kernel+initrd using pure-Go iso9660 library, store on disk, and serve over HTTP for PXE booting. Dynamic kernel/initrd filenames per image replace the previous hardcoded paths. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"provisioning/internal/config"
|
||||
"provisioning/internal/events"
|
||||
"provisioning/internal/image"
|
||||
"provisioning/internal/model"
|
||||
"provisioning/internal/orchestrator"
|
||||
"provisioning/internal/pxe"
|
||||
@@ -23,6 +24,7 @@ type UI struct {
|
||||
Ops *store.Operations
|
||||
Locks *store.Locks
|
||||
Images *store.Images
|
||||
ImageSvc *image.Service
|
||||
Runner *orchestrator.Runner
|
||||
Orchestrator *orchestrator.HostOrchestrator
|
||||
Hub *events.Hub
|
||||
@@ -160,6 +162,57 @@ func (u *UI) ImagesPage(w http.ResponseWriter, r *http.Request) {
|
||||
renderHTML(w, imagesPage(images))
|
||||
}
|
||||
|
||||
func (u *UI) NewImageForm(w http.ResponseWriter, r *http.Request) {
|
||||
renderHTML(w, imageUploadForm(""))
|
||||
}
|
||||
|
||||
func (u *UI) UploadImage(w http.ResponseWriter, r *http.Request) {
|
||||
if err := r.ParseMultipartForm(0); err != nil {
|
||||
renderHTML(w, imageUploadForm("Invalid form submission"))
|
||||
return
|
||||
}
|
||||
|
||||
name := strings.TrimSpace(r.FormValue("name"))
|
||||
version := strings.TrimSpace(r.FormValue("version"))
|
||||
kind := strings.TrimSpace(r.FormValue("kind"))
|
||||
|
||||
file, _, err := r.FormFile("iso")
|
||||
if err != nil {
|
||||
renderHTML(w, imageUploadForm("ISO file is required"))
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = u.ImageSvc.Upload(r.Context(), image.UploadParams{
|
||||
Name: name,
|
||||
Kind: kind,
|
||||
Version: version,
|
||||
ISO: file,
|
||||
})
|
||||
if err != nil {
|
||||
renderHTML(w, imageUploadForm(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/images", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func (u *UI) SetDefaultImage(w http.ResponseWriter, r *http.Request) {
|
||||
idStr := chi.URLParam(r, "id")
|
||||
var id int64
|
||||
fmt.Sscanf(idStr, "%d", &id)
|
||||
_ = u.Images.SetDefault(r.Context(), id)
|
||||
http.Redirect(w, r, "/images", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func (u *UI) DeleteImage(w http.ResponseWriter, r *http.Request) {
|
||||
idStr := chi.URLParam(r, "id")
|
||||
var id int64
|
||||
fmt.Sscanf(idStr, "%d", &id)
|
||||
_ = u.ImageSvc.Delete(r.Context(), id)
|
||||
http.Redirect(w, r, "/images", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
var macRegex = regexp.MustCompile(`^([0-9a-fA-F]{2}[:\-]){5}[0-9a-fA-F]{2}$`)
|
||||
|
||||
func isValidMAC(mac string) bool {
|
||||
|
||||
Reference in New Issue
Block a user