Improve Redfish raw replay recovery and GUI diagnostics
This commit is contained in:
@@ -646,6 +646,8 @@ function renderConfig(data) {
|
||||
|
||||
const config = data.hardware || data;
|
||||
const spec = data.specification;
|
||||
const redfishFetchErrors = Array.isArray(data.redfish_fetch_errors) ? data.redfish_fetch_errors : [];
|
||||
const visibleRedfishFetchErrors = filterVisibleRedfishFetchErrors(redfishFetchErrors);
|
||||
const devices = Array.isArray(config.devices) ? config.devices : [];
|
||||
const volumes = Array.isArray(config.volumes) ? config.volumes : [];
|
||||
|
||||
@@ -688,6 +690,32 @@ function renderConfig(data) {
|
||||
|
||||
// Specification tab
|
||||
html += '<div class="config-tab-content active" id="config-spec">';
|
||||
const partialInventory = detectPartialRedfishInventory({
|
||||
cpus,
|
||||
memory,
|
||||
redfishFetchErrors
|
||||
});
|
||||
if (partialInventory) {
|
||||
html += `<div class="spec-section">
|
||||
<h3>Частичный инвентарь</h3>
|
||||
<p class="no-data" style="margin-top: 0;">${escapeHtml(partialInventory)}</p>
|
||||
</div>`;
|
||||
}
|
||||
if (visibleRedfishFetchErrors.length > 0) {
|
||||
html += `<div class="spec-section">
|
||||
<h3>Redfish fetch errors (${visibleRedfishFetchErrors.length})</h3>
|
||||
<p class="no-data" style="margin-top: 0;">Сохранено в raw snapshot для последующего анализа в GUI.</p>
|
||||
<table class="config-table"><thead><tr><th>Endpoint</th><th>Ошибка</th></tr></thead><tbody>`;
|
||||
visibleRedfishFetchErrors.forEach(item => {
|
||||
const path = item && typeof item === 'object' ? (item.path || '-') : '-';
|
||||
const err = item && typeof item === 'object' ? (item.error || '-') : String(item || '-');
|
||||
html += `<tr>
|
||||
<td><code>${escapeHtml(String(path))}</code></td>
|
||||
<td>${escapeHtml(String(err))}</td>
|
||||
</tr>`;
|
||||
});
|
||||
html += '</tbody></table></div>';
|
||||
}
|
||||
if (spec && spec.length > 0) {
|
||||
html += '<div class="spec-section"><h3>Спецификация сервера</h3><ul class="spec-list">';
|
||||
spec.forEach(item => {
|
||||
@@ -1319,6 +1347,30 @@ function escapeHtml(text) {
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
function filterVisibleRedfishFetchErrors(items) {
|
||||
if (!Array.isArray(items)) return [];
|
||||
return items.filter(item => {
|
||||
const message = String(item && typeof item === 'object' ? (item.error || '') : item || '').toLowerCase();
|
||||
return !(
|
||||
message.startsWith('status 404 ') ||
|
||||
message.startsWith('status 405 ') ||
|
||||
message.startsWith('status 410 ') ||
|
||||
message.startsWith('status 501 ')
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function detectPartialRedfishInventory({ cpus, memory, redfishFetchErrors }) {
|
||||
const errors = Array.isArray(redfishFetchErrors) ? redfishFetchErrors : [];
|
||||
const paths = errors.map(item => String(item && typeof item === 'object' ? (item.path || '') : '')).filter(Boolean);
|
||||
const cpuMissing = (!Array.isArray(cpus) || cpus.length === 0) && paths.some(p => /\/Systems\/[^/]+\/Processors(\/)?$/i.test(p));
|
||||
const memMissing = (!Array.isArray(memory) || memory.length === 0) && paths.some(p => /\/Systems\/[^/]+\/Memory(\/)?$/i.test(p));
|
||||
if (!cpuMissing && !memMissing) return '';
|
||||
if (cpuMissing && memMissing) return 'Не удалось восстановить CPU и Memory: Redfish endpoint\'ы /Processors и /Memory были недоступны во время сбора.';
|
||||
if (cpuMissing) return 'CPU-инвентарь неполный: Redfish endpoint /Processors был недоступен во время сбора.';
|
||||
return 'Memory-инвентарь неполный: Redfish endpoint /Memory был недоступен во время сбора.';
|
||||
}
|
||||
|
||||
function calculateCPUToPCIeBalance(inventoryRows, cpus) {
|
||||
const laneByCPU = new Map();
|
||||
const cpuIndexes = new Set();
|
||||
|
||||
Reference in New Issue
Block a user