Use user timezone for maintenance and official Plutonium manifest

This commit is contained in:
2026-09-21 19:14:40 -04:00
parent 47d6dc07b7
commit ce6861203e
6 changed files with 161 additions and 45 deletions
+12 -12
View File
@@ -3,10 +3,9 @@ import { config, komodoConfigured, rconConfigured } from '../config.js';
import { getServer, listServers } from './servers.js';
import { rconGetPlayerCount, rconPlutoniumVersion } from '../integrations/rcon.js';
import { refreshRestartRollout, restartInRollout, rolloutHealth, rolloutWaitReason } from '../pipeline/restart-rollout.js';
import { nextMaintenanceAt, parseChangelogRevision } from '../../plutonium.js';
import { nextMaintenanceAt, parsePlutoniumManifest, PLUTONIUM_MANIFEST_URL } from '../../plutonium.js';
import type { MaintenanceJob, MaintenanceSchedule, PlutoniumRelease, PlutoniumStatus, PlutoniumVersion } from '../../plutonium.js';
const CHANGELOG = 'https://plutonium.pw/docs/changelog/';
const HOUR = 60 * 60 * 1000;
const nowIso = () => new Date().toISOString();
function readSetting<T>(key: string, fallback: T): T {
@@ -21,11 +20,12 @@ function release(): PlutoniumRelease {
return readSetting('plutonium_release', { revision: null, checkedAt: null, error: null });
}
function schedule(): MaintenanceSchedule {
return readSetting('plutonium_schedule', { enabled: false, time: '06:00', nextAt: null });
// Legacy schedules were explicitly UTC. Preserve their timing until saved.
return { timeZone: 'UTC', ...readSetting('plutonium_schedule', { enabled: false, time: '06:00', nextAt: null }) };
}
export function saveMaintenanceSchedule(enabled: boolean, time: string): void {
const nextAt = nextMaintenanceAt(time);
writeSetting('plutonium_schedule', { enabled, time, nextAt: enabled ? nextAt : null });
export function saveMaintenanceSchedule(enabled: boolean, time: string, timeZone: string): void {
const nextAt = nextMaintenanceAt(time, new Date(), timeZone);
writeSetting('plutonium_schedule', { enabled, time, timeZone, nextAt: enabled ? nextAt : null });
}
export function plutoniumStatus(): PlutoniumStatus {
const versions = db().prepare('SELECT * FROM plutonium_versions').all() as PlutoniumVersion[];
@@ -58,11 +58,11 @@ export function checkPlutonium(): Promise<void> {
async function check(): Promise<void> {
const previous = release();
try {
const response = await fetch(CHANGELOG, { signal: AbortSignal.timeout(config.httpTimeoutMs), redirect: 'error' });
if (!response.ok) throw new Error(`Changelog request failed (HTTP ${response.status}).`);
const html = await response.text();
if (html.length > 2_000_000) throw new Error('Changelog response was too large.');
writeSetting('plutonium_release', { revision: parseChangelogRevision(html), checkedAt: nowIso(), error: null });
const response = await fetch(PLUTONIUM_MANIFEST_URL, { signal: AbortSignal.timeout(config.httpTimeoutMs), redirect: 'error' });
if (!response.ok) throw new Error(`Updater manifest request failed (HTTP ${response.status}).`);
const body = await response.text();
if (body.length > 2_000_000) throw new Error('Updater manifest response was too large.');
writeSetting('plutonium_release', { revision: parsePlutoniumManifest(JSON.parse(body)), checkedAt: nowIso(), error: null });
} catch (err) {
writeSetting('plutonium_release', { ...previous, checkedAt: nowIso(), error: (err as Error).message });
}
@@ -122,7 +122,7 @@ async function runTick(): Promise<void> {
const names = listServers().map(s => s.name);
if (names.length) queueMaintenance(names);
// Coalesce missed days after downtime into one run; no restart backlog.
writeSetting('plutonium_schedule', { ...plan, nextAt: nextMaintenanceAt(plan.time) });
writeSetting('plutonium_schedule', { ...plan, nextAt: nextMaintenanceAt(plan.time, new Date(), plan.timeZone) });
}
})();
await refreshRestartRollout();