feat: rollout

This commit is contained in:
2025-10-21 21:01:56 +02:00
parent 7def7bce81
commit a070898cab
6 changed files with 851 additions and 82 deletions

View File

@@ -137,77 +137,40 @@ class ApiClient {
});
}
// Registry API methods
async getRegistryBaseUrl() {
// Auto-detect registry server URL based on current location
const currentHost = window.location.hostname;
// If accessing from localhost, use localhost:8080
// If accessing from another device, use the same hostname but port 8080
if (currentHost === 'localhost' || currentHost === '127.0.0.1') {
return 'http://localhost:8080';
} else {
return `http://${currentHost}:8080`;
}
// Registry API methods - now proxied through gateway
async getRegistryHealth() {
return this.request('/api/registry/health', { method: 'GET' });
}
async uploadFirmwareToRegistry(metadata, firmwareFile) {
const registryBaseUrl = await this.getRegistryBaseUrl();
const formData = new FormData();
formData.append('metadata', JSON.stringify(metadata));
formData.append('firmware', firmwareFile);
const response = await fetch(`${registryBaseUrl}/firmware`, {
return this.request('/api/registry/firmware', {
method: 'POST',
body: formData
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Registry upload failed: ${errorText}`);
}
return await response.json();
}
async updateFirmwareMetadata(name, version, metadata) {
const registryBaseUrl = await this.getRegistryBaseUrl();
const response = await fetch(`${registryBaseUrl}/firmware/${encodeURIComponent(name)}/${encodeURIComponent(version)}`, {
return this.request(`/api/registry/firmware/${encodeURIComponent(name)}/${encodeURIComponent(version)}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(metadata)
body: metadata
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Registry metadata update failed: ${errorText}`);
}
return await response.json();
}
async listFirmwareFromRegistry(name = null, version = null) {
const registryBaseUrl = await this.getRegistryBaseUrl();
const query = {};
if (name) query.name = name;
if (version) query.version = version;
const response = await fetch(`${registryBaseUrl}/firmware${Object.keys(query).length ? '?' + new URLSearchParams(query).toString() : ''}`);
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Registry list failed: ${errorText}`);
}
return await response.json();
const queryString = Object.keys(query).length ? '?' + new URLSearchParams(query).toString() : '';
return this.request(`/api/registry/firmware${queryString}`, { method: 'GET' });
}
async downloadFirmwareFromRegistry(name, version) {
const registryBaseUrl = await this.getRegistryBaseUrl();
const response = await fetch(`${registryBaseUrl}/firmware/${encodeURIComponent(name)}/${encodeURIComponent(version)}`);
const response = await fetch(`${this.baseURL}/api/registry/firmware/${encodeURIComponent(name)}/${encodeURIComponent(version)}`);
if (!response.ok) {
const errorText = await response.text();
@@ -217,16 +180,16 @@ class ApiClient {
return response.blob();
}
async getRegistryHealth() {
const registryBaseUrl = await this.getRegistryBaseUrl();
const response = await fetch(`${registryBaseUrl}/health`);
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Registry health check failed: ${errorText}`);
}
return await response.json();
// Rollout API methods
async getClusterNodeVersions() {
return this.request('/api/cluster/node/versions', { method: 'GET' });
}
async startRollout(rolloutData) {
return this.request('/api/rollout', {
method: 'POST',
body: rolloutData
});
}
}
@@ -320,6 +283,9 @@ class WebSocketClient {
case 'firmware_upload_status':
this.emit('firmwareUploadStatus', data);
break;
case 'rollout_progress':
this.emit('rolloutProgress', data);
break;
default:
logger.debug('Unknown WebSocket message type:', data.type);
}