feat(hub/agent): alphabetical disk ordering and root disk renaming (#2006)

This commit is contained in:
Sven van Ginkel
2026-08-30 13:09:04 -04:00
committed by GitHub
parent fa9de55433
commit 87620f3251
7 changed files with 46 additions and 33 deletions
+7 -1
View File
@@ -193,7 +193,13 @@ func (a *Agent) gatherStats(options common.DataRequestOptions) *system.CombinedD
data.Stats.ExtraFs = make(map[string]*system.FsStats)
data.Info.ExtraFsPct = make(map[string]float64)
for name, stats := range a.fsStats {
if !stats.Root && stats.DiskTotal > 0 {
if stats.Root {
if stats.Name != "" {
data.Info.RootDiskName = stats.Name
}
continue
}
if stats.DiskTotal > 0 {
// Use custom name if available, otherwise use device name
key := name
if stats.Name != "" {
+14 -11
View File
@@ -18,10 +18,11 @@ import (
// fsRegistrationContext holds the shared lookup state needed to resolve a
// filesystem into the tracked fsStats key and metadata.
type fsRegistrationContext struct {
filesystem string // value of optional FILESYSTEM env var
isWindows bool
efPath string // path to extra filesystems (default "/extra-filesystems")
diskIoCounters map[string]disk.IOCountersStat
filesystem string // device part of optional FILESYSTEM env var
filesystemName string // optional custom name from FILESYSTEM=device__name
isWindows bool
efPath string // path to extra filesystems (default "/extra-filesystems")
diskIoCounters map[string]disk.IOCountersStat
}
// diskDiscovery groups the transient state for a single initializeDiskInfo run so
@@ -177,7 +178,7 @@ func (d *diskDiscovery) addConfiguredRootFs() bool {
for _, p := range d.partitions {
if filesystemMatchesPartitionSetting(d.ctx.filesystem, p) {
d.addFsStat(p.Device, p.Mountpoint, true, "")
d.addFsStat(p.Device, p.Mountpoint, true, d.ctx.filesystemName)
return true
}
}
@@ -185,7 +186,7 @@ func (d *diskDiscovery) addConfiguredRootFs() bool {
// FILESYSTEM may name a physical disk absent from partitions (e.g. ZFS lists
// dataset paths like zroot/ROOT/default, not block devices).
if ioKey, match := findIoDevice(d.ctx.filesystem, d.ctx.diskIoCounters); match {
d.agent.fsStats[ioKey] = &system.FsStats{Root: true, Mountpoint: d.rootMountPoint}
d.agent.fsStats[ioKey] = &system.FsStats{Root: true, Mountpoint: d.rootMountPoint, Name: d.ctx.filesystemName}
return true
}
@@ -300,7 +301,8 @@ func (d *diskDiscovery) addExtraFilesystemFolders(folderNames []string) {
// Sets up the filesystems to monitor for disk usage and I/O.
func (a *Agent) initializeDiskInfo() {
filesystem, _ := utils.GetEnv("FILESYSTEM")
filesystemRaw, _ := utils.GetEnv("FILESYSTEM")
filesystem, filesystemName := parseFilesystemEntry(filesystemRaw)
hasRoot := false
isWindows := runtime.GOOS == "windows"
@@ -323,10 +325,11 @@ func (a *Agent) initializeDiskInfo() {
}
slog.Debug("Disk I/O", "diskstats", diskIoCounters)
ctx := fsRegistrationContext{
filesystem: filesystem,
isWindows: isWindows,
diskIoCounters: diskIoCounters,
efPath: "/extra-filesystems",
filesystem: filesystem,
filesystemName: filesystemName,
isWindows: isWindows,
diskIoCounters: diskIoCounters,
efPath: "/extra-filesystems",
}
// Get the appropriate root mount point for this system
+9 -12
View File
@@ -78,14 +78,7 @@ func TestParseFilesystemEntry(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
fsEntry := strings.TrimSpace(tt.input)
var fs, customName string
if parts := strings.SplitN(fsEntry, "__", 2); len(parts) == 2 {
fs = strings.TrimSpace(parts[0])
customName = strings.TrimSpace(parts[1])
} else {
fs = fsEntry
}
fs, customName := parseFilesystemEntry(tt.input)
assert.Equal(t, tt.expectedFs, fs)
assert.Equal(t, tt.expectedName, customName)
@@ -287,8 +280,9 @@ func TestAddConfiguredRootFs(t *testing.T) {
rootMountPoint: "/",
partitions: []disk.PartitionStat{{Device: "/dev/ada0p2", Mountpoint: "/"}},
ctx: fsRegistrationContext{
filesystem: "/dev/ada0p2",
isWindows: false,
filesystem: "/dev/ada0p2",
filesystemName: "root disk",
isWindows: false,
diskIoCounters: map[string]disk.IOCountersStat{
"ada0": {Name: "ada0", ReadBytes: 1000, WriteBytes: 1000},
},
@@ -302,6 +296,7 @@ func TestAddConfiguredRootFs(t *testing.T) {
assert.True(t, exists)
assert.True(t, stats.Root)
assert.Equal(t, "/", stats.Mountpoint)
assert.Equal(t, "root disk", stats.Name)
})
t.Run("adds root from io device when partition is missing", func(t *testing.T) {
@@ -310,8 +305,9 @@ func TestAddConfiguredRootFs(t *testing.T) {
agent: agent,
rootMountPoint: "/sysroot",
ctx: fsRegistrationContext{
filesystem: "zroot",
isWindows: false,
filesystem: "zroot",
filesystemName: "root pool",
isWindows: false,
diskIoCounters: map[string]disk.IOCountersStat{
"nda0": {Name: "nda0", Label: "zroot", ReadBytes: 1000, WriteBytes: 1000},
},
@@ -325,6 +321,7 @@ func TestAddConfiguredRootFs(t *testing.T) {
assert.True(t, exists)
assert.True(t, stats.Root)
assert.Equal(t, "/sysroot", stats.Mountpoint)
assert.Equal(t, "root pool", stats.Name)
})
t.Run("returns false when filesystem cannot be resolved", func(t *testing.T) {
+1
View File
@@ -157,6 +157,7 @@ type Info struct {
ExtraFsPct map[string]float64 `json:"efs,omitempty" cbor:"21,keyasint,omitempty"`
Services []uint16 `json:"sv,omitempty" cbor:"22,keyasint,omitempty"` // [totalServices, numFailedServices]
Battery [2]uint8 `json:"bat,omitzero" cbor:"23,keyasint,omitzero"` // [percent, charge state]
RootDiskName string `json:"rdn,omitempty" cbor:"24,keyasint,omitempty"` // custom name for root disk (set via FILESYSTEM=device__name)
}
// Data that does not change during process lifetime and is not needed in All Systems table
@@ -114,8 +114,10 @@ export function DiskUsageChart({ systemData, extraFsName }: { systemData: System
diskSize = Math.round(diskSize)
}
const title = extraFsName ? `${extraFsName} ${t`Usage`}` : t`Disk Usage`
const description = extraFsName ? t`Disk usage of ${extraFsName}` : t`Usage of root partition`
const rootName = systemData.system?.info?.rdn
const rootLabel = rootName ?? t`Root`
const title = extraFsName ? `${extraFsName} ${t`Usage`}` : `${rootLabel} ${t`Usage`}`
const description = extraFsName ? t`Disk usage of ${extraFsName}` : t`Disk usage of ${rootLabel}`
return (
<ChartCard empty={dataEmpty} grid={grid} title={title} description={description}>
@@ -152,8 +154,10 @@ export function DiskIOChart({ systemData, extraFsName }: { systemData: SystemDat
return null
}
const title = extraFsName ? `${extraFsName} I/O` : t`Disk I/O`
const description = extraFsName ? t`Throughput of ${extraFsName}` : t`Throughput of root filesystem`
const rootName = systemData.system?.info?.rdn
const rootLabel = rootName ?? t`Root`
const title = extraFsName ? `${extraFsName} I/O` : `${rootLabel} I/O`
const description = extraFsName ? t`Throughput of ${extraFsName}` : t`Throughput of ${rootLabel}`
const hasMoreIOMetrics = chartData.systemStats?.some((record) => record.stats?.dios?.at(0))
@@ -264,7 +268,7 @@ export function ExtraFsCharts({ systemData }: { systemData: SystemData }) {
return (
<div className="grid xl:grid-cols-2 gap-4">
{Object.keys(extraFs).map((extraFsName) => {
{Object.keys(extraFs).sort((a, b) => a.localeCompare(b)).map((extraFsName) => {
let diskSize = systemStats.at(-1)?.stats.efs?.[extraFsName].d ?? NaN
// round to nearest GB
if (diskSize >= 100) {
@@ -484,9 +484,9 @@ function DiskCellWithMultiple(info: CellContext<SystemRecord, unknown>) {
const { info: sysInfo, status, id } = info.row.original
const extraFs = Object.entries(sysInfo.efs ?? {})
const rootDiskPct = sysInfo.dp
const rootDiskName = sysInfo.rdn
// sort extra disks by percentage descending
extraFs.sort((a, b) => b[1] - a[1])
extraFs.sort((a, b) => a[0].localeCompare(b[0]))
function getIndicatorColor(pct: number) {
const threshold = getMeterStateByThresholds(pct, colorWarn, colorCrit)
@@ -541,8 +541,8 @@ function DiskCellWithMultiple(info: CellContext<SystemRecord, unknown>) {
<TooltipContent side="right" className="max-w-xs pb-2">
<div className="grid gap-1">
<div className="grid gap-0.5">
<div className="text-[0.65rem] text-muted-foreground uppercase tracking-wide tabular-nums">
<Trans context="Root disk label">Root</Trans>
<div className="text-[0.65rem] max-w-40 text-muted-foreground uppercase tracking-wide truncate tabular-nums">
{rootDiskName ?? <Trans context="Root disk label">Root</Trans>}
</div>
<div className="flex gap-2 items-center tabular-nums text-xs">
<span className="min-w-7">{decimalString(rootDiskPct, rootDiskPct >= 10 ? 1 : 2)}%</span>
+2
View File
@@ -78,6 +78,8 @@ export interface SystemInfo {
efs?: Record<string, number>
/** services [totalServices, numFailedServices] */
sv?: [number, number]
/** custom root disk name */
rdn?: string
}
export interface SystemStats {