Use host history for explicit Docker targets

This commit is contained in:
rcourtman
2026-08-26 12:45:53 +01:00
parent 08b8144fcf
commit 3414a5abda
5 changed files with 62 additions and 15 deletions
@@ -6391,8 +6391,9 @@ when at least one current machine has finite utilization evidence, so estates
without GPU telemetry do not carry an empty default column or an inert toggle.
The shared resource drawer keeps `GuestDrawerHistory` as the sole history
renderer. Agent-backed hosts, including standalone Unraid machines, Proxmox
nodes, and Docker/Podman hosts, consume the single
renderer. Agent-backed hosts and explicit `docker-host` metrics targets,
including standalone Unraid machines, Proxmox nodes, and Docker/Podman hosts,
consume the single
`frontend-modern/src/components/shared/hostMetricsHistoryModel.ts`
`HOST_METRICS_HISTORY_GROUPS` catalog so CPU temperature history cannot drift
out of one host surface while remaining on another. Host resources provide the
+10 -12
View File
@@ -1,15 +1,15 @@
{
"version": 1,
"base_sha": "5d46e7d0e76ddd069a12f62fb670fd3ec0356e9e",
"verified_at": "2026-08-26T11:27:33Z",
"base_sha": "08b8144fcff526519a8b7d7706dcc044bebf170c",
"verified_at": "2026-08-26T11:44:58Z",
"result": "passed",
"changed_paths": [
"frontend-modern/src/components/Infrastructure/resourceDetailDrawerMetricsHistoryModel.ts"
],
"content_sha256": {
"frontend-modern/src/components/Infrastructure/resourceDetailDrawerMetricsHistoryModel.ts": "6767cf06b2f3c42931deba2b9620858210d8c7ce55d261b042e752b6680a4223"
"frontend-modern/src/components/Infrastructure/resourceDetailDrawerMetricsHistoryModel.ts": "63066dea7134226ea5348be26147fd433e56225b429b88854825410dba80111a"
},
"routes": ["/truenas/storage"],
"routes": ["/docker/overview"],
"viewports": [
{
"width": 1230,
@@ -21,15 +21,13 @@
}
],
"states": [
"TrueNAS pool History with only the canonical capacity series populated",
"TrueNAS dataset History with only the canonical capacity series populated",
"TrueNAS physical-disk History at 24 hours and 7 days with activity, disk I/O, and temperature populated",
"narrow TrueNAS physical-disk History with the same populated chart catalog"
"explicit Docker host History at 24 hours with utilization, network I/O, disk I/O, and thermal series populated",
"explicit Docker host History at 7 days with the same canonical host chart catalog populated",
"narrow explicit Docker host History with the complete host chart catalog and no collecting placeholders"
],
"interactions": [
"opened archive and archive/cold from the TrueNAS storage table; each drawer rendered one populated Capacity chart and no workload-only charts",
"opened physical disk sdc and selected History; confirmed Activity, Disk I/O, and Temperature charts with zero Collecting history placeholders",
"switched the physical-disk History selector to 7 days; all three groups remained populated",
"rechecked sdc at 390 by 844; the responsive table and populated disk history remained usable"
"expanded auth-service-01 from the Docker host table and selected History; confirmed Utilization, Network I/O, Disk I/O, and Thermals with zero Collecting history placeholders",
"switched the host History selector to 7 days and back to 24 hours; all four canonical host groups remained populated",
"rechecked auth-service-01 at 390 by 844 and scrolled through Thermals; charts, range control, table rows, and page navigation remained visible and usable"
]
}
@@ -169,6 +169,29 @@ describe('ResourceDetailDrawer machine metrics history', () => {
expect(history).toHaveAttribute('data-metrics', 'disk,diskread,diskwrite,smart_temp');
});
it('renders explicit Docker host history with the canonical host catalog', async () => {
render(() => (
<ResourceDetailDrawer
resource={resource({
id: 'nebula-1-mock',
type: 'docker-host',
metricsTarget: { resourceType: 'docker-host', resourceId: 'nebula-1-mock' },
temperature: 58,
})}
/>
));
await fireEvent.click(screen.getByRole('tab', { name: 'History' }));
const history = screen.getByTestId('machine-history');
expect(history).toHaveAttribute('data-resource-type', 'docker-host');
expect(history).toHaveAttribute('data-groups', 'utilization,network,disk-io,thermals');
expect(history).toHaveAttribute(
'data-metrics',
'cpu,memory,disk,netin,netout,diskread,diskwrite,temperature',
);
});
it('adds a first-class discovery tab for Pulse Agent machines', async () => {
syncAIRuntimeSettings({ discovery_enabled: true } as Parameters<
typeof syncAIRuntimeSettings
@@ -288,6 +288,27 @@ describe('getResourceMetricsHistoryCurrentMetrics branch coverage', () => {
expect(getResourceMetricsHistoryCurrentMetrics(resource).temperature).toBe(57.5);
});
it('uses canonical host and GPU groups for an explicit Docker host target', () => {
const resource = baseResource({
type: 'docker-host',
metricsTarget: { resourceType: 'docker-host', resourceId: 'nebula-1-mock' },
agent: {
sensors: {
gpu: [{ id: '0', name: 'NVIDIA A6000', utilizationPercent: 72 }],
},
},
});
expect(getResourceMetricsHistoryGroups(resource).map((group) => group.id)).toEqual([
'utilization',
'network',
'disk-io',
'thermals',
'gpu-utilization',
'gpu-thermal',
]);
});
it('keeps workload history groups free of host-only thermals', () => {
const resource = baseResource({
type: 'vm',
@@ -110,6 +110,7 @@ const getBaseMetricsHistoryGroups = (
): GuestDrawerHistoryGroupConfig[] => {
switch (resourceType) {
case 'agent':
case 'docker-host':
return HOST_METRICS_HISTORY_GROUPS;
case 'node':
return NODE_METRICS_HISTORY_GROUPS;
@@ -127,7 +128,10 @@ export const getResourceMetricsHistoryGroups = (
): GuestDrawerHistoryGroupConfig[] => {
const target = getResourceMetricsHistoryTarget(resource);
const baseGroups = getBaseMetricsHistoryGroups(target?.resourceType);
const supportsGPUHistory = target?.resourceType === 'agent' || target?.resourceType === 'node';
const supportsGPUHistory =
target?.resourceType === 'agent' ||
target?.resourceType === 'docker-host' ||
target?.resourceType === 'node';
return supportsGPUHistory && (resource.agent?.sensors?.gpu?.length ?? 0) > 0
? [...baseGroups, ...GPU_HISTORY_GROUPS]
: baseGroups;