webui/collector: strip ANSI escapes in nvidia-smi topo parsing, auto-prepare drives for RAID mirror creation
- nvidia-smi underlines the topo -m header with ANSI CSI codes even when writing to a file; both NVLink matrix parsers failed to find the header and /topo showed "No NVLink-bonded GPU pairs found" on bonded systems. - raid-lsi-create-mirror failed with "resources already in use" (exit 11) on JBOD drives; the task now reads drive states and auto-converts JBOD/UBad (set good force), releases hotspares, refuses Frgn/Onln with actionable messages, and dumps preservedcache info when add vd fails. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -135,6 +135,30 @@ func TestParseGPUPairAdjacencyDoesNotChainUnrelatedGPUs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseGPUPairAdjacencyANSIUnderlinedHeader(t *testing.T) {
|
||||
// Real techdump capture: nvidia-smi underlines the header row with ANSI
|
||||
// escapes even when writing to a file, so the header line starts with
|
||||
// ESC[4m, not "GPU0".
|
||||
input := "\x1b[4m\tGPU0\tGPU1\tGPU2\tGPU3\tNIC0\tNIC1\tCPU Affinity\x1b[0m\n" +
|
||||
"GPU0\t X \tNV18\tPIX\tPIX\tNODE\tNODE\t0-31,64-95\t0\n" +
|
||||
"GPU1\tNV18\t X \tPIX\tPIX\tNODE\tNODE\t0-31,64-95\t0\n" +
|
||||
"GPU2\tPIX\tPIX\t X \tNV18\tNODE\tNODE\t0-31,64-95\t0\n" +
|
||||
"GPU3\tPIX\tPIX\tNV18\t X \tNODE\tNODE\t0-31,64-95\t0\n" +
|
||||
"NIC0\tNODE\tNODE\tNODE\tNODE\t X \tPIX\n" +
|
||||
"NIC1\tNODE\tNODE\tNODE\tNODE\tPIX\t X \n"
|
||||
|
||||
pairs := parseGPUPairAdjacency(input)
|
||||
if len(pairs) != 2 {
|
||||
t.Fatalf("pairs=%d want 2 (%#v)", len(pairs), pairs)
|
||||
}
|
||||
want := map[[2]int]bool{{0, 1}: true, {2, 3}: true}
|
||||
for _, p := range pairs {
|
||||
if !want[[2]int{p.GPUA, p.GPUB}] || p.NVLinks != 18 {
|
||||
t.Fatalf("unexpected pair %#v", p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseGPUPairAdjacencyEmptyOnNoMatrix(t *testing.T) {
|
||||
if pairs := parseGPUPairAdjacency("no gpus here"); pairs != nil {
|
||||
t.Fatalf("pairs=%v want nil", pairs)
|
||||
|
||||
Reference in New Issue
Block a user