feat: add controller update trigger + version checker (v0.1.8)
Hub now tracks controller_url from reports, periodically checks the Gitea registry for the latest controller image version, and shows a "Trigger Update" button on the customer detail page that proxies to the controller's self-update API endpoint using the shared API key. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -183,6 +183,85 @@
|
||||
{{end}}
|
||||
</section>
|
||||
|
||||
<!-- Controller Update -->
|
||||
<section class="card">
|
||||
<h2>Controller Update</h2>
|
||||
<div class="info-grid">
|
||||
<div class="info-item">
|
||||
<span class="label">Current version</span>
|
||||
<span class="value">v{{.Customer.ControllerVersion}}</span>
|
||||
</div>
|
||||
{{if .LatestVersion}}
|
||||
<div class="info-item">
|
||||
<span class="label">Latest version</span>
|
||||
<span class="value">
|
||||
v{{.LatestVersion}}
|
||||
{{if .UpdateAvailable}}
|
||||
<span style="color: #4ade80; margin-left: 0.3em;">● update available</span>
|
||||
{{else}}
|
||||
<span style="color: #94a3b8; margin-left: 0.3em;">— up to date</span>
|
||||
{{end}}
|
||||
</span>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .ControllerURL}}
|
||||
<div class="info-item">
|
||||
<span class="label">Controller URL</span>
|
||||
<span class="value"><a href="{{.ControllerURL}}" target="_blank" style="color: #60a5fa;">{{.ControllerURL}}</a></span>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{if and .ControllerURL .UpdateAvailable}}
|
||||
<div style="margin-top: 0.75em;">
|
||||
<button class="btn" id="btn-trigger-update" onclick="triggerControllerUpdate('{{.Customer.CustomerID}}')">
|
||||
Trigger Update
|
||||
</button>
|
||||
<span id="update-msg" style="margin-left: 0.5em; display: none;"></span>
|
||||
</div>
|
||||
{{else if and .ControllerURL (not .LatestVersion)}}
|
||||
<div style="margin-top: 0.75em;">
|
||||
<button class="btn" id="btn-trigger-update" onclick="triggerControllerUpdate('{{.Customer.CustomerID}}')">
|
||||
Trigger Update
|
||||
</button>
|
||||
<span id="update-msg" style="margin-left: 0.5em; display: none;"></span>
|
||||
<p style="color: #94a3b8; font-size: 0.85em; margin-top: 0.3em;">Registry check not configured — cannot verify if update is available</p>
|
||||
</div>
|
||||
{{end}}
|
||||
</section>
|
||||
|
||||
<script>
|
||||
function triggerControllerUpdate(customerID) {
|
||||
if (!confirm('Trigger self-update on this controller?\n\nThe controller will be briefly unavailable during restart.')) return;
|
||||
var btn = document.getElementById('btn-trigger-update');
|
||||
var msg = document.getElementById('update-msg');
|
||||
btn.disabled = true;
|
||||
btn.textContent = 'Triggering...';
|
||||
msg.style.display = 'none';
|
||||
fetch('/customers/' + customerID + '/trigger-update', {method: 'POST'})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.ok) {
|
||||
msg.textContent = 'Update triggered — controller restarting';
|
||||
msg.style.display = 'inline';
|
||||
msg.style.color = '#4ade80';
|
||||
} else {
|
||||
msg.textContent = data.error || 'Failed';
|
||||
msg.style.display = 'inline';
|
||||
msg.style.color = '#f87171';
|
||||
btn.disabled = false;
|
||||
btn.textContent = 'Trigger Update';
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
msg.textContent = 'Connection error';
|
||||
msg.style.display = 'inline';
|
||||
msg.style.color = '#f87171';
|
||||
btn.disabled = false;
|
||||
btn.textContent = 'Trigger Update';
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Notifications -->
|
||||
<section class="card">
|
||||
<h2>Notifications</h2>
|
||||
|
||||
Reference in New Issue
Block a user