mirror of
https://github.com/biersoeckli/QuickStack.git
synced 2026-01-08 04:30:39 -06:00
added "update quickstack" button in settings
This commit is contained in:
@@ -5,7 +5,7 @@ import paramService, { ParamService } from "@/server/services/param.service";
|
||||
import { QsIngressSettingsModel, qsIngressSettingsZodModel } from "@/model/qs-settings.model";
|
||||
import { QsLetsEncryptSettingsModel, qsLetsEncryptSettingsZodModel } from "@/model/qs-letsencrypt-settings.model";
|
||||
import quickStackService from "@/server/services/qs.service";
|
||||
import { ServerActionResult } from "@/model/server-action-error-return.model";
|
||||
import { ServerActionResult, SuccessActionResult } from "@/model/server-action-error-return.model";
|
||||
|
||||
export const updateIngressSettings = async (prevState: any, inputData: QsIngressSettingsModel) =>
|
||||
saveFormAction(inputData, qsIngressSettingsZodModel, async (validatedData) => {
|
||||
@@ -47,3 +47,10 @@ export const getConfiguredHostname: () => Promise<ServerActionResult<unknown, st
|
||||
|
||||
return await paramService.getString(ParamService.QS_SERVER_HOSTNAME);
|
||||
});
|
||||
|
||||
export const updateQuickstack = async () =>
|
||||
simpleAction(async () => {
|
||||
await getAuthUserSession();
|
||||
await quickStackService.updateQuickStack();
|
||||
return new SuccessActionResult(undefined, 'QuickStack will be updated, refresh the page in a few seconds.');
|
||||
});
|
||||
|
||||
@@ -12,6 +12,7 @@ import userService from "@/server/services/user.service";
|
||||
import paramService, { ParamService } from "@/server/services/param.service";
|
||||
import QuickStackIngressSettings from "./qs-ingress-settings";
|
||||
import QuickStackLetsEncryptSettings from "./qs-letsencrypt-settings";
|
||||
import QuickStackMaintenanceSettings from "./qs-maintenance-settings";
|
||||
|
||||
export default async function ProjectPage() {
|
||||
|
||||
@@ -28,6 +29,7 @@ export default async function ProjectPage() {
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div><QuickStackIngressSettings disableNodePortAccess={disableNodePortAccess!} serverUrl={serverUrl!} /></div>
|
||||
<div> <QuickStackLetsEncryptSettings letsEncryptMail={letsEncryptMail!} /></div>
|
||||
<div><QuickStackMaintenanceSettings /></div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
32
src/app/settings/server/qs-maintenance-settings.tsx
Normal file
32
src/app/settings/server/qs-maintenance-settings.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
'use client';
|
||||
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { updateQuickstack } from "./actions";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Toast } from "@/lib/toast.utils";
|
||||
import { useConfirmDialog } from "@/lib/zustand.states";
|
||||
|
||||
export default function QuickStackMaintenanceSettings() {
|
||||
|
||||
const useConfirm = useConfirmDialog();
|
||||
|
||||
return <>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Maintenance</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Button variant="secondary" onClick={async () => {
|
||||
if (await useConfirm.openDialog({
|
||||
title: 'Update QuickStack',
|
||||
description: 'This action will restart the QuickStack service and installs the lastest version. It may take a few minutes to complete.',
|
||||
yesButton: "Update QuickStack",
|
||||
})) {
|
||||
Toast.fromAction(() => updateQuickstack());
|
||||
}
|
||||
}}>Update QuickStack</Button>
|
||||
</CardContent>
|
||||
</Card >
|
||||
|
||||
</>;
|
||||
}
|
||||
@@ -15,6 +15,10 @@ class QuickStackService {
|
||||
private readonly QUICKSTACK_SERVICEACCOUNT_NAME = 'qs-service-account';
|
||||
private readonly CLUSTER_ISSUER_NAME = 'letsencrypt-production';
|
||||
|
||||
async updateQuickStack() {
|
||||
const existingDeployment = await this.getExistingDeployment();
|
||||
await this.createOrUpdateDeployment(existingDeployment.nextAuthHostname, existingDeployment.nextAuthSecret);
|
||||
}
|
||||
|
||||
async initializeQuickStack() {
|
||||
await namespaceService.createNamespaceIfNotExists(this.QUICKSTACK_NAMESPACE)
|
||||
@@ -254,7 +258,7 @@ class QuickStackService {
|
||||
}
|
||||
}
|
||||
|
||||
async createOrUpdateDeployment(nextAuthHostname?: string, inputNextAuthSecret?: string) {
|
||||
async createOrUpdateDeployment(nextAuthHostname?: string, inputNextAuthSecret?: string, imageTag = 'latest') {
|
||||
const generatedNextAuthSecret = crypto.randomBytes(32).toString('base64');
|
||||
const existingDeployment = await this.getExistingDeployment();
|
||||
const body: V1Deployment = {
|
||||
@@ -275,6 +279,9 @@ class QuickStackService {
|
||||
metadata: {
|
||||
labels: {
|
||||
app: this.QUICKSTACK_DEPLOYMENT_NAME
|
||||
},
|
||||
annotations: {
|
||||
deploymentTimestamp: new Date().getTime() + "",
|
||||
}
|
||||
},
|
||||
spec: {
|
||||
@@ -287,7 +294,7 @@ class QuickStackService {
|
||||
containers: [
|
||||
{
|
||||
name: this.QUICKSTACK_DEPLOYMENT_NAME,
|
||||
image: 'quickstack/quickstack:latest',
|
||||
image: `quickstack/quickstack:${imageTag}`,
|
||||
imagePullPolicy: 'Always',
|
||||
env: [
|
||||
{
|
||||
@@ -346,7 +353,8 @@ class QuickStackService {
|
||||
const allDeployments = await k3s.apps.listNamespacedDeployment(this.QUICKSTACK_NAMESPACE);
|
||||
const existingDeployments = allDeployments.body.items.find(d => d.metadata!.name === this.QUICKSTACK_DEPLOYMENT_NAME);
|
||||
const nextAuthSecret = existingDeployments?.spec?.template?.spec?.containers?.[0].env?.find(e => e.name === 'NEXTAUTH_SECRET')?.value;
|
||||
return { existingDeployments, nextAuthSecret };
|
||||
const nextAuthHostname = existingDeployments?.spec?.template?.spec?.containers?.[0].env?.find(e => e.name === 'NEXTAUTH_URL')?.value;
|
||||
return { existingDeployments, nextAuthSecret, nextAuthHostname };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user