Add Plutonium version checks and scheduled rolling restarts

This commit is contained in:
2026-09-21 18:47:24 -04:00
parent 424d6cefb6
commit 47d6dc07b7
10 changed files with 583 additions and 0 deletions
+27
View File
@@ -0,0 +1,27 @@
import { json } from '@sveltejs/kit';
import { cancelMaintenance, checkPlutonium, plutoniumStatus, queueMaintenance, saveMaintenanceSchedule } from '$lib/server/fleet/plutonium.js';
export function GET() { return json(plutoniumStatus()); }
export async function POST({ request }: { request: Request }) {
let body;
try { body = await request.json(); } catch { return json({ error: 'Invalid JSON.' }, { status: 400 }); }
if (!body || typeof body !== 'object') return json({ error: 'Invalid request.' }, { status: 400 });
if (body.action === 'check') {
await checkPlutonium();
} else if (body.action === 'schedule') {
if (typeof body.enabled !== 'boolean' || typeof body.time !== 'string' || !/^([01]\d|2[0-3]):[0-5]\d$/.test(body.time)) {
return json({ error: 'Provide enabled and a valid UTC time (HH:mm).' }, { status: 400 });
}
saveMaintenanceSchedule(body.enabled, body.time);
} else if (body.action === 'restart') {
if (!Array.isArray(body.servers) || !body.servers.length || body.servers.some((s: unknown) => typeof s !== 'string')) {
return json({ error: 'Choose servers to restart.' }, { status: 400 });
}
try { queueMaintenance(body.servers); }
catch (err) { return json({ error: (err as Error).message }, { status: 400 }); }
} else if (body.action === 'cancel') {
if (!Number.isSafeInteger(body.id) || !cancelMaintenance(body.id)) return json({ error: 'Only queued restarts can be cancelled.' }, { status: 409 });
} else return json({ error: 'Unknown action.' }, { status: 400 });
return json(plutoniumStatus());
}
+2
View File
@@ -6,6 +6,7 @@
import SectionHeader from '$ui/components/primitives/SectionHeader.svelte';
import Button from '$ui/components/primitives/Button.svelte';
import Badge from '$ui/components/primitives/Badge.svelte';
import PlutoniumMaintenance from '$ui/components/PlutoniumMaintenance.svelte';
let data = $state<SystemStatus | null>(null);
let loading = $state(false);
let error = $state('');
@@ -38,6 +39,7 @@
{#if data}<p>Example: {$timeFormat.dateTime(data.checkedAt)}</p>{/if}
{#if $timeZonePersistenceError}<p role="status">Browser storage is unavailable. Your timezone applies for this visit but cannot be saved.</p>{/if}
</section>
<PlutoniumMaintenance />
<div class="heading">
<div><h2>System status</h2><p>Check your connections and the prerequisites for a playable server.</p></div>
<Button loading={loading} onclick={() => refresh(true)}>Check connections</Button>