added install script for agent
changed backend to agent
This commit is contained in:
1 parent
7f2785fb05
commit
0b059aec1d
669 files changed
+767
-70582
No files matched your search
@@ -0,0 +1,88 @@
|
||||
import { Router } from 'express';
|
||||
import { access } from 'node:fs/promises';
|
||||
import { constants } from 'node:fs';
|
||||
import { config, missingEnvVars } from '../config.js';
|
||||
import { spawnCommand, runRestic } from '../executor.js';
|
||||
|
||||
export const healthRouter = Router();
|
||||
|
||||
healthRouter.get('/', async (_req, res) => {
|
||||
const missing = missingEnvVars();
|
||||
const checks = {
|
||||
config: checkValue(!missing.length, missing.length ? `missing: ${missing.join(', ')}` : 'ok'),
|
||||
commands: await checkCommands({
|
||||
incus: ['version'],
|
||||
zfs: ['version'],
|
||||
zpool: ['version'],
|
||||
restic: ['version'],
|
||||
udevadm: ['--version'],
|
||||
dd: ['--version'],
|
||||
}),
|
||||
zfsPool: await checkZfsPool(),
|
||||
zvol: await checkZvolAccess(),
|
||||
resticRepository: await checkResticRepository(),
|
||||
};
|
||||
|
||||
const ok = Object.values(checks).every((value) => value.ok);
|
||||
res.status(ok ? 200 : 503).json({ ok, checks });
|
||||
});
|
||||
|
||||
async function checkCommands(commands) {
|
||||
const results = {};
|
||||
await Promise.all(Object.entries(commands).map(async ([command, args]) => {
|
||||
results[command] = await checkCommand(command, args);
|
||||
}));
|
||||
const failed = Object.entries(results).filter(([, result]) => !result.ok);
|
||||
return {
|
||||
ok: failed.length === 0,
|
||||
message: failed.length ? `failed: ${failed.map(([command]) => command).join(', ')}` : 'ok',
|
||||
details: results,
|
||||
};
|
||||
}
|
||||
|
||||
async function checkCommand(command, args) {
|
||||
try {
|
||||
const result = await spawnCommand(command, args, { ignoreExitCode: true });
|
||||
return checkValue(result.exitCode === 0, result.exitCode === 0 ? 'ok' : result.stderr.trim() || result.stdout.trim() || 'failed');
|
||||
} catch (error) {
|
||||
return checkValue(false, error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function checkZfsPool() {
|
||||
if (!config.zfsPoolName) return checkValue(false, 'ZFS_POOL_NAME is not configured');
|
||||
try {
|
||||
const result = await spawnCommand('zpool', ['list', '-Hp', '-o', 'name,size,alloc,free,cap', config.zfsPoolName], { ignoreExitCode: true });
|
||||
if (result.exitCode !== 0) return checkValue(false, result.stderr.trim() || 'zpool list failed');
|
||||
const [name, size, allocated, free, capacity] = result.stdout.trim().split('\t');
|
||||
return {
|
||||
ok: true,
|
||||
message: 'ok',
|
||||
details: { name, size: Number(size), allocated: Number(allocated), free: Number(free), capacity },
|
||||
};
|
||||
} catch (error) {
|
||||
return checkValue(false, error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function checkZvolAccess() {
|
||||
try {
|
||||
await access('/dev/zvol', constants.R_OK);
|
||||
return checkValue(true, 'ok');
|
||||
} catch (error) {
|
||||
return checkValue(false, error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function checkResticRepository() {
|
||||
try {
|
||||
const result = await runRestic(['--no-lock', 'snapshots', '--json'], { ignoreExitCode: true });
|
||||
return checkValue(result.exitCode === 0, result.exitCode === 0 ? 'ok' : result.stderr.trim() || 'restic repository check failed');
|
||||
} catch (error) {
|
||||
return checkValue(false, error.message);
|
||||
}
|
||||
}
|
||||
|
||||
function checkValue(ok, message, details = null) {
|
||||
return { ok, message, ...(details ? { details } : {}) };
|
||||
}
|
||||
Reference in new issue
Block a user