Tag Komodo deployments with game + canonical map name
New deployments get two tags attached (e.g. "t5" and "zombie_pentagon") so operators can filter the Komodo deployment list by game and by map. Tags are ensured via read/ListTags + write/CreateTag fallback, then attached with write/UpdateTagsOnResource against the deployment name. Tag application runs fire-and-forget after CreateDeployment: any failure logs a warning and the server creation proceeds. Tags are cosmetic organization inside Komodo, not a correctness requirement.
This commit is contained in:
@@ -9,6 +9,8 @@ import {
|
||||
komodoDestroyDeployment,
|
||||
komodoDeleteDeployment,
|
||||
komodoInspectHealthy,
|
||||
komodoEnsureTag,
|
||||
komodoUpdateTagsOnResource,
|
||||
type CreateDeploymentSpec,
|
||||
type DeploymentEnvVar
|
||||
} from '../integrations/komodo.js';
|
||||
@@ -198,7 +200,13 @@ export async function createServer(input: CreateServerInput): Promise<CreateServ
|
||||
return { ok: false, kind: 'db', message: `failed to insert server row: ${(err as Error).message}` };
|
||||
}
|
||||
|
||||
// Step 4: execute/Deploy — actually start the container.
|
||||
// Step 4: apply Komodo tags so operators can filter the deployment list
|
||||
// by game/map. Best-effort — a tag failure doesn't roll back the server;
|
||||
// the deployment is fully functional without cosmetic tags. Fires in
|
||||
// parallel to keep the create latency down.
|
||||
void applyDeploymentTags(name, 't5', mapEntry.canonical);
|
||||
|
||||
// Step 5: execute/Deploy — actually start the container.
|
||||
const deployRes = await komodoDeploy(name);
|
||||
if (!deployRes.ok) {
|
||||
// Container never started — undo everything so retrying is clean.
|
||||
@@ -208,13 +216,40 @@ export async function createServer(input: CreateServerInput): Promise<CreateServ
|
||||
return { ok: false, kind: 'komodo', message: `Deploy: ${deployRes.message}` };
|
||||
}
|
||||
|
||||
// Step 5: kick the sweep so RCON status polling for this server starts
|
||||
// Step 6: kick the sweep so RCON status polling for this server starts
|
||||
// now instead of on the next 15s tick.
|
||||
void kick().catch((err) => console.error('[createServer] post-create kick failed:', err));
|
||||
|
||||
return { ok: true, name, port };
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure `game` and `map` tags exist in Komodo, then attach both to the given
|
||||
* deployment. Purely cosmetic — any failure here logs and returns; the caller
|
||||
* treats it as fire-and-forget.
|
||||
*/
|
||||
async function applyDeploymentTags(deployment: string, gameTagName: string, mapTagName: string): Promise<void> {
|
||||
try {
|
||||
const [gameTag, mapTag] = await Promise.all([
|
||||
komodoEnsureTag(gameTagName),
|
||||
komodoEnsureTag(mapTagName)
|
||||
]);
|
||||
const tagIds: string[] = [];
|
||||
if (gameTag.ok) tagIds.push(gameTag.id);
|
||||
else console.warn(`[createServer] tag "${gameTagName}": ${gameTag.message}`);
|
||||
if (mapTag.ok) tagIds.push(mapTag.id);
|
||||
else console.warn(`[createServer] tag "${mapTagName}": ${mapTag.message}`);
|
||||
if (tagIds.length === 0) return;
|
||||
|
||||
const res = await komodoUpdateTagsOnResource('Deployment', deployment, tagIds);
|
||||
if (!res.ok) {
|
||||
console.warn(`[createServer] UpdateTagsOnResource for ${deployment}: ${res.message}`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(`[createServer] tag application for ${deployment} threw:`, err);
|
||||
}
|
||||
}
|
||||
|
||||
export async function destroyServer(name: string): Promise<DestroyServerResult> {
|
||||
const row = getServer(name);
|
||||
if (!row) {
|
||||
|
||||
Reference in New Issue
Block a user