Files
ProxmoxVE-Local/src/server/api/routers/backups.ts
Michel Roegl-Brunner 7833d5d408 Fix type errors
2025-11-28 13:21:37 +01:00

172 lines
5.2 KiB
TypeScript

import { z } from 'zod';
import { createTRPCRouter, publicProcedure } from '~/server/api/trpc';
import { getDatabase } from '~/server/database-prisma';
import { getBackupService } from '~/server/services/backupService';
import { getRestoreService } from '~/server/services/restoreService';
import { readFile } from 'fs/promises';
import { join } from 'path';
import { existsSync } from 'fs';
import stripAnsi from 'strip-ansi';
export const backupsRouter = createTRPCRouter({
// Get all backups grouped by container ID
getAllBackupsGrouped: publicProcedure
.query(async () => {
try {
const db = getDatabase();
const groupedBackups = await db.getBackupsGroupedByContainer();
// Convert Map to array format for frontend
const result: Array<{
container_id: string;
hostname: string;
backups: Array<{
id: number;
backup_name: string;
backup_path: string;
size: bigint | null;
created_at: Date | null;
storage_name: string;
storage_type: string;
discovered_at: Date;
server_id?: number;
server_name: string | null;
server_color: string | null;
}>;
}> = [];
for (const [containerId, backups] of groupedBackups.entries()) {
if (backups.length === 0) continue;
// Get hostname from first backup (all backups for same container should have same hostname)
const hostname = backups[0]?.hostname ?? '';
result.push({
container_id: containerId,
hostname,
backups: backups.map(backup => ({
id: backup.id,
backup_name: backup.backup_name,
backup_path: backup.backup_path,
size: backup.size,
created_at: backup.created_at,
storage_name: backup.storage_name,
storage_type: backup.storage_type,
discovered_at: backup.discovered_at,
server_id: backup.server_id,
server_name: backup.server?.name ?? null,
server_color: backup.server?.color ?? null,
})),
});
}
return {
success: true,
backups: result,
};
} catch (error) {
console.error('Error in getAllBackupsGrouped:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Failed to fetch backups',
backups: [],
};
}
}),
// Discover backups for all containers
discoverBackups: publicProcedure
.mutation(async () => {
try {
const backupService = getBackupService();
await backupService.discoverAllBackups();
return {
success: true,
message: 'Backup discovery completed successfully',
};
} catch (error) {
console.error('Error in discoverBackups:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Failed to discover backups',
};
}
}),
// Get restore progress from log file
getRestoreProgress: publicProcedure
.query(async () => {
try {
const logPath = join(process.cwd(), 'restore.log');
if (!existsSync(logPath)) {
return {
success: true,
logs: [],
isComplete: false
};
}
const logs = await readFile(logPath, 'utf-8');
const logLines = logs.split('\n')
.filter(line => line.trim())
.map(line => stripAnsi(line)); // Strip ANSI color codes
// Check if restore is complete by looking for completion indicators
const isComplete = logLines.some(line =>
line.includes('complete: Restore completed successfully') ||
line.includes('error: Error:') ||
line.includes('Restore completed successfully') ||
line.includes('Restore failed')
);
return {
success: true,
logs: logLines,
isComplete
};
} catch (error) {
console.error('Error reading restore logs:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Failed to read restore logs',
logs: [],
isComplete: false
};
}
}),
// Restore backup
restoreBackup: publicProcedure
.input(z.object({
backupId: z.number(),
containerId: z.string(),
serverId: z.number(),
}))
.mutation(async ({ input }) => {
try {
const restoreService = getRestoreService();
const result = await restoreService.executeRestore(
input.backupId,
input.containerId,
input.serverId
);
return {
success: result.success,
error: result.error,
progress: result.progress,
};
} catch (error) {
console.error('Error in restoreBackup:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Failed to restore backup',
progress: [],
};
}
}),
});