v0.24.0 — Pre-testing observability: debug logging, diagnostic dump, startup self-test
- Add [DEBUG] logging across all modules (backup, storage, sync, selfupdate, monitor, notify, report, assets, setup) gated behind logging.level: "debug" - Add /api/debug/dump endpoint returning full controller state JSON (debug only) - Add startup self-test validating 9 subsystems (Docker, dirs, storage, hub, restic repos, metrics DB) with pass/warn/fail summary - New packages: internal/selftest, internal/util - Constructor/signature changes: debug bool params, logger params on RunHealthCheck and BuildReport, smart watchdog probe logging Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,11 +5,14 @@ package storage
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/util"
|
||||
)
|
||||
|
||||
// lsblkOutput matches the top-level JSON from lsblk -J.
|
||||
@@ -193,7 +196,13 @@ func partitionToParentDisk(devPath string) string {
|
||||
// enrichWithBlkid fills in missing FSType, UUID, and Label on partitions using blkid.
|
||||
// Probes each partition individually via /host-dev (Docker overrides /dev with its own
|
||||
// tmpfs, so the host block devices are accessible at /host-dev instead).
|
||||
func enrichWithBlkid(disks []BlockDevice) {
|
||||
func enrichWithBlkid(disks []BlockDevice, logger *log.Logger, debug bool) {
|
||||
dbg := func(format string, args ...interface{}) {
|
||||
if debug && logger != nil {
|
||||
logger.Printf("[DEBUG] enrichWithBlkid: "+format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
for i := range disks {
|
||||
for j := range disks[i].Partitions {
|
||||
p := &disks[i].Partitions[j]
|
||||
@@ -202,16 +211,25 @@ func enrichWithBlkid(disks []BlockDevice) {
|
||||
if p.FSType == "" {
|
||||
if out, err := exec.Command("blkid", "-o", "value", "-s", "TYPE", hostPath).Output(); err == nil {
|
||||
p.FSType = strings.TrimSpace(string(out))
|
||||
dbg("blkid TYPE %s → %q", hostPath, p.FSType)
|
||||
} else {
|
||||
dbg("blkid TYPE %s failed: %v", hostPath, err)
|
||||
}
|
||||
}
|
||||
if p.UUID == "" {
|
||||
if out, err := exec.Command("blkid", "-o", "value", "-s", "UUID", hostPath).Output(); err == nil {
|
||||
p.UUID = strings.TrimSpace(string(out))
|
||||
dbg("blkid UUID %s → %q", hostPath, p.UUID)
|
||||
} else {
|
||||
dbg("blkid UUID %s failed: %v", hostPath, err)
|
||||
}
|
||||
}
|
||||
if p.Label == "" {
|
||||
if out, err := exec.Command("blkid", "-o", "value", "-s", "LABEL", hostPath).Output(); err == nil {
|
||||
p.Label = strings.TrimSpace(string(out))
|
||||
dbg("blkid LABEL %s → %q", hostPath, p.Label)
|
||||
} else {
|
||||
dbg("blkid LABEL %s failed: %v", hostPath, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,7 +238,13 @@ func enrichWithBlkid(disks []BlockDevice) {
|
||||
|
||||
// ScanDisks detects all block devices and classifies them into
|
||||
// available (not mounted, not system) and system/mounted disks.
|
||||
func ScanDisks() (*ScanResult, error) {
|
||||
func ScanDisks(logger *log.Logger, debug bool) (*ScanResult, error) {
|
||||
dbg := func(format string, args ...interface{}) {
|
||||
if debug && logger != nil {
|
||||
logger.Printf("[DEBUG] ScanDisks: "+format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
out, err := exec.Command(
|
||||
"lsblk", "-J", "-b",
|
||||
"-o", "NAME,PATH,SIZE,TYPE,FSTYPE,MOUNTPOINT,MODEL,RM",
|
||||
@@ -229,11 +253,15 @@ func ScanDisks() (*ScanResult, error) {
|
||||
return nil, fmt.Errorf("lsblk failed: %w", err)
|
||||
}
|
||||
|
||||
dbg("raw lsblk JSON: %s", util.TruncateStr(string(out), 500))
|
||||
|
||||
var parsed lsblkOutput
|
||||
if err := json.Unmarshal(out, &parsed); err != nil {
|
||||
return nil, fmt.Errorf("lsblk JSON parse failed: %w", err)
|
||||
}
|
||||
|
||||
dbg("lsblk returned %d block devices", len(parsed.BlockDevices))
|
||||
|
||||
// Get system disk names from host fstab (works correctly inside container)
|
||||
systemDiskNames := getSystemDiskNames()
|
||||
|
||||
@@ -287,16 +315,27 @@ func ScanDisks() (*ScanResult, error) {
|
||||
isSystem := systemDiskNames[dev.Name]
|
||||
bd.Mounted = anyMounted || isSystem
|
||||
|
||||
classification := "available"
|
||||
if isSystem || anyMounted {
|
||||
classification = "system"
|
||||
result.SystemDisks = append(result.SystemDisks, bd)
|
||||
} else {
|
||||
result.AvailableDisks = append(result.AvailableDisks, bd)
|
||||
}
|
||||
|
||||
dbg("disk %s: model=%q size=%s partitions=%d removable=%v classification=%s",
|
||||
bd.Name, bd.Model, bd.Size, len(bd.Partitions), bd.Removable, classification)
|
||||
|
||||
for _, p := range bd.Partitions {
|
||||
dbg(" partition %s: fstype=%q mountpoint=%q size=%s", p.Name, p.FSType, p.MountPoint, p.Size)
|
||||
}
|
||||
}
|
||||
|
||||
dbg("classification result: %d available, %d system", len(result.AvailableDisks), len(result.SystemDisks))
|
||||
|
||||
// Enrich FSType, UUID, Label from blkid (lsblk can't probe fstype in container)
|
||||
enrichWithBlkid(result.AvailableDisks)
|
||||
enrichWithBlkid(result.SystemDisks)
|
||||
enrichWithBlkid(result.AvailableDisks, logger, debug)
|
||||
enrichWithBlkid(result.SystemDisks, logger, debug)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user