fix: repair brace mismatch in DataContext and replace PV Pool column with Dataset
- TnsCsiDataContext: pool stats fetch was outside the outer try block due to a brace mismatch introduced when adding TrueNAS API integration; this caused the entire fetchAsync function to throw a syntax-level error, breaking the OverviewPage - StorageClassColumns (PV): replace non-populating Pool column with Dataset column (tns-csi driver writes datasetName, not pool, into PV volumeAttributes) Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
This commit is contained in:
@@ -168,32 +168,32 @@ export function TnsCsiDataProvider({ children }: { children: React.ReactNode })
|
|||||||
setVolumeSnapshots([]);
|
setVolumeSnapshots([]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TrueNAS pool stats (only when API key is configured)
|
|
||||||
const config = getTnsCsiConfig();
|
// TrueNAS pool stats (only when API key is configured)
|
||||||
if (config.truenasApiKey.trim()) {
|
const config = getTnsCsiConfig();
|
||||||
// Determine server: explicit override → first SC server param → fail gracefully
|
if (config.truenasApiKey.trim()) {
|
||||||
const server = config.truenasServerOverride.trim();
|
const server = config.truenasServerOverride.trim();
|
||||||
if (server) {
|
if (server) {
|
||||||
try {
|
try {
|
||||||
const pools = await fetchTruenasPoolStats(server, config.truenasApiKey.trim());
|
const pools = await fetchTruenasPoolStats(server, config.truenasApiKey.trim());
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
setPoolStats(pools);
|
setPoolStats(pools);
|
||||||
setPoolStatsError(null);
|
setPoolStatsError(null);
|
||||||
}
|
}
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
setPoolStats([]);
|
setPoolStats([]);
|
||||||
setPoolStatsError(err instanceof Error ? err.message : String(err));
|
setPoolStatsError(err instanceof Error ? err.message : String(err));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (!cancelled) {
|
||||||
|
setPoolStats([]);
|
||||||
|
setPoolStatsError(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} catch (err: unknown) {
|
||||||
if (!cancelled) {
|
|
||||||
setPoolStats([]);
|
|
||||||
setPoolStatsError(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err: unknown) {
|
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
setAsyncError(err instanceof Error ? err.message : String(err));
|
setAsyncError(err instanceof Error ? err.message : String(err));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* StorageClassColumns — registerResourceTableColumnsProcessor for StorageClass and PV tables.
|
* StorageClassColumns — registerResourceTableColumnsProcessor for StorageClass and PV tables.
|
||||||
*
|
*
|
||||||
* Adds Protocol/Pool/Server columns to the native /storage-classes table and
|
* Adds Protocol/Pool/Server columns to the native /storage-classes table and
|
||||||
* Protocol/Volume Handle columns to the native /persistent-volumes table.
|
* Protocol/Dataset columns to the native /persistent-volumes table.
|
||||||
*
|
*
|
||||||
* Items in column processors are KubeObject class instances from Headlamp.
|
* Items in column processors are KubeObject class instances from Headlamp.
|
||||||
* Raw Kubernetes JSON fields (parameters, spec, status) must be accessed
|
* Raw Kubernetes JSON fields (parameters, spec, status) must be accessed
|
||||||
@@ -131,18 +131,18 @@ export function buildPVColumns() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Volume Handle',
|
label: 'Dataset',
|
||||||
getValue: (pv: unknown): string | null => {
|
getValue: (pv: unknown): string | null => {
|
||||||
const driver = getField(pv, 'spec', 'csi', 'driver') as string | undefined;
|
const driver = getField(pv, 'spec', 'csi', 'driver') as string | undefined;
|
||||||
if (driver !== TNS_CSI_PROVISIONER) return null;
|
if (driver !== TNS_CSI_PROVISIONER) return null;
|
||||||
const h = getField(pv, 'spec', 'csi', 'volumeHandle');
|
const d = getField(pv, 'spec', 'csi', 'volumeAttributes', 'datasetName');
|
||||||
return typeof h === 'string' ? h : null;
|
return typeof d === 'string' ? d : null;
|
||||||
},
|
},
|
||||||
render: (pv: unknown) => {
|
render: (pv: unknown) => {
|
||||||
const driver = getField(pv, 'spec', 'csi', 'driver') as string | undefined;
|
const driver = getField(pv, 'spec', 'csi', 'driver') as string | undefined;
|
||||||
if (driver !== TNS_CSI_PROVISIONER) return <span>—</span>;
|
if (driver !== TNS_CSI_PROVISIONER) return <span>—</span>;
|
||||||
const handle = getField(pv, 'spec', 'csi', 'volumeHandle') as string | undefined;
|
const dataset = getField(pv, 'spec', 'csi', 'volumeAttributes', 'datasetName') as string | undefined;
|
||||||
return <span style={{ fontFamily: 'monospace', fontSize: '0.85em' }}>{handle ?? '—'}</span>;
|
return <span style={{ fontFamily: 'monospace', fontSize: '0.85em' }}>{dataset ?? '—'}</span>;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
Reference in New Issue
Block a user