mirror of
https://github.com/biersoeckli/QuickStack.git
synced 2026-02-10 21:49:19 -06:00
feat: add functionality to delete orphaned containers in maintenance settings
This commit is contained in:
@@ -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({
|
||||
}
|
||||
}}><RotateCcw />Update Traefik.me SSL Certificates</Button>
|
||||
|
||||
<Button variant="secondary" onClick={async () => {
|
||||
if (await useConfirm.openConfirmDialog({
|
||||
title: 'Delete Orphaned Containers',
|
||||
description: 'This action deletes all unused pods (failed or succeded). Use this action to free up resources.',
|
||||
okButton: "Delete Orphaned Containers"
|
||||
})) {
|
||||
Toast.fromAction(() => deleteAllFailedAndSuccededPods());
|
||||
}
|
||||
}}><Trash /> Delete Orphaned Containers</Button>
|
||||
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user