102 lines · 2.8 KB · TypeScript
RawDownload
import type { apiRestoreBackup } from "@dokploy/server/db/schema";import type { Compose } from "@dokploy/server/services/compose";import type { Destination } from "@dokploy/server/services/destination";import type { z } from "zod";import { getS3Credentials } from "../backups/utils";import { execAsync, execAsyncRemote } from "../process/execAsync";import { getRestoreCommand } from "./utils"; interface DatabaseCredentials {	databaseUser?: string;	databasePassword?: string;} export const restoreComposeBackup = async (	compose: Compose,	destination: Destination,	backupInput: z.infer<typeof apiRestoreBackup>,	emit: (log: string) => void,) => {	try {		if (backupInput.databaseType === "web-server") {			return;		}		const { serverId, appName, composeType } = compose; 		const rcloneFlags = getS3Credentials(destination);		const bucketPath = `:s3:${destination.bucket}`;		const backupPath = `${bucketPath}/${backupInput.backupFile}`;		let rcloneCommand = `rclone cat ${rcloneFlags.join(" ")} "${backupPath}" | gunzip`; 		if (backupInput.metadata?.mongo) {			rcloneCommand = `rclone copy ${rcloneFlags.join(" ")} "${backupPath}"`;		} 		let credentials: DatabaseCredentials = {}; 		switch (backupInput.databaseType) {			case "postgres":				credentials = {					databaseUser: backupInput.metadata?.postgres?.databaseUser,				};				break;			case "mariadb":				credentials = {					databaseUser: backupInput.metadata?.mariadb?.databaseUser,					databasePassword: backupInput.metadata?.mariadb?.databasePassword,				};				break;			case "mysql":				credentials = {					databasePassword: backupInput.metadata?.mysql?.databaseRootPassword,				};				break;			case "mongo":				credentials = {					databaseUser: backupInput.metadata?.mongo?.databaseUser,					databasePassword: backupInput.metadata?.mongo?.databasePassword,				};				break;		} 		const restoreCommand = getRestoreCommand({			appName: appName,			serviceName: backupInput.metadata?.serviceName,			type: backupInput.databaseType as				| "postgres"				| "mariadb"				| "mysql"				| "mongo",			credentials: {				database: backupInput.databaseName,				...credentials,			},			restoreType: composeType,			rcloneCommand,			backupFile: backupInput.backupFile,		}); 		emit("Starting restore...");		emit(			`Restoring database: ${backupInput.databaseName} from ${backupInput.backupFile}`,		); 		if (serverId) {			await execAsyncRemote(serverId, restoreCommand);		} else {			await execAsync(restoreCommand);		} 		emit("Restore completed successfully!");	} catch (error) {		console.error(error);		emit(			`Error: ${				error instanceof Error ? error.message : "Error restoring mongo backup"			}`,		);		throw new Error(			error instanceof Error ? error.message : "Error restoring mongo backup",		);	}};