diff --git a/src/app/settings/maintenance/qs-maintenance-settings.tsx b/src/app/settings/maintenance/qs-maintenance-settings.tsx
index 40147b6..2a2169a 100644
--- a/src/app/settings/maintenance/qs-maintenance-settings.tsx
+++ b/src/app/settings/maintenance/qs-maintenance-settings.tsx
@@ -1,7 +1,7 @@
'use client';
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
-import { cleanupOldBuildJobs, cleanupOldTmpFiles, purgeRegistryImages, updateRegistry, updateTraefikMeCertificates } from "../server/actions";
+import { cleanupOldBuildJobs, cleanupOldTmpFiles, deleteAllFailedAndSuccededPods, purgeRegistryImages, updateRegistry, updateTraefikMeCertificates } from "../server/actions";
import { Button } from "@/components/ui/button";
import { Toast } from "@/frontend/utils/toast.utils";
import { useConfirmDialog } from "@/frontend/states/zustand.states";
@@ -87,6 +87,16 @@ export default function QuickStackMaintenanceSettings({
}
}}>Update Traefik.me SSL Certificates
+
+
;
diff --git a/src/app/settings/server/actions.ts b/src/app/settings/server/actions.ts
index 9427c37..0f433b6 100644
--- a/src/app/settings/server/actions.ts
+++ b/src/app/settings/server/actions.ts
@@ -16,6 +16,7 @@ import buildService from "@/server/services/build.service";
import { PathUtils } from "@/server/utils/path.utils";
import { FsUtils } from "@/server/utils/fs.utils";
import traefikMeDomainStandaloneService from "@/server/services/standalone-services/traefik-me-domain-standalone.service";
+import standalonePodService from "@/server/services/standalone-services/standalone-pod.service";
export const updateIngressSettings = async (prevState: any, inputData: QsIngressSettingsModel) =>
saveFormAction(inputData, qsIngressSettingsZodModel, async (validatedData) => {
@@ -119,6 +120,13 @@ export const updateTraefikMeCertificates = async () =>
return new SuccessActionResult(undefined, 'Certificates will be updated, this might take a few seconds.');
});
+export const deleteAllFailedAndSuccededPods = async () =>
+ simpleAction(async () => {
+ await getAuthUserSession();
+ await standalonePodService.deleteAllFailedAndSuccededPods();
+ return new SuccessActionResult(undefined, 'Successfully deleted all failed and succeeded pods.');
+ });
+
export const purgeRegistryImages = async () =>
simpleAction(async () => {
await getAuthUserSession();
diff --git a/src/server/services/standalone-services/standalone-pod.service.ts b/src/server/services/standalone-services/standalone-pod.service.ts
index f4cd037..0ae0f2b 100644
--- a/src/server/services/standalone-services/standalone-pod.service.ts
+++ b/src/server/services/standalone-services/standalone-pod.service.ts
@@ -2,6 +2,7 @@ import k3s from "../../adapter/kubernetes-api.adapter";
import fs from 'fs';
import stream from 'stream';
import * as k8s from '@kubernetes/client-node';
+import dataAccess from "../../../server/adapter/db.client";
class SetupPodService {
@@ -226,7 +227,18 @@ class SetupPodService {
}, 5000);
});
});
+ }
+ async deleteAllFailedAndSuccededPods() {
+ const projects = await dataAccess.client.project.findMany();
+
+ for (const project of projects) {
+ const podsOfNamespace = await k3s.core.listNamespacedPod(project.id);
+ const failedPods = podsOfNamespace.body.items.filter((pod) => ['Failed', 'Succeeded'].includes(pod.status?.phase!));
+ for (const pod of failedPods) {
+ await k3s.core.deleteNamespacedPod(pod.metadata?.name!, project.id);
+ }
+ }
}
}