Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions web/actions/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,7 @@ export async function deleteService(
const reusableBackupIds: string[] = [];

if (!runningDeployment || !runningDeployment.containerId) {
const latestBackupIds: string[] = [];
for (const volume of volumes) {
const latestBackup = await db
.select({ id: volumeBackups.id })
Expand All @@ -569,17 +570,19 @@ export async function deleteService(
.limit(1)
.then((r) => r[0]);

if (!latestBackup) {
throw new Error(
"Stateful service must be running long enough to create a recoverable backup before deletion",
);
}
if (latestBackup) latestBackupIds.push(latestBackup.id);
}

if (latestBackupIds.length === volumes.length) {
await db
.update(volumeBackups)
.set({ isDeletionBackup: true })
.where(eq(volumeBackups.id, latestBackup.id));
reusableBackupIds.push(latestBackup.id);
.where(inArray(volumeBackups.id, latestBackupIds));
reusableBackupIds.push(...latestBackupIds);
} else if (!service.lockedServerId) {
throw new Error(
"Stateful service must have a locked server or completed backups before deletion",
);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,12 @@ export default function ConfigurationPage() {
<>
<br />
<br />
<span className="font-medium text-destructive">
No completed backup is available for every volume.
<span className="font-medium text-foreground">
This service is not currently running.
</span>{" "}
Delete will fail unless the service is running so a
fresh deletion backup can be created.
{service.lockedServerId
? "A fresh backup will be created from its stopped volumes before deletion."
: "No server or completed backup is available for its volumes, so deletion cannot start."}
</>
)}
</>
Expand Down
19 changes: 13 additions & 6 deletions web/lib/inngest/functions/service-deletion-workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,16 @@ export const serviceDeletionWorkflow = inngest.createFunction(
const createdBackupIds = await step.run(
"start-delete-backups",
async () => {
const deployment = setup.runningDeployment;
if (!deployment?.containerId) {
throw new Error("No active deployment found for deletion backup");
const backupTarget = setup.runningDeployment?.containerId
? setup.runningDeployment
: setup.service.lockedServerId
? {
serverId: setup.service.lockedServerId,
containerId: null,
}
: null;
if (!backupTarget) {
throw new Error("No server found for deletion backup");
}

const ids: string[] = [];
Expand All @@ -133,16 +140,16 @@ export const serviceDeletionWorkflow = inngest.createFunction(
volumeId: volume.id,
volumeName: volume.name,
serviceId,
serverId: deployment.serverId,
serverId: backupTarget.serverId,
status: "pending",
storagePath,
isDeletionBackup: true,
});

await enqueueWork(deployment.serverId, "backup_volume", {
await enqueueWork(backupTarget.serverId, "backup_volume", {
backupId,
serviceId,
containerId: deployment.containerId,
containerId: backupTarget.containerId,
volumeName: volume.name,
storagePath,
storageConfig: {
Expand Down
Loading