fix(backup): keep old path when agent is disabled
This commit is contained in:
parent
38b4ac2c5c
commit
d5eea2fb97
1 changed files with 54 additions and 3 deletions
|
|
@ -1,10 +1,13 @@
|
||||||
|
import { Effect } from "effect";
|
||||||
import type { BackupSchedule, Volume, Repository } from "../../db/schema";
|
import type { BackupSchedule, Volume, Repository } from "../../db/schema";
|
||||||
import { resticDeps } from "../../core/restic";
|
import { config } from "../../core/config";
|
||||||
|
import { restic, resticDeps } from "../../core/restic";
|
||||||
import type { BackupRunPayload } from "@zerobyte/contracts/agent-protocol";
|
import type { BackupRunPayload } from "@zerobyte/contracts/agent-protocol";
|
||||||
import { agentManager, type BackupExecutionProgress } from "../agents/agents-manager";
|
import { agentManager, type BackupExecutionProgress } from "../agents/agents-manager";
|
||||||
import { getVolumePath } from "../volumes/helpers";
|
import { getVolumePath } from "../volumes/helpers";
|
||||||
import { decryptRepositoryConfig } from "../repositories/repository-config-secrets";
|
import { decryptRepositoryConfig } from "../repositories/repository-config-secrets";
|
||||||
import { createBackupOptions } from "./backup.helpers";
|
import { createBackupOptions } from "./backup.helpers";
|
||||||
|
import { toErrorDetails } from "../../utils/errors";
|
||||||
|
|
||||||
const LOCAL_AGENT_ID = "local";
|
const LOCAL_AGENT_ID = "local";
|
||||||
|
|
||||||
|
|
@ -56,6 +59,47 @@ const createBackupRunPayload = async ({
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const executeBackupWithoutAgent = async (
|
||||||
|
payload: BackupRunPayload,
|
||||||
|
{ signal, onProgress }: Pick<BackupExecutionRequest, "signal" | "onProgress">,
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const execution = await Effect.runPromise(
|
||||||
|
restic
|
||||||
|
.backup(payload.repositoryConfig, payload.sourcePath, {
|
||||||
|
...payload.options,
|
||||||
|
organizationId: payload.organizationId,
|
||||||
|
signal,
|
||||||
|
onProgress,
|
||||||
|
})
|
||||||
|
.pipe(
|
||||||
|
Effect.map((result) => ({ success: true as const, result })),
|
||||||
|
Effect.catchAll((error) => Effect.succeed({ success: false as const, error })),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!execution.success) {
|
||||||
|
return {
|
||||||
|
status: "failed" as const,
|
||||||
|
error: toErrorDetails(execution.error),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const { exitCode, result, warningDetails } = execution.result;
|
||||||
|
return {
|
||||||
|
status: "completed" as const,
|
||||||
|
exitCode,
|
||||||
|
result,
|
||||||
|
warningDetails,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
status: "failed" as const,
|
||||||
|
error: toErrorDetails(error),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const backupExecutor = {
|
export const backupExecutor = {
|
||||||
track: (scheduleId: number) => {
|
track: (scheduleId: number) => {
|
||||||
const abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
|
|
@ -73,23 +117,30 @@ export const backupExecutor = {
|
||||||
throw new Error(`Backup execution for schedule ${request.scheduleId} was not tracked`);
|
throw new Error(`Backup execution for schedule ${request.scheduleId} was not tracked`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const jobId = Bun.randomUUIDv7();
|
|
||||||
if (request.signal.aborted) {
|
if (request.signal.aborted) {
|
||||||
throw request.signal.reason || new Error("Operation aborted");
|
throw request.signal.reason || new Error("Operation aborted");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const jobId = Bun.randomUUIDv7();
|
||||||
|
|
||||||
const payload = await createBackupRunPayload({ ...request, jobId });
|
const payload = await createBackupRunPayload({ ...request, jobId });
|
||||||
|
|
||||||
if (request.signal.aborted) {
|
if (request.signal.aborted) {
|
||||||
throw request.signal.reason || new Error("Operation aborted");
|
throw request.signal.reason || new Error("Operation aborted");
|
||||||
}
|
}
|
||||||
|
|
||||||
return agentManager.runBackup(LOCAL_AGENT_ID, {
|
const executionResult = await agentManager.runBackup(LOCAL_AGENT_ID, {
|
||||||
scheduleId: request.scheduleId,
|
scheduleId: request.scheduleId,
|
||||||
payload,
|
payload,
|
||||||
signal: request.signal,
|
signal: request.signal,
|
||||||
onProgress: request.onProgress,
|
onProgress: request.onProgress,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (executionResult.status === "unavailable" && !config.flags.enableLocalAgent) {
|
||||||
|
return executeBackupWithoutAgent(payload, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
return executionResult;
|
||||||
},
|
},
|
||||||
cancel: async (scheduleId: number) => {
|
cancel: async (scheduleId: number) => {
|
||||||
const abortController = activeControllersByScheduleId.get(scheduleId);
|
const abortController = activeControllersByScheduleId.get(scheduleId);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue