feat(ui): ajout machine OS/type, section Hardware, identité app (tâche 3)
- AddMachineModal : sélecteurs OS + Type machine ; createMachine accepte osFamily/machineKind (manuel prioritaire, "Autre/auto" → détection os-release) - section Hardware sur la tuile + panneau détail : os/type/virt/arch/gpu/réseau depuis machine_hardware (sonde) via GET /machines/:id/hardware - identité : favicon.svg (serveur + LED Gruvbox), favicon.ico, apple-touch-icon, PWA 192/512, site.webmanifest ; liens + theme-color dans index.html tsc 0 · 104 tests · build OK. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
import { Hono } from "hono";
|
||||
import {
|
||||
listMachines, createMachine, deleteMachine, updateMachine, getMachineRow, getCreds, testConnection,
|
||||
getMachineHardware,
|
||||
type CreateMachineInput, type UpdateMachineInput,
|
||||
} from "../services/machines.js";
|
||||
import { refreshMachine, getLatestSnapshot } from "../services/refresh.js";
|
||||
@@ -53,6 +54,14 @@ machinesRoutes.patch("/:id", async (c) => {
|
||||
}
|
||||
});
|
||||
|
||||
machinesRoutes.get("/:id/hardware", (c) => {
|
||||
try {
|
||||
return c.json(getMachineHardware(c.req.param("id")));
|
||||
} catch (err) {
|
||||
return c.json({ error: (err as Error).message }, 404);
|
||||
}
|
||||
});
|
||||
|
||||
// Sonde synchrone (lecture seule) : renvoie faits + proposition de correction.
|
||||
machinesRoutes.post("/:id/probe", async (c) => {
|
||||
try {
|
||||
|
||||
@@ -17,6 +17,8 @@ export interface CreateMachineInput {
|
||||
sudoPassword?: string | null;
|
||||
aptProxyMode?: AptProxyMode;
|
||||
aptProxyUrl?: string | null;
|
||||
osFamily?: OsFamily; // choix manuel ; sinon auto-détecté via os-release
|
||||
machineKind?: MachineKind;
|
||||
}
|
||||
|
||||
type MachineRow = typeof schema.machines.$inferSelect;
|
||||
@@ -118,11 +120,11 @@ export async function createMachine(input: CreateMachineInput): Promise<MachineV
|
||||
name: input.name,
|
||||
hostname: input.hostname,
|
||||
port: input.port,
|
||||
osFamily: os.family,
|
||||
osFamily: input.osFamily && input.osFamily !== "unknown" ? input.osFamily : os.family, // manuel prioritaire, "unknown" => auto
|
||||
osVersion: os.version || null,
|
||||
osCodename: null,
|
||||
arch: null,
|
||||
machineKind: null,
|
||||
machineKind: input.machineKind ?? null,
|
||||
virtualization: null,
|
||||
hardwareProfile: null,
|
||||
username: input.username,
|
||||
@@ -146,6 +148,26 @@ export function deleteMachine(id: string): void {
|
||||
db.delete(schema.machines).where(eq(schema.machines.id, id)).run();
|
||||
}
|
||||
|
||||
/** Faits matériels d'une machine (machine_hardware rempli par machine_probe + colonnes machines). */
|
||||
export function getMachineHardware(id: string) {
|
||||
const m = getMachineRow(id);
|
||||
if (!m) throw new Error("Machine introuvable");
|
||||
const hw = db.select().from(schema.machineHardware).where(eq(schema.machineHardware.machineId, id)).get();
|
||||
const parse = <T>(j: string | null | undefined): T[] => {
|
||||
try { return j ? (JSON.parse(j) as T[]) : []; } catch { return []; }
|
||||
};
|
||||
return {
|
||||
osFamily: m.osFamily,
|
||||
osVersion: m.osVersion,
|
||||
arch: m.arch,
|
||||
machineKind: m.machineKind,
|
||||
virtualization: m.virtualization,
|
||||
gpus: parse<string>(hw?.gpusJson),
|
||||
network: parse<{ iface: string; addr: string }>(hw?.networkJson),
|
||||
probed: !!hw,
|
||||
};
|
||||
}
|
||||
|
||||
/** Applique un proxy APT à toutes les machines. Renvoie le nombre de machines modifiées. */
|
||||
export function applyProxyToAllMachines(mode: AptProxyMode, url: string | null): number {
|
||||
const res = db
|
||||
|
||||
Reference in New Issue
Block a user