a stack restored to new locations always keeps its compose file and stays internal

This commit is contained in:
jarek committed 2026-08-09 10:31:27 +02:00
1 parent bd06b340c5
commit 5adac5e19e
5 files changed
+667 -174

No files matched your search

@@ -1,15 +1,15 @@
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { authorize } from '$lib/server/authorize';
import { previewSnapshot } from '$lib/server/backups';
import { requireBackups } from '$lib/server/backups/route-guards';
import { previewSnapshot, previewRestoreTargets } from '$lib/server/backups';
import { validateSnapshotId } from '$lib/server/docker-validation';
import { guardSnapshotEnvAccess } from '$lib/server/backups/route-guards';
export const POST: RequestHandler = async ({ request, cookies }) => {
const auth = await authorize(cookies);
if (auth.authEnabled && !await auth.can('backups', 'manage')) {
return json({ error: 'Permission denied' }, { status: 403 });
}
const rbacDenied = await requireBackups(auth, 'manage');
if (rbacDenied) return rbacDenied;
const body = await request.json();
@@ -29,6 +29,23 @@ export const POST: RequestHandler = async ({ request, cookies }) => {
try {
const access = { isEnterprise: auth.isEnterprise, canAccessEnvironment: (id: number) => auth.canAccessEnvironment(id) };
const preview = await previewSnapshot(body.destinationId, body.snapshotId, access);
// When the caller supplies a restore mode, ALSO resolve the exact on-disk targets and probe
// them on the target host (the same computation the real restore uses). Absent `mode` keeps
// the metadata-only response the initial modal load and existing callers rely on.
if (body.mode === 'in-place' || body.mode === 'new-location') {
const targets = await previewRestoreTargets(body.destinationId, body.snapshotId, {
mode: body.mode,
environmentId: body.environmentId ?? null,
targetType: body.targetType,
targetName: body.targetName ?? null,
targetPath: body.targetPath ?? null,
volumeDestinations: body.volumeDestinations,
skipStackFiles: body.skipStackFiles,
mergeStackFiles: body.mergeStackFiles,
volumes: body.volumes,
}, access);
return json({ ...preview, targets });
}
return json(preview);
} catch (error) {
const errorMsg = error instanceof Error ? error.message : String(error);