agent v0.3.17: correction statut Tailscale + overlay de reconnexion pendant l'update

This commit is contained in:
EduBox Dev
2026-06-28 20:03:49 +00:00
parent 41929be34c
commit d2c3edea2f
3 changed files with 62 additions and 21 deletions
+1 -1
View File
@@ -1 +1 @@
0.3.16
0.3.17
+3 -5
View File
@@ -214,12 +214,10 @@ func getTailscaleIP() string {
}
// isTailscaleReady reports whether tailscaled is running and has successfully
// joined the tailnet (i.e. it has a Tailscale IP). This is a stronger check
// than isTailscaleRunning which only verifies the process exists.
// joined the tailnet (i.e. it has a Tailscale IP). It does not rely on
// isTailscaleRunning because tailscaled may have been started by a previous
// agent run or externally; the important thing is that the socket responds.
func isTailscaleReady() bool {
if !isTailscaleRunning() {
return false
}
tsCmdMu.Lock()
socket := tsSocket
tsCmdMu.Unlock()
+44 -1
View File
@@ -608,9 +608,10 @@
</div>
<script>
const ws = new WebSocket('ws://' + location.host + '/ws');
let ws;
let currentView = 'activation';
let studentName = '';
let updateInProgress = false;
const instanceProgress = {}; // instanceId -> { percent, message }
const views = {
@@ -628,7 +629,14 @@
}
}
function connectWebSocket() {
ws = new WebSocket('ws://' + location.host + '/ws');
ws.onopen = () => {
if (updateInProgress) {
hideUpdateOverlay();
updateInProgress = false;
}
ws.send(JSON.stringify({action: 'check'}));
ws.send(JSON.stringify({action: 'get_status'}));
};
@@ -639,12 +647,21 @@
};
ws.onclose = () => {
if (updateInProgress) {
setTimeout(connectWebSocket, 2000);
} else {
showView('disconnected');
}
};
ws.onerror = () => {
if (!updateInProgress) {
showView('disconnected');
}
};
}
connectWebSocket();
function handleMessage(msg) {
switch (msg.action) {
@@ -968,16 +985,31 @@
</div>
</div>
`;
document.getElementById('update-overlay-bar').style.width = pct + '%';
document.getElementById('update-overlay-message').textContent = message || 'Mise à jour en cours...';
}
function showUpdateOverlay() {
updateInProgress = true;
document.getElementById('update-overlay').classList.remove('hidden');
}
function hideUpdateOverlay() {
updateInProgress = false;
document.getElementById('update-overlay').classList.add('hidden');
}
async function startAgentUpdate() {
showUpdateOverlay();
showUpdateProgress('10', 'Préparation de la mise à jour...');
try {
const res = await fetch('/api/update', {method: 'POST'});
if (!res.ok) {
hideUpdateOverlay();
showUpdateProgress('0', 'Erreur ' + res.status);
}
} catch (err) {
hideUpdateOverlay();
showUpdateProgress('0', escapeHtml(err.message));
}
}
@@ -1044,5 +1076,16 @@
.replace(/'/g, '&#039;');
}
</script>
<!-- Update in progress overlay -->
<div id="update-overlay" class="hidden" style="position: fixed; inset: 0; background: rgba(0,0,0,0.85); display: flex; align-items: center; justify-content: center; z-index: 1000;">
<div class="card" style="max-width: 400px; text-align: center;">
<div class="service-icon" style="background: var(--info); margin: 0 auto 1rem; width: 48px; height: 48px; font-size: 1.5rem;"><span class="spin"></span></div>
<h2>Mise à jour en cours</h2>
<p class="subtitle">L'agent se redémarre. Cette page se reconnectera automatiquement.</p>
<div class="progress-bar"><div id="update-overlay-bar" style="width: 0%"></div></div>
<p id="update-overlay-message" class="service-detail" style="margin-top: 0.75rem;">Préparation...</p>
</div>
</div>
</body>
</html>