mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-10-19 07:01:35 +00:00
fix(project-export-import): keep restoring dumps when file writes fail, check local networks correctly
This commit is contained in:
@@ -91,6 +91,7 @@ const executeImport = async (
|
||||
...postApplyErrors,
|
||||
...(await restoreDumps(ctx.db, snapshot, result, workDir, {
|
||||
emit: (message) => updateImportJob(importId, { message }),
|
||||
skipServiceIds: new Set(postApplyErrors.map((error) => error.serviceId)),
|
||||
})),
|
||||
];
|
||||
updateImportJob(importId, { restoreErrors, deployCandidates });
|
||||
|
||||
@@ -885,7 +885,12 @@ export const validatePlan = async (
|
||||
if (!row || row.organizationId !== organizationId) {
|
||||
throw new Error("Not found in this organization");
|
||||
}
|
||||
if ((row.serverId ?? null) !== probeServerIdForRequirement(key)) {
|
||||
const requirement = requirementByKey.get(key);
|
||||
if (
|
||||
requirement &&
|
||||
(row.serverId ?? null) !==
|
||||
networkDestServerId(requirement, serviceServerMap, plan.serverMap)
|
||||
) {
|
||||
throw new Error(
|
||||
`Network ${row.name} is on a different server than the services that use it`,
|
||||
);
|
||||
|
||||
@@ -141,20 +141,29 @@ const writeCertificateFiles = async (
|
||||
plan: Plan,
|
||||
result: TransferResult,
|
||||
emit: Emit,
|
||||
): Promise<void> => {
|
||||
): Promise<RestoreError[]> => {
|
||||
const errors: RestoreError[] = [];
|
||||
for (const requirement of snapshot.requirements) {
|
||||
if (requirement.kind !== "certificate" || !requirement.originalId) continue;
|
||||
const resolution = plan.resolutions[requirementKey(requirement)];
|
||||
if (resolution?.action !== "create") continue;
|
||||
const newCertificateId = result.idMap.certificate?.[requirement.originalId];
|
||||
if (!newCertificateId) continue;
|
||||
const row = await db.query.certificates.findFirst({
|
||||
where: (fields, { eq }) => eq(fields.certificateId, newCertificateId),
|
||||
});
|
||||
if (!row) continue;
|
||||
await createCertificateFiles(row as Certificate);
|
||||
emit(`Wrote certificate files for ${row.name}`);
|
||||
try {
|
||||
const row = await db.query.certificates.findFirst({
|
||||
where: (fields, { eq }) => eq(fields.certificateId, newCertificateId),
|
||||
});
|
||||
if (!row) continue;
|
||||
await createCertificateFiles(row as Certificate);
|
||||
emit(`Wrote certificate files for ${row.name}`);
|
||||
} catch (error) {
|
||||
errors.push({
|
||||
serviceId: newCertificateId,
|
||||
error: safeErrorMessage(error),
|
||||
});
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
};
|
||||
|
||||
const writeRawTraefikConfig = async (
|
||||
@@ -235,7 +244,8 @@ const writeFileMounts = async (
|
||||
snapshot: Snapshot,
|
||||
result: TransferResult,
|
||||
emit: Emit,
|
||||
): Promise<void> => {
|
||||
): Promise<RestoreError[]> => {
|
||||
const errors: RestoreError[] = [];
|
||||
for (const service of snapshot.resources.services) {
|
||||
const kind = service.kind as ServiceType;
|
||||
const oldId = service[SERVICE_ID_FIELD[kind]] as string | undefined;
|
||||
@@ -246,15 +256,24 @@ const writeFileMounts = async (
|
||||
const ownerField = SERVICE_ID_FIELD[
|
||||
kind
|
||||
] as keyof typeof mounts.$inferSelect;
|
||||
const fileMounts = await db.query.mounts.findMany({
|
||||
where: (fields, { eq, and }) =>
|
||||
and(eq(fields[ownerField], newId), eq(fields.type, "file")),
|
||||
});
|
||||
for (const mount of fileMounts) {
|
||||
await createFileMount(mount.mountId);
|
||||
emit(`Wrote mount file ${mount.filePath} for ${newId}`);
|
||||
try {
|
||||
const fileMounts = await db.query.mounts.findMany({
|
||||
where: (fields, { eq, and }) =>
|
||||
and(eq(fields[ownerField], newId), eq(fields.type, "file")),
|
||||
});
|
||||
for (const mount of fileMounts) {
|
||||
await createFileMount(mount.mountId);
|
||||
emit(`Wrote mount file ${mount.filePath} for ${newId}`);
|
||||
}
|
||||
} catch (error) {
|
||||
errors.push({
|
||||
serviceId: newId,
|
||||
serviceName: (service.name as string | undefined) ?? newId,
|
||||
error: safeErrorMessage(error),
|
||||
});
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
};
|
||||
|
||||
export const postApply = async (
|
||||
@@ -337,8 +356,10 @@ export const postApply = async (
|
||||
postApplyErrors.push(
|
||||
...(await createImportedNetworks(snapshot, plan, result, emit)),
|
||||
);
|
||||
await writeCertificateFiles(db, snapshot, plan, result, emit);
|
||||
await writeFileMounts(db, snapshot, result, emit);
|
||||
postApplyErrors.push(
|
||||
...(await writeCertificateFiles(db, snapshot, plan, result, emit)),
|
||||
...(await writeFileMounts(db, snapshot, result, emit)),
|
||||
);
|
||||
|
||||
return { deployCandidates, postApplyErrors };
|
||||
};
|
||||
|
||||
@@ -180,6 +180,7 @@ export type RestoreDumpsOptions = {
|
||||
emit?: Emit;
|
||||
deploy?: Partial<Record<RestorableKind, DeployFn>>;
|
||||
readiness?: ReadinessOptions;
|
||||
skipServiceIds?: Set<string>;
|
||||
};
|
||||
|
||||
export const restoreDumps = async (
|
||||
@@ -228,6 +229,15 @@ export const restoreDumps = async (
|
||||
});
|
||||
continue;
|
||||
}
|
||||
if (opts.skipServiceIds?.has(newServiceId)) {
|
||||
restoreErrors.push({
|
||||
serviceId: newServiceId,
|
||||
serviceName,
|
||||
error:
|
||||
"Dump not restored because the service's files could not be written",
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
const row = await (
|
||||
|
||||
Reference in New Issue
Block a user