mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-31 12:48:10 +00:00
feat(fleet): add remote node update management (#353)
Add the ability to check for outdated nodes and trigger over-the-air updates from Fleet View. Nodes self-update by pulling the latest Docker image and recreating their container via the "last breath" pattern. Backend: - SelfUpdateService: self-container identification via HOSTNAME + Docker Compose labels, triggers pull + force-recreate - CapabilityRegistry: runtime capability disabling via disableCapability() - POST /api/system/update (202 + deferred self-update) - GET /api/fleet/update-status (version comparison across fleet) - POST /api/fleet/nodes/:nodeId/update (single node) - POST /api/fleet/update-all (bulk remote update) - In-memory update tracker with 5-min timeout Frontend: - Node Updates modal with summary stats, search filter, table layout, per-node Update buttons, and bulk Update All - Version badges and update-available indicators on node cards - ReconnectingOverlay for local node updates (polls /api/health) - 5s fast-poll when any node is actively updating - UpdateStatusBadge shared component for consistent badge rendering Requires Skipper (Pro) tier. Nodes must be deployed via Docker Compose with Docker socket access.
This commit is contained in:
@@ -27,6 +27,7 @@ export const CAPABILITIES = [
|
||||
'api-tokens',
|
||||
'users',
|
||||
'registries',
|
||||
'self-update',
|
||||
] as const;
|
||||
|
||||
export type Capability = (typeof CAPABILITIES)[number];
|
||||
@@ -41,6 +42,19 @@ export interface RemoteMeta {
|
||||
capabilities: string[];
|
||||
}
|
||||
|
||||
// Runtime capability overrides — services call disableCapability() during init
|
||||
const disabledCapabilities = new Set<Capability>();
|
||||
|
||||
export function disableCapability(c: Capability): void {
|
||||
disabledCapabilities.add(c);
|
||||
}
|
||||
|
||||
/** Returns capabilities this instance actually supports at runtime. */
|
||||
export function getActiveCapabilities(): readonly string[] {
|
||||
if (disabledCapabilities.size === 0) return CAPABILITIES;
|
||||
return CAPABILITIES.filter(c => !disabledCapabilities.has(c));
|
||||
}
|
||||
|
||||
/** Fetch /api/meta from a remote Sencho instance. Returns empty data on failure. */
|
||||
export async function fetchRemoteMeta(baseUrl: string, apiToken: string): Promise<RemoteMeta> {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user