Files
backupsidecar/src/backupUtils.ts
Timo Behrendt e5cd26ef16
All checks were successful
CI / Build Docker image (pull_request) Successful in 19s
sync
2025-09-01 19:53:31 +02:00

101 lines
2.6 KiB
TypeScript

import type { BackupContext } from "./backupContext";
export function parseResticSummary(output: string): string | null {
try {
const lines = output.split("\n").filter((line) => line.trim());
for (const line of lines) {
try {
const parsed = JSON.parse(line);
if (parsed.message_type === "summary") {
return `Snapshot ${parsed.snapshot_id || "none"}: files new: ${
parsed.files_new || 0
}, files changed: ${parsed.files_changed || 0}, data added: ${
parsed.data_added || 0
} bytes in ${parsed.total_duration || 0} sec`;
}
} catch {
continue;
}
}
} catch (error) {
console.warn(`Failed to parse restic output: ${error}`);
}
return null;
}
export function runResticBackup(
sourceDir: string,
context: BackupContext
): { success: boolean; output: string; summary: string | null } {
const { logger, resticRepository } = context;
logger.info(
`Starting backup of '${sourceDir}' to repository ${resticRepository}`
);
const result = Bun.spawnSync(
[
"restic",
"-r",
resticRepository,
"backup",
"--no-cache",
"--json",
"--verbose",
".",
],
{
cwd: sourceDir,
stdio: ["pipe", "pipe", "pipe"],
}
);
const output = result.stdout?.toString() + result.stderr?.toString() || "";
const success = result.success;
const summary = parseResticSummary(output);
return { success, output, summary };
}
export async function executeBackup(
backupType: string,
backupFn: () => Promise<{
success: boolean;
output: string;
summary: string | null;
}>,
context: BackupContext
): Promise<void> {
const { logger, notificationClient } = context;
try {
logger.info(`Starting ${backupType} backup process`);
const { success, output, summary } = await backupFn();
console.log(output);
if (success) {
const message = `${backupType} backup successful. ${
summary || "No summary available"
}`;
logger.info(message);
await notificationClient.sendNotification(message);
} else {
const message = `${backupType} backup failed: ${
summary || "Unknown error"
}`;
logger.error(message);
await notificationClient.sendNotification(message);
throw new Error(`${backupType} backup failed: ${message}`);
}
logger.info(`${backupType} backup completed successfully`);
} catch (error) {
const errorMessage = `${backupType} backup failed: ${error}`;
logger.error(errorMessage);
await notificationClient.sendNotification(errorMessage);
throw error;
}
}