Show provisioning status during server creation
This commit is contained in:
@@ -86,6 +86,7 @@
|
||||
let empty = $derived(healthy.filter(server => server.last_players === 0).length);
|
||||
let problems = $derived(servers.filter(server => server.health === 'offline' || server.health === 'stale'));
|
||||
let starting = $derived(servers.filter(server => server.health === 'starting').length);
|
||||
let provisioning = $derived(servers.filter(server => server.health === 'provisioning').length);
|
||||
let filtered = $derived(servers.filter(server => matchesFleet(server, query, filter, game, pinned, activeOperations, $uiNow))
|
||||
.sort((a, b) => {
|
||||
const pinOrder = Number(pinned.includes(b.name)) - Number(pinned.includes(a.name));
|
||||
@@ -161,13 +162,13 @@
|
||||
<div class="setup-note"><span><strong>Finish system setup</strong> · {!$fleetIntegrations.komodo ? 'Komodo' : ''}{!$fleetIntegrations.komodo && !$fleetIntegrations.rcon ? ' and ' : ''}{!$fleetIntegrations.rcon ? 'RCON' : ''} not configured.</span><a href="/settings">Review setup →</a></div>
|
||||
{/if}
|
||||
|
||||
{#if problems.length || attentionOperations.length || starting}
|
||||
{#if problems.length || attentionOperations.length || starting || provisioning}
|
||||
<div class="attention" class:has-issues={problems.length > 0 || attentionOperations.length > 0}>
|
||||
<span class="attention-mark" aria-hidden="true">{problems.length || attentionOperations.length ? '!' : '✓'}</span>
|
||||
<div class="attention-copy">
|
||||
{#if problems.length}
|
||||
<button onclick={() => { resetFilters(); filter = 'attention'; }}>{problems.length} {problems.length === 1 ? 'server needs' : 'servers need'} attention →</button>
|
||||
{:else}<strong>{servers.length ? starting ? `${starting} ${starting === 1 ? 'server is' : 'servers are'} starting` : 'All servers healthy' : 'Preparing your fleet'}</strong>{/if}
|
||||
{:else}<strong>{provisioning ? `${provisioning} ${provisioning === 1 ? 'server is' : 'servers are'} provisioning` : servers.length ? starting ? `${starting} ${starting === 1 ? 'server is' : 'servers are'} starting` : 'All servers healthy' : 'Preparing your fleet'}</strong>{/if}
|
||||
|
||||
</div>
|
||||
{#if attentionOperations.length}<a href="#fleet-operations" onclick={() => operationsOpen = true}>{attentionOperations.length} operation {attentionOperations.length === 1 ? 'needs' : 'need'} attention →</a>{/if}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { kick } from '$lib/server/pipeline/worker.js';
|
||||
import { json } from '@sveltejs/kit';
|
||||
import { listServers, heldByBeta } from '$lib/server/fleet/servers.js';
|
||||
import { classifyHealth } from '$lib/server/fleet/health.js';
|
||||
import { isProvisioning } from '$lib/server/fleet/provisioning.js';
|
||||
import { queueCreateServer } from '$lib/server/fleet/create.js';
|
||||
import { config, komodoConfigured, rconConfigured } from '$lib/server/config.js';
|
||||
import type { RconPlayer } from '$lib/server/integrations/rcon.js';
|
||||
@@ -20,7 +21,8 @@ function safeJson<T>(raw: string | null): T | null {
|
||||
export async function GET() {
|
||||
const rconHost = config.rcon.host;
|
||||
const servers = listServers().map((s) => {
|
||||
const ready = !s.container_state || s.container_state === 'running';
|
||||
const provisioning = isProvisioning(s.name);
|
||||
const ready = !provisioning && (!s.container_state || s.container_state === 'running');
|
||||
return {
|
||||
...s,
|
||||
last_players: ready ? s.last_players : null,
|
||||
@@ -30,7 +32,7 @@ export async function GET() {
|
||||
game_started_at: ready ? s.game_started_at : null,
|
||||
game_ended_at: ready ? s.game_ended_at : null,
|
||||
roster: ready ? safeJson<RconPlayer[]>(s.last_roster) : null,
|
||||
health: classifyHealth(s.last_seen_at, s.last_error, s.container_state),
|
||||
health: provisioning ? 'provisioning' : classifyHealth(s.last_seen_at, s.last_error, s.container_state),
|
||||
replySnippet: ready ? s.last_reply_snippet : null,
|
||||
// Derived endpoint — same logic as endpointFor() but without asking
|
||||
// Komodo. If we don't have a port yet, endpoint is null.
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
let gameInProgress = $derived(!!effectiveGameStartedAt && !effectiveGameEndedAt && !!effectiveActiveSince);
|
||||
let gameElapsed = $derived(fresh && gameInProgress ? elapsedSince(effectiveGameStartedAt, $uiNow) : null);
|
||||
|
||||
let hasDiagnosticIssue = $derived(effectiveHealth !== 'online' && effectiveHealth !== 'starting');
|
||||
let hasDiagnosticIssue = $derived(effectiveHealth !== 'online' && effectiveHealth !== 'starting' && effectiveHealth !== 'provisioning');
|
||||
|
||||
function ago(iso: string | null, now: number): string {
|
||||
if (!iso) return 'never';
|
||||
@@ -243,6 +243,7 @@
|
||||
<span class="health-label">
|
||||
{effectiveHealth === 'online' ? 'Online' :
|
||||
effectiveHealth === 'starting' ? 'Starting' :
|
||||
effectiveHealth === 'provisioning' ? 'Provisioning' :
|
||||
effectiveHealth === 'stale' ? 'Stale' : 'Offline'}
|
||||
</span>
|
||||
</div>
|
||||
@@ -286,7 +287,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if effectiveHealth !== 'starting'}<RoundTelemetry {name} />{/if}
|
||||
{#if effectiveHealth !== 'starting' && effectiveHealth !== 'provisioning'}<RoundTelemetry {name} />{/if}
|
||||
|
||||
</Card>
|
||||
|
||||
@@ -348,7 +349,9 @@
|
||||
<Card padding="lg">
|
||||
<div class="panel-head">
|
||||
<h2>RCON diagnostic</h2>
|
||||
{#if effectiveHealth === 'starting'}
|
||||
{#if effectiveHealth === 'provisioning'}
|
||||
<Badge variant="info" uppercase>Provisioning</Badge>
|
||||
{:else if effectiveHealth === 'starting'}
|
||||
<Badge variant="info" uppercase>Waiting for container</Badge>
|
||||
{:else if hasDiagnosticIssue}
|
||||
<Badge variant="warning" uppercase>Issue</Badge>
|
||||
|
||||
Reference in New Issue
Block a user