Fix: Add port allocation and EdgePublisher integration
- Allocate ports using PortAllocationService.reserve() - Pass ports to agent payload builders (game and dev) - Generate proper FQDN (slotHostname) for DNS records - Include all required fields in enqueuePublishEdge (ports, slotHostname, txnId) - Commit ports after successful provisioning - Rollback ports on error - Fixes DNS record creation, Velocity registration, and EdgePublisher jobs
This commit is contained in:
parent
167246dfc6
commit
9eb678ea25
@ -43,6 +43,7 @@ const AGENT_TEMPLATE_VMID = Number(
|
||||
|
||||
const AGENT_PORT = Number(process.env.ZLH_AGENT_PORT || 18888);
|
||||
const AGENT_TOKEN = process.env.ZLH_AGENT_TOKEN || null;
|
||||
const ZONE = process.env.TECHNITIUM_ZONE || "zerolaghub.quest";
|
||||
|
||||
/* -------------------------------------------------------------
|
||||
VERSION PARSER (Minecraft only)
|
||||
@ -107,7 +108,7 @@ function generateAdminPassword() {
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------
|
||||
GAME PAYLOAD (UNCHANGED)
|
||||
GAME PAYLOAD
|
||||
------------------------------------------------------------- */
|
||||
function buildGameAgentPayload({
|
||||
vmid,
|
||||
@ -186,9 +187,9 @@ function buildGameAgentPayload({
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------
|
||||
DEV PAYLOAD (NEW, MINIMAL, CANONICAL)
|
||||
DEV PAYLOAD
|
||||
------------------------------------------------------------- */
|
||||
function buildDevAgentPayload({ vmid, runtime, version, memoryMiB }) {
|
||||
function buildDevAgentPayload({ vmid, runtime, version, memoryMiB, ports }) {
|
||||
if (!runtime) throw new Error("runtime required for dev container");
|
||||
if (!version) throw new Error("version required for dev container");
|
||||
|
||||
@ -198,6 +199,7 @@ function buildDevAgentPayload({ vmid, runtime, version, memoryMiB }) {
|
||||
runtime,
|
||||
version,
|
||||
memory_mb: Number(memoryMiB) || 2048,
|
||||
ports: Array.isArray(ports) ? ports : [ports].filter(Boolean),
|
||||
};
|
||||
}
|
||||
|
||||
@ -283,10 +285,35 @@ export async function provisionAgentInstance(body = {}) {
|
||||
|
||||
let vmid;
|
||||
let ctIp;
|
||||
let allocatedPorts = [];
|
||||
let txnId = null;
|
||||
|
||||
try {
|
||||
vmid = await allocateVmid(ctype);
|
||||
|
||||
// Allocate ports if needed
|
||||
if (req.portsNeeded && req.portsNeeded > 0) {
|
||||
console.log(`[agentProvision] Allocating ${req.portsNeeded} port(s)`);
|
||||
txnId = crypto.randomUUID();
|
||||
|
||||
const portObjs = await PortAllocationService.reserve({
|
||||
game: req.game,
|
||||
variant: req.variant,
|
||||
customerId: req.customerId,
|
||||
vmid,
|
||||
purpose: ctype === 'game' ? 'game_main' : 'dev',
|
||||
txnId,
|
||||
count: req.portsNeeded,
|
||||
});
|
||||
|
||||
// Extract port numbers from objects
|
||||
allocatedPorts = Array.isArray(portObjs)
|
||||
? portObjs.map(p => typeof p === 'object' ? p.port : p)
|
||||
: [portObjs];
|
||||
|
||||
console.log(`[agentProvision] Allocated ports: ${allocatedPorts.join(', ')}`);
|
||||
}
|
||||
|
||||
const hostname = generateSystemHostname({
|
||||
ctype,
|
||||
game: req.game,
|
||||
@ -294,6 +321,9 @@ export async function provisionAgentInstance(body = {}) {
|
||||
vmid,
|
||||
});
|
||||
|
||||
// Generate FQDN for DNS/EdgePublisher
|
||||
const slotHostname = `${hostname}.${ZONE}`;
|
||||
|
||||
await cloneContainer({
|
||||
templateVmid: AGENT_TEMPLATE_VMID,
|
||||
vmid,
|
||||
@ -312,6 +342,7 @@ export async function provisionAgentInstance(body = {}) {
|
||||
|
||||
ctIp = await getCtIpWithRetry(vmid);
|
||||
|
||||
// Build payload WITH ports
|
||||
const payload =
|
||||
ctype === "dev"
|
||||
? buildDevAgentPayload({
|
||||
@ -319,10 +350,12 @@ export async function provisionAgentInstance(body = {}) {
|
||||
runtime: body.runtime,
|
||||
version: body.version,
|
||||
memoryMiB: req.memoryMiB,
|
||||
ports: allocatedPorts,
|
||||
})
|
||||
: buildGameAgentPayload({
|
||||
vmid,
|
||||
...req,
|
||||
ports: allocatedPorts,
|
||||
});
|
||||
|
||||
await sendAgentConfig({ ip: ctIp, payload });
|
||||
@ -335,23 +368,47 @@ export async function provisionAgentInstance(body = {}) {
|
||||
ctype,
|
||||
hostname,
|
||||
ip: ctIp,
|
||||
ports: allocatedPorts,
|
||||
payload,
|
||||
agentState: "running",
|
||||
agentLastSeen: new Date(),
|
||||
},
|
||||
});
|
||||
|
||||
// Enqueue EdgePublisher with ALL required fields
|
||||
if (allocatedPorts.length > 0) {
|
||||
console.log(`[agentProvision] Enqueuing EdgePublisher for vmid=${vmid}`);
|
||||
await enqueuePublishEdge({
|
||||
vmid,
|
||||
instanceHostname: hostname,
|
||||
slotHostname, // ← FQDN for DNS records
|
||||
instanceHostname: hostname, // ← Short hostname
|
||||
ports: allocatedPorts, // ← CRITICAL
|
||||
ctIp,
|
||||
game: req.game,
|
||||
txnId,
|
||||
});
|
||||
|
||||
// Commit ports to mark them as in-use
|
||||
await PortAllocationService.commit({ vmid, ports: allocatedPorts });
|
||||
console.log(`[agentProvision] Ports committed for vmid=${vmid}`);
|
||||
}
|
||||
|
||||
await confirmVmidAllocated(vmid);
|
||||
|
||||
return { vmid, hostname, ip: ctIp };
|
||||
return { vmid, hostname, ip: ctIp, ports: allocatedPorts };
|
||||
} catch (err) {
|
||||
console.error(`[agentProvision] ERROR for vmid=${vmid}:`, err.message);
|
||||
|
||||
// Rollback ports on failure
|
||||
if (vmid && allocatedPorts.length > 0) {
|
||||
try {
|
||||
await PortAllocationService.releaseByVmid(vmid);
|
||||
console.log(`[agentProvision] Rolled back ports for vmid=${vmid}`);
|
||||
} catch (rollbackErr) {
|
||||
console.error(`[agentProvision] Port rollback failed:`, rollbackErr.message);
|
||||
}
|
||||
}
|
||||
|
||||
if (vmid) {
|
||||
try { await deleteContainer(vmid); } catch {}
|
||||
try { await releaseVmid(vmid); } catch {}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user