mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
feat(backup): enhance RestoreBackup component and API to include serverId
- Added serverId prop to RestoreBackup component for better context during backup restoration. - Updated ShowBackups component to pass serverId from the Postgres object. - Modified backup API to handle serverId, allowing remote execution of backup commands when specified. - Improved file display in RestoreBackup for better user experience.
This commit is contained in:
@@ -48,6 +48,7 @@ import { toast } from "sonner";
|
|||||||
interface Props {
|
interface Props {
|
||||||
databaseId: string;
|
databaseId: string;
|
||||||
databaseType: Exclude<ServiceType, "application" | "redis">;
|
databaseType: Exclude<ServiceType, "application" | "redis">;
|
||||||
|
serverId: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const RestoreBackupSchema = z.object({
|
const RestoreBackupSchema = z.object({
|
||||||
@@ -76,7 +77,11 @@ const RestoreBackupSchema = z.object({
|
|||||||
|
|
||||||
type RestoreBackup = z.infer<typeof RestoreBackupSchema>;
|
type RestoreBackup = z.infer<typeof RestoreBackupSchema>;
|
||||||
|
|
||||||
export const RestoreBackup = ({ databaseId, databaseType }: Props) => {
|
export const RestoreBackup = ({
|
||||||
|
databaseId,
|
||||||
|
databaseType,
|
||||||
|
serverId,
|
||||||
|
}: Props) => {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
|
|
||||||
@@ -101,6 +106,7 @@ export const RestoreBackup = ({ databaseId, databaseType }: Props) => {
|
|||||||
{
|
{
|
||||||
destinationId: destionationId,
|
destinationId: destionationId,
|
||||||
search,
|
search,
|
||||||
|
serverId: serverId ?? "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: isOpen && !!destionationId,
|
enabled: isOpen && !!destionationId,
|
||||||
@@ -304,7 +310,9 @@ export const RestoreBackup = ({ databaseId, databaseType }: Props) => {
|
|||||||
form.setValue("backupFile", file);
|
form.setValue("backupFile", file);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{file}
|
<div className="flex w-full justify-between">
|
||||||
|
<span>{file}</span>
|
||||||
|
</div>
|
||||||
<CheckIcon
|
<CheckIcon
|
||||||
className={cn(
|
className={cn(
|
||||||
"ml-auto h-4 w-4",
|
"ml-auto h-4 w-4",
|
||||||
|
|||||||
@@ -74,7 +74,11 @@ export const ShowBackups = ({ id, type }: Props) => {
|
|||||||
{postgres && postgres?.backups?.length > 0 && (
|
{postgres && postgres?.backups?.length > 0 && (
|
||||||
<div className="flex flex-col lg:flex-row gap-4 w-full lg:w-auto">
|
<div className="flex flex-col lg:flex-row gap-4 w-full lg:w-auto">
|
||||||
<AddBackup databaseId={id} databaseType={type} refetch={refetch} />
|
<AddBackup databaseId={id} databaseType={type} refetch={refetch} />
|
||||||
<RestoreBackup databaseId={id} databaseType={type} />
|
<RestoreBackup
|
||||||
|
databaseId={id}
|
||||||
|
databaseType={type}
|
||||||
|
serverId={postgres.serverId}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
@@ -108,7 +112,11 @@ export const ShowBackups = ({ id, type }: Props) => {
|
|||||||
databaseType={type}
|
databaseType={type}
|
||||||
refetch={refetch}
|
refetch={refetch}
|
||||||
/>
|
/>
|
||||||
<RestoreBackup databaseId={id} databaseType={type} />
|
<RestoreBackup
|
||||||
|
databaseId={id}
|
||||||
|
databaseType={type}
|
||||||
|
serverId={postgres.serverId}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -31,7 +31,10 @@ import {
|
|||||||
|
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { execAsync } from "@dokploy/server/utils/process/execAsync";
|
import {
|
||||||
|
execAsync,
|
||||||
|
execAsyncRemote,
|
||||||
|
} from "@dokploy/server/utils/process/execAsync";
|
||||||
import { getS3Credentials } from "@dokploy/server/utils/backups/utils";
|
import { getS3Credentials } from "@dokploy/server/utils/backups/utils";
|
||||||
import { findDestinationById } from "@dokploy/server/services/destination";
|
import { findDestinationById } from "@dokploy/server/services/destination";
|
||||||
import {
|
import {
|
||||||
@@ -229,6 +232,7 @@ export const backupRouter = createTRPCRouter({
|
|||||||
z.object({
|
z.object({
|
||||||
destinationId: z.string(),
|
destinationId: z.string(),
|
||||||
search: z.string(),
|
search: z.string(),
|
||||||
|
serverId: z.string().optional(),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.query(async ({ input }) => {
|
.query(async ({ input }) => {
|
||||||
@@ -250,7 +254,16 @@ export const backupRouter = createTRPCRouter({
|
|||||||
const searchPath = baseDir ? `${bucketPath}/${baseDir}` : bucketPath;
|
const searchPath = baseDir ? `${bucketPath}/${baseDir}` : bucketPath;
|
||||||
const listCommand = `rclone lsf ${rcloneFlags.join(" ")} "${searchPath}" | head -n 100`;
|
const listCommand = `rclone lsf ${rcloneFlags.join(" ")} "${searchPath}" | head -n 100`;
|
||||||
|
|
||||||
const { stdout } = await execAsync(listCommand);
|
let stdout = "";
|
||||||
|
|
||||||
|
if (input.serverId) {
|
||||||
|
const result = await execAsyncRemote(listCommand, input.serverId);
|
||||||
|
stdout = result.stdout;
|
||||||
|
} else {
|
||||||
|
const result = await execAsync(listCommand);
|
||||||
|
stdout = result.stdout;
|
||||||
|
}
|
||||||
|
|
||||||
const files = stdout.split("\n").filter(Boolean);
|
const files = stdout.split("\n").filter(Boolean);
|
||||||
|
|
||||||
const results = baseDir
|
const results = baseDir
|
||||||
|
|||||||
Reference in New Issue
Block a user