Provision instance bank credentials automatically (Refs #146)

This commit is contained in:
2026-10-12 20:44:01 -04:00
parent e071e5b574
commit d14c6a7ff4
21 changed files with 634 additions and 109 deletions
@@ -13,6 +13,7 @@ export interface NativeLaunchInput {
instance: NativeInstance;
serverKey: string;
rconPassword: string;
bankToken: string;
rebuild: boolean;
safetyOverride?: boolean;
unhealthyRecovery?: boolean;
+15 -1
View File
@@ -71,6 +71,19 @@ parentPort!.on(
};
})();
const instance = input.instance;
// Credential files travel only in this host's private operation payload, never
// shared recipes, promoted files, or the content-addressed download store.
const bankPath = posix.join(
relDestForKind('config', recipe.game),
'electric_cherry_bank.cfg'
);
if (
recipe.files.some(
(file) =>
posix.join(relDestForKind(file.kind, recipe.game), file.path) === bankPath
)
)
throw new Error('electric_cherry_bank.cfg is reserved for instance credentials.');
const payload = {
name: instance.server,
game: recipe.game,
@@ -79,13 +92,14 @@ parentPort!.on(
port: instance.port,
bindAddress: instance.bind_address,
rconPassword: password,
bank: { token: input.bankToken, configPath: bankPath },
env: {
PLUTAINER_SERVER_NAME: instance.server,
PLUTAINER_PORT: String(instance.port),
PLUTAINER_GAME: recipe.game === 't6' ? 't6zm' : 't5sp',
PLUTAINER_CONFIG_FILE: recipe.configFile,
PLUTAINER_MAP_ROTATE: 'false',
PLUTAINER_EXTRA_ARGS: `+exec electric_cherry_map.cfg +set tws_server_id ${instance.server} +map_rotate`,
PLUTAINER_EXTRA_ARGS: `+exec electric_cherry_map.cfg +exec electric_cherry_bank.cfg +set tws_server_id ${instance.server} +map_rotate`,
PLUTO_SERVER_KEY: input.serverKey
},
files: recipe.files.map((file) => ({
+2
View File
@@ -12,6 +12,7 @@ import { isIP } from 'node:net';
import { setImmediate as yieldToController } from 'node:timers/promises';
import { choosePlacement, availableHostPort, type PlacementOptions } from '../hosts/capacity.js';
import { randomBytes, randomUUID } from 'node:crypto';
import { bankCredential } from '../auth/bank.js';
import { posix } from 'node:path';
import { db } from '../db/index.js';
import { unsettledCancelledCommand } from './cancellation.js';
@@ -1936,6 +1937,7 @@ async function processJob(job: Job, eligibility: (job: Job) => string | null) {
instance,
serverKey: preparedKey,
rconPassword: preparedPassword,
bankToken: bankCredential(instance.id),
rebuild: job.action === 'rebuild' && !migration,
safetyOverride: overrideSafety,
unhealthyRecovery: host.inventory.capabilities?.includes(