Enhance cloud-init scripts and dashboard for improved USB boot functionality</message>
<message>Update the bootstrap script to ensure hostname resolution by adding entries to /etc/hosts, preventing "sudo: unable to resolve host" errors. Modify user-data.bootstrap to include the same hostname resolution logic. Revise dashboard templates to reflect the new project name "GNSS Guard Provisioning" and improve user interface elements related to USB boot operations, including clearer instructions and status messages. These changes enhance the overall user experience and streamline the provisioning process.
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Admin · CM4 Provisioning</title>
|
||||
<title>Admin · GNSS Guard Provisioning</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&family=Outfit:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
@@ -76,6 +76,23 @@
|
||||
<p id="goldenInfo" class="mono" style="font-size:0.9rem;">Loading…</p>
|
||||
</div>
|
||||
|
||||
<!-- Update boot (EEPROM) -->
|
||||
<div class="section" id="adminUpdateBootSection">
|
||||
<h2 class="section-title">Update boot (EEPROM)</h2>
|
||||
<p id="adminUpdateBootHint" class="mono" style="font-size:0.85rem; color:var(--text-muted);">When a device is connected in USB boot mode, it appears here. Use this to write EEPROM boot order (e.g. eMMC only) to the device.</p>
|
||||
<div id="adminUpdateBootDevice" style="display:none; margin-top:0.5rem;">
|
||||
<p class="mono" style="font-size:0.9rem; margin-bottom:0.5rem;">Device in USB boot mode</p>
|
||||
<div style="display:flex; align-items:center; gap:0.5rem; flex-wrap:wrap;">
|
||||
<label>Boot order:</label>
|
||||
<select id="adminEepromPreset" class="eeprom-preset" title="Boot order">
|
||||
<option value="0x1">eMMC only</option>
|
||||
</select>
|
||||
<button type="button" class="btn btn-outline btn-sm" id="adminUpdateEepromBtn">Update EEPROM</button>
|
||||
</div>
|
||||
</div>
|
||||
<p id="adminUpdateBootNone" class="mono" style="font-size:0.85rem; color:var(--text-muted); display:none;">No device in USB boot mode. Connect a device with eMMC disable jumper and USB to host.</p>
|
||||
</div>
|
||||
|
||||
<!-- Backups -->
|
||||
<div class="section">
|
||||
<h2 class="section-title">
|
||||
@@ -247,6 +264,47 @@
|
||||
authFetch('/api/admin/users', { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({username: username, password: password}) }).then(function(r){ return r.json(); }).then(function(d){ if(d.ok) { document.getElementById('addUserForm').style.display = 'none'; document.getElementById('newUsername').value = ''; document.getElementById('newPassword').value = ''; fetchUsers(); } else alert(d.error); });
|
||||
};
|
||||
|
||||
function fetchPendingDevices() {
|
||||
authFetch('/api/pending-devices').then(function(r){ return r.json(); }).then(function(d){
|
||||
var devEl = document.getElementById('adminUpdateBootDevice');
|
||||
var noneEl = document.getElementById('adminUpdateBootNone');
|
||||
if (d.usb) {
|
||||
if (devEl) devEl.style.display = 'block';
|
||||
if (noneEl) noneEl.style.display = 'none';
|
||||
} else {
|
||||
if (devEl) devEl.style.display = 'none';
|
||||
if (noneEl) noneEl.style.display = 'block';
|
||||
}
|
||||
}).catch(function(){});
|
||||
}
|
||||
function fetchEepromPresets() {
|
||||
authFetch('/api/eeprom-presets').then(function(r){ return r.json(); }).then(function(d){
|
||||
var sel = document.getElementById('adminEepromPreset');
|
||||
if (!sel) return;
|
||||
sel.innerHTML = '';
|
||||
(d.presets || []).forEach(function(p){
|
||||
var opt = document.createElement('option');
|
||||
opt.value = p.id || p.value;
|
||||
opt.textContent = p.label || p.id || p.value;
|
||||
sel.appendChild(opt);
|
||||
});
|
||||
}).catch(function(){});
|
||||
}
|
||||
fetchPendingDevices();
|
||||
fetchEepromPresets();
|
||||
var adminUpdateEepromBtn = document.getElementById('adminUpdateEepromBtn');
|
||||
if (adminUpdateEepromBtn) {
|
||||
adminUpdateEepromBtn.onclick = function(){
|
||||
var presetEl = document.getElementById('adminEepromPreset');
|
||||
var bootOrder = (presetEl && presetEl.value) ? presetEl.value : '0x1';
|
||||
authFetch('/api/device-action', { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({ source: 'usb', action: 'eeprom_update', boot_order: bootOrder }) })
|
||||
.then(function(r){ return r.json(); })
|
||||
.then(function(d){ if (d.ok) { fetchPendingDevices(); alert('Update EEPROM sent. The host will write to the device.'); } else alert(d.error || 'Failed'); })
|
||||
.catch(function(){ alert('Request failed'); });
|
||||
};
|
||||
}
|
||||
setInterval(fetchPendingDevices, 3000);
|
||||
|
||||
fetchBackups(); fetchCloudinit(); fetchUsers(); fetchLogs(); fetchGolden();
|
||||
setInterval(fetchLogs, 30000);
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user