From 4262c5b798bc5ea955a930a376024d2bcc4d215b Mon Sep 17 00:00:00 2001 From: Mikhail Chusavitin Date: Thu, 18 Jun 2026 15:50:42 +0300 Subject: [PATCH] Add SAA DMI editor to Tools page Adds a new card to the web UI Tools page for reading and editing DMI fields via SAA (In-Band). Reads current DMI configuration with GetDmiInfo, displays all fields as an editable table, and applies only the changed fields via EditDmiInfo + ChangeDmiInfo. Backs up the original DMI file to dmi-backups/ before any write, making it available in the support bundle for rollback. Also adds "saa" to the standard tool check list. Co-Authored-By: Claude Sonnet 4.6 --- audit/internal/webui/api.go | 2 +- audit/internal/webui/page_export_tools.go | 2 + audit/internal/webui/saa_dmi.go | 287 ++++++++++++++++++++++ audit/internal/webui/server.go | 2 + audit/internal/webui/task_runner.go | 6 + audit/internal/webui/tasks.go | 7 +- 6 files changed, 302 insertions(+), 4 deletions(-) create mode 100644 audit/internal/webui/saa_dmi.go diff --git a/audit/internal/webui/api.go b/audit/internal/webui/api.go index 5d2504d..ae9a394 100644 --- a/audit/internal/webui/api.go +++ b/audit/internal/webui/api.go @@ -1297,7 +1297,7 @@ func (h *handler) handleAPIInstallToRAM(w http.ResponseWriter, r *http.Request) var standardTools = []string{ "dmidecode", "smartctl", "nvme", "lspci", "ipmitool", "nvidia-smi", "dcgmi", "nv-hostengine", "memtester", "stress-ng", "nvtop", - "mstflint", + "mstflint", "saa", } func (h *handler) handleAPIToolsCheck(w http.ResponseWriter, r *http.Request) { diff --git a/audit/internal/webui/page_export_tools.go b/audit/internal/webui/page_export_tools.go index 7d31210..ac27339 100644 --- a/audit/internal/webui/page_export_tools.go +++ b/audit/internal/webui/page_export_tools.go @@ -477,6 +477,8 @@ function installToRAM() { ` + renderNVMeFormatCard() + ` +` + renderSAADMICard() + ` + +` +} diff --git a/audit/internal/webui/server.go b/audit/internal/webui/server.go index ea1e089..6b26d78 100644 --- a/audit/internal/webui/server.go +++ b/audit/internal/webui/server.go @@ -314,6 +314,8 @@ func NewHandler(opts HandlerOptions) http.Handler { mux.HandleFunc("GET /api/tools/check", h.handleAPIToolsCheck) mux.HandleFunc("GET /api/tools/nvme-formats", h.handleAPINVMeFormats) mux.HandleFunc("POST /api/tools/nvme-format/run", h.handleAPINVMeFormatRun) + mux.HandleFunc("GET /api/tools/saa-dmi", h.handleAPISAADMIRead) + mux.HandleFunc("POST /api/tools/saa-dmi/write", h.handleAPISAADMIWrite) // GPU presence / tools mux.HandleFunc("GET /api/gpu/presence", h.handleAPIGPUPresence) diff --git a/audit/internal/webui/task_runner.go b/audit/internal/webui/task_runner.go index 6836317..db597e1 100644 --- a/audit/internal/webui/task_runner.go +++ b/audit/internal/webui/task_runner.go @@ -382,6 +382,12 @@ func executeTaskWithOptions(opts *HandlerOptions, t *Task, j *jobState, ctx cont break } err = runNVMeFormatTask(ctx, j, t.params.Device, t.params.LBAF) + case "saa-dmi-write": + if len(t.params.SAADmiChanges) == 0 { + err = fmt.Errorf("no changes provided") + break + } + err = runSAADMIWriteTask(ctx, j, opts.ExportDir, t.params) default: j.append("ERROR: unknown target: " + t.Target) j.finish("unknown target") diff --git a/audit/internal/webui/tasks.go b/audit/internal/webui/tasks.go index c14b27d..7b2bce7 100644 --- a/audit/internal/webui/tasks.go +++ b/audit/internal/webui/tasks.go @@ -137,9 +137,10 @@ type taskParams struct { RampTotal int `json:"ramp_total,omitempty"` RampRunID string `json:"ramp_run_id,omitempty"` DisplayName string `json:"display_name,omitempty"` - Device string `json:"device,omitempty"` // for install - LBAF int `json:"lbaf,omitempty"` - PlatformComponents []string `json:"platform_components,omitempty"` + Device string `json:"device,omitempty"` // for install + LBAF int `json:"lbaf,omitempty"` + PlatformComponents []string `json:"platform_components,omitempty"` + SAADmiChanges []saaChange `json:"saa_dmi_changes,omitempty"` } type persistedTask struct {