Aucune sauvegarde HA n avait jamais ete faite, et git ne la couvrait pas -- un seul fichier HA y etait versionne. HA declarait pourtant trois destinations Synology, dont 10.10.10.22 et une troisieme machine en 10.10.10.50 absente de toute la documentation du projet. Quotidienne 04:45, sept copies, base d historique exclue (20 Mo au lieu de 4,4 Go), poussee sur les trois machines. La configuration passe par le websocket car l API REST ne l expose pas. Verifiee archive en main : .storage, packages, dashboards, secrets et custom_components presents, base d historique absente comme voulu. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
49 lines
2.2 KiB
JavaScript
49 lines
2.2 KiB
JavaScript
#!/usr/bin/env node
|
|
// Liste les sauvegardes Home Assistant et, pour chacune, les destinations où
|
|
// elle est RÉELLEMENT présente. C'est cette dernière colonne qui compte : une
|
|
// sauvegarde qui n'existe que sur la machine dont on se protège ne protège rien.
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
const HA_URL = process.env.HA_URL || 'http://10.10.10.17:8123';
|
|
const token = process.env.HA_TOKEN ||
|
|
fs.readFileSync(path.join(ROOT, '.env'), 'utf8').match(/^\s*HA_TOKEN\s*=\s*(.+?)\s*$/m)[1].replace(/^["']|["']$/g, '');
|
|
|
|
const HOST = {
|
|
'backup.local': '10.10.10.17 (local)',
|
|
'synology_dsm.1660NZN396007': '10.10.10.22',
|
|
'synology_dsm.14B0MPN914514': '10.10.10.50',
|
|
'synology_dsm.20A0SBRVM9PF2': '10.10.10.17',
|
|
};
|
|
|
|
const ws = new WebSocket(HA_URL.replace(/^http/, 'ws') + '/api/websocket');
|
|
ws.onmessage = (ev) => {
|
|
const m = JSON.parse(ev.data);
|
|
if (m.type === 'auth_required') return ws.send(JSON.stringify({ type: 'auth', access_token: token }));
|
|
if (m.type === 'auth_ok') return ws.send(JSON.stringify({ id: 1, type: 'backup/info' }));
|
|
if (m.type === 'result') {
|
|
const r = m.result || {};
|
|
if (r.backups?.length) {
|
|
for (const b of r.backups) {
|
|
const mo = (b.agents ? Object.entries(b.agents) : []);
|
|
console.log(`\n${b.name} (${b.backup_id})`);
|
|
console.log(` créée : ${new Date(b.date).toLocaleString('fr-FR', { timeZone: 'Europe/Paris' })}`);
|
|
console.log(` base incluse : ${b.database_included} automatique : ${b.with_automatic_settings}`);
|
|
for (const [agent, info] of mo) {
|
|
const mb = info.size ? (info.size / 1048576).toFixed(1) + ' Mo' : '?';
|
|
console.log(` → ${(HOST[agent] || agent).padEnd(22)} ${mb.padStart(9)}`);
|
|
}
|
|
}
|
|
} else {
|
|
console.log('Aucune sauvegarde.');
|
|
}
|
|
if (r.next_automatic_backup) {
|
|
console.log(`\nProchaine automatique : ${new Date(r.next_automatic_backup).toLocaleString('fr-FR', { timeZone: 'Europe/Paris' })}`);
|
|
}
|
|
ws.close(); process.exit(0);
|
|
}
|
|
};
|
|
setTimeout(() => { console.error('délai dépassé'); process.exit(1); }, 30000);
|