cdk-local 0.167.1 → 0.167.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +2 -2
- package/dist/index.js +1 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -1
- package/dist/{local-studio-CrP4kia1.js → local-studio-B0Wlk_VO.js} +438 -217
- package/dist/local-studio-B0Wlk_VO.js.map +1 -0
- package/dist/local-studio-DDUOz4HF.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/local-studio-CrP4kia1.js.map +0 -1
|
@@ -2502,6 +2502,32 @@ async function resolveProfileRegion(profile) {
|
|
|
2502
2502
|
return resolveSdkDefaultRegion(profile);
|
|
2503
2503
|
}
|
|
2504
2504
|
|
|
2505
|
+
// src/utils/shutdown-signal.ts
|
|
2506
|
+
function signalExitCode(signal) {
|
|
2507
|
+
return signal === "SIGINT" ? 130 : 143;
|
|
2508
|
+
}
|
|
2509
|
+
function createShutdownSignalHandler(options) {
|
|
2510
|
+
const exit = options.exit ?? ((code) => process.exit(code));
|
|
2511
|
+
const writeStderr = options.writeStderr ?? ((text) => void process.stderr.write(text));
|
|
2512
|
+
let count = 0;
|
|
2513
|
+
const handler = (signal, exitCode) => {
|
|
2514
|
+
const code = exitCode ?? signalExitCode(signal === "SIGINT" ? "SIGINT" : "SIGTERM");
|
|
2515
|
+
count += 1;
|
|
2516
|
+
if (count === 1) {
|
|
2517
|
+
options.info(options.stoppingMessage(signal));
|
|
2518
|
+
options.cleanup().then(() => exit(code));
|
|
2519
|
+
return;
|
|
2520
|
+
}
|
|
2521
|
+
if (count === 2) {
|
|
2522
|
+
options.warn(`Received ${signal} again; still shutting down — waiting for the cleanup to remove the containers and networks. Send it once more to force-exit (that skips the cleanup).`);
|
|
2523
|
+
return;
|
|
2524
|
+
}
|
|
2525
|
+
writeStderr(`Force-exit on repeated ${signal}; container cleanup skipped. ${options.forceExitHint}\n`);
|
|
2526
|
+
exit(code);
|
|
2527
|
+
};
|
|
2528
|
+
return handler;
|
|
2529
|
+
}
|
|
2530
|
+
|
|
2505
2531
|
// src/utils/error-handler.ts
|
|
2506
2532
|
var CdkLocalError = class CdkLocalError extends Error {
|
|
2507
2533
|
code;
|
|
@@ -7247,10 +7273,43 @@ function getAttReads(node, out = []) {
|
|
|
7247
7273
|
}
|
|
7248
7274
|
return out;
|
|
7249
7275
|
}
|
|
7276
|
+
function computedAttributeRead(node) {
|
|
7277
|
+
if (node === null || typeof node !== "object") return void 0;
|
|
7278
|
+
if (Array.isArray(node)) {
|
|
7279
|
+
for (const item of node) {
|
|
7280
|
+
const r = computedAttributeRead(item);
|
|
7281
|
+
if (r !== void 0) return r;
|
|
7282
|
+
}
|
|
7283
|
+
return;
|
|
7284
|
+
}
|
|
7285
|
+
for (const [key, value] of Object.entries(node)) {
|
|
7286
|
+
if (key === "Fn::GetAtt" && isCrossStackIntrinsic(value)) return "a Fn::GetAtt whose logical ID or attribute name is a cross-stack reference, which CloudFormation does not accept";
|
|
7287
|
+
if (key === "Fn::Sub") {
|
|
7288
|
+
if (isCrossStackIntrinsic(Array.isArray(value) ? value[0] : value)) return "a Fn::Sub whose template is a cross-stack reference, which CloudFormation does not accept";
|
|
7289
|
+
}
|
|
7290
|
+
const r = computedAttributeRead(value);
|
|
7291
|
+
if (r !== void 0) return r;
|
|
7292
|
+
}
|
|
7293
|
+
}
|
|
7294
|
+
function withMaskWatch(context, masked) {
|
|
7295
|
+
const inner = context.crossStackResolver;
|
|
7296
|
+
if (!inner) return context;
|
|
7297
|
+
const watch = (v) => {
|
|
7298
|
+
if (v === STATE_SECRET_MASK) masked.hit = true;
|
|
7299
|
+
return v;
|
|
7300
|
+
};
|
|
7301
|
+
return {
|
|
7302
|
+
...context,
|
|
7303
|
+
crossStackResolver: {
|
|
7304
|
+
resolveImport: async (exportName) => watch(await inner.resolveImport(exportName)),
|
|
7305
|
+
resolveGetStackOutput: async (stack, region, output) => watch(await inner.resolveGetStackOutput(stack, region, output))
|
|
7306
|
+
}
|
|
7307
|
+
};
|
|
7308
|
+
}
|
|
7250
7309
|
const CROSS_STACK_ARGV_REASON = "a cross-stack reference (Fn::ImportValue / Fn::GetStackOutput): it resolves only from a state source with the producer stack deployed";
|
|
7251
7310
|
function argvValue(sub, consumedSensitive) {
|
|
7252
|
-
if (sub.kind !== "literal") return { reason: sub.reason };
|
|
7253
7311
|
if (consumedSensitive) return { reason: "resolved from a SecureString parameter, which would put the secret on the docker run argv; move the value into an Environment variable or a Secrets entry" };
|
|
7312
|
+
if (sub.kind !== "literal") return { reason: sub.reason };
|
|
7254
7313
|
const value = sub.value;
|
|
7255
7314
|
if (typeof value === "number" || typeof value === "boolean") return { value: String(value) };
|
|
7256
7315
|
if (value === STATE_SECRET_MASK) return { reason: "resolved to the secret mask (***), not the deployed value" };
|
|
@@ -7663,16 +7722,17 @@ async function applyCrossStackResolverToTask(task, context, containerState) {
|
|
|
7663
7722
|
remaining.push(u);
|
|
7664
7723
|
continue;
|
|
7665
7724
|
}
|
|
7666
|
-
const
|
|
7667
|
-
if (
|
|
7725
|
+
const refusal = secretAttributeRead(rawElement, argvContext.resources) ?? computedAttributeRead(rawElement);
|
|
7726
|
+
if (refusal !== void 0) {
|
|
7668
7727
|
remaining.push({
|
|
7669
7728
|
...u,
|
|
7670
|
-
reason:
|
|
7729
|
+
reason: refusal
|
|
7671
7730
|
});
|
|
7672
7731
|
continue;
|
|
7673
7732
|
}
|
|
7674
|
-
const {
|
|
7675
|
-
const
|
|
7733
|
+
const masked = { hit: false };
|
|
7734
|
+
const { result: sub, consumedSensitive } = await resolveWithSensitivityAsync(rawElement, withMaskWatch(argvContext, masked));
|
|
7735
|
+
const arg = masked.hit ? { reason: `resolved a cross-stack value recorded as the secret mask (${STATE_SECRET_MASK}), not the deployed value` } : argvValue(sub, consumedSensitive);
|
|
7676
7736
|
if ("value" in arg) {
|
|
7677
7737
|
target[u.index] = arg.value;
|
|
7678
7738
|
continue;
|
|
@@ -8411,32 +8471,6 @@ function isMalformedEnvKey(key) {
|
|
|
8411
8471
|
return !WELL_FORMED_ENV_KEY.test(key);
|
|
8412
8472
|
}
|
|
8413
8473
|
|
|
8414
|
-
// src/utils/shutdown-signal.ts
|
|
8415
|
-
function signalExitCode(signal) {
|
|
8416
|
-
return signal === "SIGINT" ? 130 : 143;
|
|
8417
|
-
}
|
|
8418
|
-
function createShutdownSignalHandler(options) {
|
|
8419
|
-
const exit = options.exit ?? ((code) => process.exit(code));
|
|
8420
|
-
const writeStderr = options.writeStderr ?? ((text) => void process.stderr.write(text));
|
|
8421
|
-
let count = 0;
|
|
8422
|
-
const handler = (signal, exitCode) => {
|
|
8423
|
-
const code = exitCode ?? signalExitCode(signal === "SIGINT" ? "SIGINT" : "SIGTERM");
|
|
8424
|
-
count += 1;
|
|
8425
|
-
if (count === 1) {
|
|
8426
|
-
options.info(options.stoppingMessage(signal));
|
|
8427
|
-
options.cleanup().then(() => exit(code));
|
|
8428
|
-
return;
|
|
8429
|
-
}
|
|
8430
|
-
if (count === 2) {
|
|
8431
|
-
options.warn(`Received ${signal} again; still shutting down — waiting for the cleanup to remove the containers and networks. Send it once more to force-exit (that skips the cleanup).`);
|
|
8432
|
-
return;
|
|
8433
|
-
}
|
|
8434
|
-
writeStderr(`Force-exit on repeated ${signal}; container cleanup skipped. ${options.forceExitHint}\n`);
|
|
8435
|
-
exit(code);
|
|
8436
|
-
};
|
|
8437
|
-
return handler;
|
|
8438
|
-
}
|
|
8439
|
-
|
|
8440
8474
|
// src/assets/asset-source-path.ts
|
|
8441
8475
|
function resolveAssetSourcePath(opts) {
|
|
8442
8476
|
const { manifestDir, value, assetOutdir, field, subject, action, wrapError } = opts;
|
|
@@ -9670,6 +9704,46 @@ function execEnvForSecrets(passthrough) {
|
|
|
9670
9704
|
return { env };
|
|
9671
9705
|
}
|
|
9672
9706
|
|
|
9707
|
+
// src/local/container-start-guard.ts
|
|
9708
|
+
const NAME_CONFLICT = /is already (?:in use|used) by|Conflict\. The container name/;
|
|
9709
|
+
function createContainerStartGuard(options) {
|
|
9710
|
+
const remove = options.remove ?? removeContainer;
|
|
9711
|
+
let stopping = false;
|
|
9712
|
+
const inFlight = /* @__PURE__ */ new Set();
|
|
9713
|
+
const cancelled = () => new CdkLocalError("Shutting down: the container is not used.", options.cancelledCode);
|
|
9714
|
+
const stopAll = async () => {
|
|
9715
|
+
stopping = true;
|
|
9716
|
+
return (await Promise.all([...inFlight])).filter((id) => id !== void 0);
|
|
9717
|
+
};
|
|
9718
|
+
return {
|
|
9719
|
+
async run(start, name) {
|
|
9720
|
+
if (stopping) throw cancelled();
|
|
9721
|
+
const started = start();
|
|
9722
|
+
const outcome = started.then((id) => id, async (err) => {
|
|
9723
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
9724
|
+
if (name !== void 0 && !NAME_CONFLICT.test(message)) try {
|
|
9725
|
+
await remove(name);
|
|
9726
|
+
} catch {}
|
|
9727
|
+
});
|
|
9728
|
+
inFlight.add(outcome);
|
|
9729
|
+
try {
|
|
9730
|
+
const id = await started;
|
|
9731
|
+
if (stopping) throw cancelled();
|
|
9732
|
+
return id;
|
|
9733
|
+
} catch (err) {
|
|
9734
|
+
await outcome;
|
|
9735
|
+
throw err;
|
|
9736
|
+
} finally {
|
|
9737
|
+
inFlight.delete(outcome);
|
|
9738
|
+
}
|
|
9739
|
+
},
|
|
9740
|
+
async stop() {
|
|
9741
|
+
return (await stopAll())[0];
|
|
9742
|
+
},
|
|
9743
|
+
stopAll
|
|
9744
|
+
};
|
|
9745
|
+
}
|
|
9746
|
+
|
|
9673
9747
|
// src/local/debug-timeout.ts
|
|
9674
9748
|
const DEBUG_FUNCTION_TIMEOUT_SEC = 36e3;
|
|
9675
9749
|
function applyDebuggerEnv(dockerEnv, debugPort) {
|
|
@@ -10404,13 +10478,17 @@ async function localInvokeCommand(target, options, extraStateProviders) {
|
|
|
10404
10478
|
let containerId;
|
|
10405
10479
|
let stopLogs;
|
|
10406
10480
|
let sigintHandler;
|
|
10481
|
+
let sigtermHandler;
|
|
10407
10482
|
let profileCredsFile;
|
|
10483
|
+
const startGuard = createContainerStartGuard({ cancelledCode: "LOCAL_INVOKE_CANCELLED" });
|
|
10408
10484
|
const cleanup = singleFlight(async () => {
|
|
10485
|
+
const pendingContainer = startGuard.stop();
|
|
10409
10486
|
if (stopLogs) try {
|
|
10410
10487
|
stopLogs();
|
|
10411
10488
|
} catch (err) {
|
|
10412
10489
|
getLogger().debug(`streamLogs stop failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
10413
10490
|
}
|
|
10491
|
+
containerId ??= await pendingContainer;
|
|
10414
10492
|
if (containerId) try {
|
|
10415
10493
|
await removeContainer(containerId);
|
|
10416
10494
|
} catch (err) {
|
|
@@ -10456,6 +10534,17 @@ async function localInvokeCommand(target, options, extraStateProviders) {
|
|
|
10456
10534
|
}, (err) => {
|
|
10457
10535
|
getLogger().debug(`cleanup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
10458
10536
|
});
|
|
10537
|
+
const onSignal = createShutdownSignalHandler({
|
|
10538
|
+
cleanup,
|
|
10539
|
+
stoppingMessage: (signal) => `Received ${signal}, removing the Lambda container...`,
|
|
10540
|
+
forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
|
|
10541
|
+
info: (m) => logger.info(m),
|
|
10542
|
+
warn: (m) => logger.warn(m)
|
|
10543
|
+
});
|
|
10544
|
+
sigintHandler = () => onSignal("SIGINT");
|
|
10545
|
+
sigtermHandler = () => onSignal("SIGTERM");
|
|
10546
|
+
process.on("SIGINT", sigintHandler);
|
|
10547
|
+
process.on("SIGTERM", sigtermHandler);
|
|
10459
10548
|
try {
|
|
10460
10549
|
await activateWorkloadAwsWiring({
|
|
10461
10550
|
...options,
|
|
@@ -10523,29 +10612,26 @@ async function localInvokeCommand(target, options, extraStateProviders) {
|
|
|
10523
10612
|
readOnly: true
|
|
10524
10613
|
}] : imagePlan.extraMounts;
|
|
10525
10614
|
const hostGatewayExtraHosts = await resolveHostGatewayExtraHosts();
|
|
10526
|
-
|
|
10527
|
-
|
|
10528
|
-
|
|
10615
|
+
const containerName = `${getEmbedConfig().resourceNamePrefix}-invoke-${process.pid}-${Math.random().toString(36).slice(2, 8)}`;
|
|
10616
|
+
const runPlan = imagePlan;
|
|
10617
|
+
containerId = await startGuard.run(() => runDetached({
|
|
10618
|
+
name: containerName,
|
|
10619
|
+
image: runPlan.image,
|
|
10620
|
+
mounts: runPlan.mounts,
|
|
10529
10621
|
extraMounts: extraMountsWithProfile,
|
|
10530
10622
|
env: dockerEnv,
|
|
10531
10623
|
...containerEnv.sensitiveEnvKeys.length > 0 && { sensitiveEnvKeys: new Set(containerEnv.sensitiveEnvKeys) },
|
|
10532
10624
|
...hostGatewayExtraHosts.length > 0 && { extraHosts: hostGatewayExtraHosts },
|
|
10533
|
-
cmd:
|
|
10625
|
+
cmd: runPlan.cmd,
|
|
10534
10626
|
hostPort,
|
|
10535
10627
|
host: containerHost,
|
|
10536
10628
|
...debugPort !== void 0 && { debugPort },
|
|
10537
|
-
...
|
|
10538
|
-
...
|
|
10539
|
-
...
|
|
10540
|
-
...
|
|
10541
|
-
});
|
|
10629
|
+
...runPlan.platform !== void 0 && { platform: runPlan.platform },
|
|
10630
|
+
...runPlan.entryPoint !== void 0 && { entryPoint: runPlan.entryPoint },
|
|
10631
|
+
...runPlan.workingDir !== void 0 && { workingDir: runPlan.workingDir },
|
|
10632
|
+
...runPlan.tmpfs !== void 0 && { tmpfs: runPlan.tmpfs }
|
|
10633
|
+
}), containerName);
|
|
10542
10634
|
stopLogs = streamLogs(containerId);
|
|
10543
|
-
sigintHandler = () => {
|
|
10544
|
-
cleanup().then(() => {
|
|
10545
|
-
process.exit(130);
|
|
10546
|
-
});
|
|
10547
|
-
};
|
|
10548
|
-
process.on("SIGINT", sigintHandler);
|
|
10549
10635
|
await waitForRieReady(containerHost, hostPort, 5e3);
|
|
10550
10636
|
const invokeTimeoutMs = rieInvokeTimeoutMs(lambda.timeoutSec, debugPort !== void 0);
|
|
10551
10637
|
const result = await invokeRie(containerHost, hostPort, event, invokeTimeoutMs);
|
|
@@ -10553,8 +10639,9 @@ async function localInvokeCommand(target, options, extraStateProviders) {
|
|
|
10553
10639
|
process.stdout.write(`${result.raw}\n`);
|
|
10554
10640
|
if (options.responseFile) writeFileSync(options.responseFile, result.raw);
|
|
10555
10641
|
} finally {
|
|
10556
|
-
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
10557
10642
|
await cleanup();
|
|
10643
|
+
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
10644
|
+
if (sigtermHandler) process.off("SIGTERM", sigtermHandler);
|
|
10558
10645
|
}
|
|
10559
10646
|
}
|
|
10560
10647
|
async function resolveImagePlan(lambda, options) {
|
|
@@ -13058,6 +13145,8 @@ function createContainerPool(specs, options) {
|
|
|
13058
13145
|
const entries = /* @__PURE__ */ new Map();
|
|
13059
13146
|
let disposed = false;
|
|
13060
13147
|
const inFlightStarts = /* @__PURE__ */ new Set();
|
|
13148
|
+
const startGuard = createContainerStartGuard({ cancelledCode: "CONTAINER_POOL_DISPOSED" });
|
|
13149
|
+
const startedNotReady = /* @__PURE__ */ new Set();
|
|
13061
13150
|
for (const logicalId of specs.keys()) entries.set(logicalId, emptyEntry(logicalId));
|
|
13062
13151
|
function emptyEntry(logicalId) {
|
|
13063
13152
|
return {
|
|
@@ -13088,7 +13177,7 @@ function createContainerPool(specs, options) {
|
|
|
13088
13177
|
}] : optMount;
|
|
13089
13178
|
const containerCodePath = resolveRuntimeCodeMountPath(spec.lambda.runtime);
|
|
13090
13179
|
const image = resolveRuntimeImage(spec.lambda.runtime);
|
|
13091
|
-
containerId = await runDetached({
|
|
13180
|
+
containerId = await startGuard.run(() => runDetached({
|
|
13092
13181
|
image,
|
|
13093
13182
|
platform: architectureToPlatform(spec.lambda.architecture),
|
|
13094
13183
|
mounts: [{
|
|
@@ -13106,8 +13195,8 @@ function createContainerPool(specs, options) {
|
|
|
13106
13195
|
...spec.debugPort !== void 0 && { debugPort: spec.debugPort },
|
|
13107
13196
|
...spec.tmpfs !== void 0 && { tmpfs: spec.tmpfs },
|
|
13108
13197
|
...spec.extraHosts !== void 0 && { extraHosts: spec.extraHosts }
|
|
13109
|
-
});
|
|
13110
|
-
} else containerId = await runDetached({
|
|
13198
|
+
}), name);
|
|
13199
|
+
} else containerId = await startGuard.run(() => runDetached({
|
|
13111
13200
|
image: spec.image,
|
|
13112
13201
|
mounts: [],
|
|
13113
13202
|
extraMounts: [...spec.rieMount ? [spec.rieMount] : [], ...spec.profileCredentialsFile ? [{
|
|
@@ -13127,14 +13216,17 @@ function createContainerPool(specs, options) {
|
|
|
13127
13216
|
...spec.debugPort !== void 0 && { debugPort: spec.debugPort },
|
|
13128
13217
|
...spec.tmpfs !== void 0 && { tmpfs: spec.tmpfs },
|
|
13129
13218
|
...spec.extraHosts !== void 0 && { extraHosts: spec.extraHosts }
|
|
13130
|
-
});
|
|
13219
|
+
}), name);
|
|
13131
13220
|
const stopLogStream = streamingEnabled ? streamLogs(containerId) : () => void 0;
|
|
13221
|
+
startedNotReady.add(containerId);
|
|
13132
13222
|
try {
|
|
13133
13223
|
await waitForRieReady(spec.containerHost, hostPort, 3e4);
|
|
13134
13224
|
} catch (err) {
|
|
13135
13225
|
stopLogStream();
|
|
13136
13226
|
await removeContainer(containerId).catch(() => void 0);
|
|
13137
13227
|
throw err;
|
|
13228
|
+
} finally {
|
|
13229
|
+
startedNotReady.delete(containerId);
|
|
13138
13230
|
}
|
|
13139
13231
|
return {
|
|
13140
13232
|
logicalId: spec.lambda.logicalId,
|
|
@@ -13191,6 +13283,7 @@ function createContainerPool(specs, options) {
|
|
|
13191
13283
|
}
|
|
13192
13284
|
return {
|
|
13193
13285
|
async acquire(logicalId) {
|
|
13286
|
+
if (disposed) throw new Error(`Container pool disposed; not starting ${displayIdent(logicalId)}.`);
|
|
13194
13287
|
const entry = entries.get(logicalId);
|
|
13195
13288
|
if (!entry) throw new Error(`containerPool.acquire: no spec registered for Lambda ${displayIdent(logicalId)}. This is a bug — every reachable route's Lambda should be registered at server boot.`);
|
|
13196
13289
|
if (entry.warm.length > 0) {
|
|
@@ -13257,6 +13350,7 @@ function createContainerPool(specs, options) {
|
|
|
13257
13350
|
return;
|
|
13258
13351
|
}
|
|
13259
13352
|
disposed = true;
|
|
13353
|
+
const pendingRuns = startGuard.stopAll();
|
|
13260
13354
|
logger.debug("Disposing container pool");
|
|
13261
13355
|
for (const entry of entries.values()) {
|
|
13262
13356
|
if (entry.idleTimer) {
|
|
@@ -13318,10 +13412,14 @@ function createContainerPool(specs, options) {
|
|
|
13318
13412
|
let timedOut = 0;
|
|
13319
13413
|
for (const r of results) if (r.kind === "ok") allHandles.push(r.handle);
|
|
13320
13414
|
else if (r.kind === "timeout") timedOut++;
|
|
13321
|
-
if (timedOut > 0) logger.
|
|
13415
|
+
if (timedOut > 0) logger.debug(`${timedOut} in-flight start(s) still pending after ${drainTimeoutMs}ms; removing them by id once their docker run returns.`);
|
|
13322
13416
|
inFlightStarts.clear();
|
|
13323
13417
|
}
|
|
13324
|
-
await
|
|
13418
|
+
const interruptedIds = [...await pendingRuns, ...startedNotReady];
|
|
13419
|
+
startedNotReady.clear();
|
|
13420
|
+
await Promise.allSettled([...allHandles.map((h) => tearDown(h)), ...interruptedIds.map((id) => removeContainer(id).catch((err) => {
|
|
13421
|
+
logger.warn(`Failed to remove container ${id}: ${err instanceof Error ? err.message : String(err)}. Continuing cleanup.`);
|
|
13422
|
+
}))]);
|
|
13325
13423
|
entries.clear();
|
|
13326
13424
|
}
|
|
13327
13425
|
};
|
|
@@ -16255,6 +16353,21 @@ function formatServerListeningBanner(scheme, host, port, pathSuffix, label) {
|
|
|
16255
16353
|
return `Server listening on ${scheme}://${formatAuthority(host, port)}${pathSuffix} (${label})\n`;
|
|
16256
16354
|
}
|
|
16257
16355
|
async function localStartApiCommand(targets, options, extraStateProviders) {
|
|
16356
|
+
let boot;
|
|
16357
|
+
try {
|
|
16358
|
+
await serveStartApi(targets, options, extraStateProviders, (b) => {
|
|
16359
|
+
boot = b;
|
|
16360
|
+
});
|
|
16361
|
+
} catch (err) {
|
|
16362
|
+
if (boot) {
|
|
16363
|
+
await boot.teardown().catch(() => void 0);
|
|
16364
|
+
if (boot.signalled()) await new Promise(() => void 0);
|
|
16365
|
+
boot.detachSignals();
|
|
16366
|
+
}
|
|
16367
|
+
throw err;
|
|
16368
|
+
}
|
|
16369
|
+
}
|
|
16370
|
+
async function serveStartApi(targets, options, extraStateProviders, registerBoot) {
|
|
16258
16371
|
const logger = getLogger();
|
|
16259
16372
|
if (options.verbose) logger.setLevel("debug");
|
|
16260
16373
|
let apiFilters = [...targets];
|
|
@@ -16291,6 +16404,106 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
|
|
|
16291
16404
|
const inlineTmpDirs = /* @__PURE__ */ new Set();
|
|
16292
16405
|
const layerTmpDirs = /* @__PURE__ */ new Set();
|
|
16293
16406
|
let profileCredsFile;
|
|
16407
|
+
const servers = [];
|
|
16408
|
+
const wsServers = [];
|
|
16409
|
+
const bootPools = [];
|
|
16410
|
+
let watcher;
|
|
16411
|
+
let reloadQueue;
|
|
16412
|
+
let shuttingDown = false;
|
|
16413
|
+
let signalled = false;
|
|
16414
|
+
const runCleanup = singleFlight(async () => {
|
|
16415
|
+
shuttingDown = true;
|
|
16416
|
+
await stopWatchReloads({
|
|
16417
|
+
watcher,
|
|
16418
|
+
queue: reloadQueue,
|
|
16419
|
+
onWatcherCloseError: (err) => logger.warn(`watcher.close() failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
16420
|
+
});
|
|
16421
|
+
await Promise.allSettled(wsServers.map(async (ws) => {
|
|
16422
|
+
try {
|
|
16423
|
+
await ws.attached.close();
|
|
16424
|
+
} catch (err) {
|
|
16425
|
+
logger.warn(`WebSocket close() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
16426
|
+
}
|
|
16427
|
+
}));
|
|
16428
|
+
await Promise.allSettled(servers.map(async ({ server, group }) => {
|
|
16429
|
+
try {
|
|
16430
|
+
await server.close();
|
|
16431
|
+
} catch (err) {
|
|
16432
|
+
logger.warn(`server.close() failed for ${group.displayName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
16433
|
+
}
|
|
16434
|
+
}));
|
|
16435
|
+
await Promise.allSettled(wsServers.map(async (ws) => {
|
|
16436
|
+
try {
|
|
16437
|
+
await ws.server.close();
|
|
16438
|
+
} catch (err) {
|
|
16439
|
+
logger.warn(`WebSocket server.close() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
16440
|
+
}
|
|
16441
|
+
}));
|
|
16442
|
+
await Promise.allSettled(servers.map(async ({ server, group }) => {
|
|
16443
|
+
try {
|
|
16444
|
+
await server.getServerState().pool.dispose();
|
|
16445
|
+
} catch (err) {
|
|
16446
|
+
logger.warn(`pool.dispose() failed for ${group.displayName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
16447
|
+
}
|
|
16448
|
+
}));
|
|
16449
|
+
await Promise.allSettled(wsServers.map(async (ws) => {
|
|
16450
|
+
try {
|
|
16451
|
+
await ws.server.getServerState().pool.dispose();
|
|
16452
|
+
} catch (err) {
|
|
16453
|
+
logger.warn(`WebSocket pool.dispose() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
16454
|
+
}
|
|
16455
|
+
}));
|
|
16456
|
+
await Promise.allSettled(bootPools.map(async (pool) => {
|
|
16457
|
+
try {
|
|
16458
|
+
await pool.dispose();
|
|
16459
|
+
} catch (err) {
|
|
16460
|
+
logger.warn(`pool.dispose() failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
16461
|
+
}
|
|
16462
|
+
}));
|
|
16463
|
+
for (const dir of inlineTmpDirs) try {
|
|
16464
|
+
rmSync(dir, {
|
|
16465
|
+
recursive: true,
|
|
16466
|
+
force: true
|
|
16467
|
+
});
|
|
16468
|
+
} catch (err) {
|
|
16469
|
+
logger.warn(`Failed to remove inline-code tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
16470
|
+
}
|
|
16471
|
+
for (const dir of layerTmpDirs) try {
|
|
16472
|
+
rmSync(dir, {
|
|
16473
|
+
recursive: true,
|
|
16474
|
+
force: true
|
|
16475
|
+
});
|
|
16476
|
+
} catch (err) {
|
|
16477
|
+
logger.warn(`Failed to remove merged-layers tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
16478
|
+
}
|
|
16479
|
+
if (profileCredsFile) try {
|
|
16480
|
+
await profileCredsFile.dispose();
|
|
16481
|
+
} catch (err) {
|
|
16482
|
+
logger.warn(`Failed to remove profile credentials tmpdir ${profileCredsFile.hostPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
16483
|
+
}
|
|
16484
|
+
});
|
|
16485
|
+
const shutdown = createShutdownSignalHandler({
|
|
16486
|
+
cleanup: async () => {
|
|
16487
|
+
signalled = true;
|
|
16488
|
+
await runCleanup();
|
|
16489
|
+
},
|
|
16490
|
+
stoppingMessage: (signal) => `Received ${signal}, shutting down...`,
|
|
16491
|
+
forceExitHint: `Orphan containers may remain — run 'docker ps --filter name=${getEmbedConfig().resourceNamePrefix}-' and 'docker rm -f' to clean up.`,
|
|
16492
|
+
info: (m) => logger.info(m),
|
|
16493
|
+
warn: (m) => logger.warn(m)
|
|
16494
|
+
});
|
|
16495
|
+
const onSigint = () => shutdown("SIGINT");
|
|
16496
|
+
const onSigterm = () => shutdown("SIGTERM");
|
|
16497
|
+
process.on("SIGINT", onSigint);
|
|
16498
|
+
process.on("SIGTERM", onSigterm);
|
|
16499
|
+
registerBoot({
|
|
16500
|
+
teardown: runCleanup,
|
|
16501
|
+
detachSignals: () => {
|
|
16502
|
+
process.off("SIGINT", onSigint);
|
|
16503
|
+
process.off("SIGTERM", onSigterm);
|
|
16504
|
+
},
|
|
16505
|
+
signalled: () => signalled
|
|
16506
|
+
});
|
|
16294
16507
|
const authorizerCache = createAuthorizerCache();
|
|
16295
16508
|
const jwksCache = createJwksCache();
|
|
16296
16509
|
const jwksWarnedAt = /* @__PURE__ */ new Map();
|
|
@@ -16412,6 +16625,7 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
|
|
|
16412
16625
|
};
|
|
16413
16626
|
};
|
|
16414
16627
|
const buildPool = (specs) => {
|
|
16628
|
+
if (shuttingDown) throw new CdkLocalError("Shutting down: no container pool is built.", "LOCAL_START_API_CANCELLED");
|
|
16415
16629
|
const pool = createContainerPool(specs, {
|
|
16416
16630
|
perLambdaConcurrency,
|
|
16417
16631
|
skipPull: options.pull === false
|
|
@@ -16437,11 +16651,11 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
|
|
|
16437
16651
|
const mtlsConfig = resolveMtlsConfig(options);
|
|
16438
16652
|
if (mtlsConfig) logger.info("mTLS enabled: client certificates required (chain check against --mtls-truststore at TLS handshake).");
|
|
16439
16653
|
const initialGroups = groupRoutesByServer(initialMaterial.routes);
|
|
16440
|
-
const servers = [];
|
|
16441
16654
|
let nextPort = basePort;
|
|
16442
16655
|
for (const group of initialGroups) {
|
|
16443
16656
|
const groupSpecs = filterSpecsForGroup(group, initialMaterial.specs);
|
|
16444
16657
|
const groupPool = buildPool(groupSpecs);
|
|
16658
|
+
bootPools.push(groupPool);
|
|
16445
16659
|
const groupState = {
|
|
16446
16660
|
routes: group.routes,
|
|
16447
16661
|
pool: groupPool,
|
|
@@ -16450,6 +16664,7 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
|
|
|
16450
16664
|
if (options.warm) {
|
|
16451
16665
|
logger.info(`Pre-warming ${groupSpecs.size} container(s) for ${group.displayName}...`);
|
|
16452
16666
|
const handles = await Promise.allSettled([...groupSpecs.keys()].map((id) => groupPool.acquire(id)));
|
|
16667
|
+
if (shuttingDown) throw new CdkLocalError("Shutting down: the boot is not continued.", "LOCAL_START_API_CANCELLED");
|
|
16453
16668
|
for (const result of handles) if (result.status === "fulfilled") groupPool.release(result.value);
|
|
16454
16669
|
else logger.warn(`Pre-warm failed for one Lambda in ${group.displayName} (cold start cost will apply on first request): ${result.reason instanceof Error ? result.reason.message : String(result.reason)}`);
|
|
16455
16670
|
}
|
|
@@ -16474,7 +16689,6 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
|
|
|
16474
16689
|
});
|
|
16475
16690
|
if (basePort !== 0) nextPort += 1;
|
|
16476
16691
|
}
|
|
16477
|
-
const wsServers = [];
|
|
16478
16692
|
const initialWsApis = initialMaterial.webSocketApis ?? [];
|
|
16479
16693
|
warnUnsupportedWebSocketApis(initialWsApis, logger);
|
|
16480
16694
|
if (initialWsApis.filter((api) => !api.unsupported).length > 0) {
|
|
@@ -16495,6 +16709,7 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
|
|
|
16495
16709
|
continue;
|
|
16496
16710
|
}
|
|
16497
16711
|
const wsPool = buildPool(wsSpecs);
|
|
16712
|
+
bootPools.push(wsPool);
|
|
16498
16713
|
const wsState = {
|
|
16499
16714
|
routes: [],
|
|
16500
16715
|
pool: wsPool,
|
|
@@ -16562,8 +16777,6 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
|
|
|
16562
16777
|
process.stdout.write(formatServerListeningBanner(scheme, ws.server.host, ws.server.port, ws.apiPath, `${ws.api.apiLogicalId} (WebSocket API)`));
|
|
16563
16778
|
}
|
|
16564
16779
|
process.stdout.write("^C to stop and clean up containers.\n");
|
|
16565
|
-
let watcher;
|
|
16566
|
-
let reloadQueue;
|
|
16567
16780
|
if (options.watch) {
|
|
16568
16781
|
const watchRoot = process.cwd();
|
|
16569
16782
|
const { ignored, shouldTrigger, excludePatterns } = createWatchPredicates({
|
|
@@ -16593,82 +16806,6 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
|
|
|
16593
16806
|
});
|
|
16594
16807
|
logger.info(`Watching ${watchRoot} for source changes (excluding ${excludePatterns.join(", ")}).`);
|
|
16595
16808
|
}
|
|
16596
|
-
const runCleanup = singleFlight(async () => {
|
|
16597
|
-
await stopWatchReloads({
|
|
16598
|
-
watcher,
|
|
16599
|
-
queue: reloadQueue,
|
|
16600
|
-
onWatcherCloseError: (err) => logger.warn(`watcher.close() failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
16601
|
-
});
|
|
16602
|
-
await Promise.allSettled(wsServers.map(async (ws) => {
|
|
16603
|
-
try {
|
|
16604
|
-
await ws.attached.close();
|
|
16605
|
-
} catch (err) {
|
|
16606
|
-
logger.warn(`WebSocket close() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
16607
|
-
}
|
|
16608
|
-
}));
|
|
16609
|
-
await Promise.allSettled(servers.map(async ({ server, group }) => {
|
|
16610
|
-
try {
|
|
16611
|
-
await server.close();
|
|
16612
|
-
} catch (err) {
|
|
16613
|
-
logger.warn(`server.close() failed for ${group.displayName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
16614
|
-
}
|
|
16615
|
-
}));
|
|
16616
|
-
await Promise.allSettled(wsServers.map(async (ws) => {
|
|
16617
|
-
try {
|
|
16618
|
-
await ws.server.close();
|
|
16619
|
-
} catch (err) {
|
|
16620
|
-
logger.warn(`WebSocket server.close() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
16621
|
-
}
|
|
16622
|
-
}));
|
|
16623
|
-
await Promise.allSettled(servers.map(async ({ server, group }) => {
|
|
16624
|
-
try {
|
|
16625
|
-
await server.getServerState().pool.dispose();
|
|
16626
|
-
} catch (err) {
|
|
16627
|
-
logger.warn(`pool.dispose() failed for ${group.displayName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
16628
|
-
}
|
|
16629
|
-
}));
|
|
16630
|
-
await Promise.allSettled(wsServers.map(async (ws) => {
|
|
16631
|
-
try {
|
|
16632
|
-
await ws.server.getServerState().pool.dispose();
|
|
16633
|
-
} catch (err) {
|
|
16634
|
-
logger.warn(`WebSocket pool.dispose() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
16635
|
-
}
|
|
16636
|
-
}));
|
|
16637
|
-
for (const dir of inlineTmpDirs) try {
|
|
16638
|
-
rmSync(dir, {
|
|
16639
|
-
recursive: true,
|
|
16640
|
-
force: true
|
|
16641
|
-
});
|
|
16642
|
-
} catch (err) {
|
|
16643
|
-
logger.warn(`Failed to remove inline-code tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
16644
|
-
}
|
|
16645
|
-
for (const dir of layerTmpDirs) try {
|
|
16646
|
-
rmSync(dir, {
|
|
16647
|
-
recursive: true,
|
|
16648
|
-
force: true
|
|
16649
|
-
});
|
|
16650
|
-
} catch (err) {
|
|
16651
|
-
logger.warn(`Failed to remove merged-layers tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
16652
|
-
}
|
|
16653
|
-
if (profileCredsFile) try {
|
|
16654
|
-
await profileCredsFile.dispose();
|
|
16655
|
-
} catch (err) {
|
|
16656
|
-
logger.warn(`Failed to remove profile credentials tmpdir ${profileCredsFile.hostPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
16657
|
-
}
|
|
16658
|
-
});
|
|
16659
|
-
const shutdown = createShutdownSignalHandler({
|
|
16660
|
-
cleanup: runCleanup,
|
|
16661
|
-
stoppingMessage: (signal) => `Received ${signal}, shutting down...`,
|
|
16662
|
-
forceExitHint: `Orphan containers may remain — run 'docker ps --filter name=${getEmbedConfig().resourceNamePrefix}-' and 'docker rm -f' to clean up.`,
|
|
16663
|
-
info: (m) => logger.info(m),
|
|
16664
|
-
warn: (m) => logger.warn(m)
|
|
16665
|
-
});
|
|
16666
|
-
process.on("SIGINT", () => {
|
|
16667
|
-
shutdown("SIGINT");
|
|
16668
|
-
});
|
|
16669
|
-
process.on("SIGTERM", () => {
|
|
16670
|
-
shutdown("SIGTERM");
|
|
16671
|
-
});
|
|
16672
16809
|
process.on("uncaughtException", (err) => {
|
|
16673
16810
|
logger.error(`Uncaught exception: ${err instanceof Error ? err.stack ?? err.message : String(err)}`);
|
|
16674
16811
|
shutdown("uncaughtException", 1);
|
|
@@ -18381,7 +18518,9 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
|
|
|
18381
18518
|
let profileCredsFile;
|
|
18382
18519
|
let stateProvider;
|
|
18383
18520
|
let stopWatch;
|
|
18521
|
+
const startGuard = createContainerStartGuard({ cancelledCode: "LOCAL_INVOKE_AGENTCORE_CANCELLED" });
|
|
18384
18522
|
const cleanup = singleFlight(async () => {
|
|
18523
|
+
const pendingContainer = startGuard.stop();
|
|
18385
18524
|
if (stopWatch) await stopWatch();
|
|
18386
18525
|
if (stateProvider) try {
|
|
18387
18526
|
stateProvider.dispose();
|
|
@@ -18393,6 +18532,7 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
|
|
|
18393
18532
|
} catch (err) {
|
|
18394
18533
|
getLogger().debug(`streamLogs stop failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
18395
18534
|
}
|
|
18535
|
+
containerId ??= await pendingContainer;
|
|
18396
18536
|
if (containerId) try {
|
|
18397
18537
|
await removeContainer(containerId);
|
|
18398
18538
|
} catch (err) {
|
|
@@ -18406,6 +18546,17 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
|
|
|
18406
18546
|
}, (err) => {
|
|
18407
18547
|
getLogger().debug(`cleanup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
18408
18548
|
});
|
|
18549
|
+
const onSignal = createShutdownSignalHandler({
|
|
18550
|
+
cleanup,
|
|
18551
|
+
stoppingMessage: (signal) => `Received ${signal}, removing the agent container...`,
|
|
18552
|
+
forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
|
|
18553
|
+
info: (m) => logger.info(m),
|
|
18554
|
+
warn: (m) => logger.warn(m)
|
|
18555
|
+
});
|
|
18556
|
+
sigintHandler = () => onSignal("SIGINT");
|
|
18557
|
+
sigtermHandler = () => onSignal("SIGTERM");
|
|
18558
|
+
process.on("SIGINT", sigintHandler);
|
|
18559
|
+
process.on("SIGTERM", sigtermHandler);
|
|
18409
18560
|
try {
|
|
18410
18561
|
await activateWorkloadAwsWiring({
|
|
18411
18562
|
...options,
|
|
@@ -18485,7 +18636,7 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
|
|
|
18485
18636
|
const containerPort = isMcp ? MCP_CONTAINER_PORT : isA2a ? A2A_CONTAINER_PORT : void 0;
|
|
18486
18637
|
const containerPortLabel = isMcp ? `${MCP_CONTAINER_PORT}${MCP_PATH}` : isA2a ? `${A2A_CONTAINER_PORT}${"/"}` : "8080";
|
|
18487
18638
|
logger.info(`Starting agent container (image=${image}, port=${hostPort} -> ${containerPortLabel})...`);
|
|
18488
|
-
containerId = await runDetached({
|
|
18639
|
+
containerId = await startGuard.run(() => runDetached({
|
|
18489
18640
|
image,
|
|
18490
18641
|
mounts: [],
|
|
18491
18642
|
env: dockerEnv,
|
|
@@ -18496,19 +18647,8 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
|
|
|
18496
18647
|
name: containerName,
|
|
18497
18648
|
...containerPort !== void 0 && { containerPort },
|
|
18498
18649
|
...sensitiveEnvKeys.size > 0 && { sensitiveEnvKeys }
|
|
18499
|
-
});
|
|
18650
|
+
}), containerName);
|
|
18500
18651
|
stopLogs = streamLogs(containerId);
|
|
18501
|
-
const onSignal = createShutdownSignalHandler({
|
|
18502
|
-
cleanup,
|
|
18503
|
-
stoppingMessage: (signal) => `Received ${signal}, removing the agent container...`,
|
|
18504
|
-
forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
|
|
18505
|
-
info: (m) => logger.info(m),
|
|
18506
|
-
warn: (m) => logger.warn(m)
|
|
18507
|
-
});
|
|
18508
|
-
sigintHandler = () => onSignal("SIGINT");
|
|
18509
|
-
sigtermHandler = () => onSignal("SIGTERM");
|
|
18510
|
-
process.on("SIGINT", sigintHandler);
|
|
18511
|
-
process.on("SIGTERM", sigtermHandler);
|
|
18512
18652
|
if (isMcp && mcpRequest) {
|
|
18513
18653
|
logger.info(`MCP request: ${mcpRequest.method}`);
|
|
18514
18654
|
const mcp = await mcpInvokeOnce(containerHost, hostPort, mcpRequest, { requestTimeoutMs: options.timeout });
|
|
@@ -23430,8 +23570,32 @@ function createFrontDoorLambdaRunner(lambda, opts) {
|
|
|
23430
23570
|
let stopLogStream;
|
|
23431
23571
|
let starting;
|
|
23432
23572
|
let stopped = false;
|
|
23573
|
+
const startGuard = createContainerStartGuard({ cancelledCode: "FRONT_DOOR_LAMBDA_STOPPED" });
|
|
23574
|
+
function removePlanTmpDirs(p) {
|
|
23575
|
+
if (p?.inlineTmpDir) try {
|
|
23576
|
+
rmSync(p.inlineTmpDir, {
|
|
23577
|
+
recursive: true,
|
|
23578
|
+
force: true
|
|
23579
|
+
});
|
|
23580
|
+
} catch (err) {
|
|
23581
|
+
logger.debug(`Failed to remove inline-code tmpdir ${p.inlineTmpDir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
23582
|
+
}
|
|
23583
|
+
if (p?.assetTmpDir) try {
|
|
23584
|
+
rmSync(p.assetTmpDir, {
|
|
23585
|
+
recursive: true,
|
|
23586
|
+
force: true
|
|
23587
|
+
});
|
|
23588
|
+
} catch (err) {
|
|
23589
|
+
logger.debug(`Failed to remove zip-asset tmpdir ${p.assetTmpDir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
23590
|
+
}
|
|
23591
|
+
}
|
|
23433
23592
|
async function doStart() {
|
|
23434
|
-
|
|
23593
|
+
const resolved = lambda.kind === "zip" ? await resolveZipImagePlan(lambda, opts) : await resolveContainerImagePlan(lambda, opts);
|
|
23594
|
+
if (stopped) {
|
|
23595
|
+
removePlanTmpDirs(resolved);
|
|
23596
|
+
throw new Error("FrontDoorLambdaRunner stopped while starting");
|
|
23597
|
+
}
|
|
23598
|
+
plan = resolved;
|
|
23435
23599
|
const port = await pickFreePort();
|
|
23436
23600
|
hostPort = port;
|
|
23437
23601
|
const name = `${getEmbedConfig().resourceNamePrefix}-alblambda-${lambda.logicalId}-${process.pid}-${Math.floor(Math.random() * 1e6)}`;
|
|
@@ -23444,20 +23608,20 @@ function createFrontDoorLambdaRunner(lambda, opts) {
|
|
|
23444
23608
|
AWS_LAMBDA_LOG_STREAM_NAME: "local",
|
|
23445
23609
|
...forwardAwsEnv()
|
|
23446
23610
|
};
|
|
23447
|
-
logger.info(`Starting Lambda target container for ${lambda.logicalId} (image=${
|
|
23448
|
-
const id = await runDetached({
|
|
23449
|
-
image:
|
|
23450
|
-
mounts:
|
|
23611
|
+
logger.info(`Starting Lambda target container for ${lambda.logicalId} (image=${resolved.image}, port=${port})...`);
|
|
23612
|
+
const id = await startGuard.run(() => runDetached({
|
|
23613
|
+
image: resolved.image,
|
|
23614
|
+
mounts: resolved.mounts,
|
|
23451
23615
|
env,
|
|
23452
23616
|
...opts.sensitiveEnvKeys && opts.sensitiveEnvKeys.size > 0 && { sensitiveEnvKeys: opts.sensitiveEnvKeys },
|
|
23453
|
-
cmd:
|
|
23617
|
+
cmd: resolved.cmd,
|
|
23454
23618
|
hostPort: port,
|
|
23455
23619
|
host: opts.containerHost,
|
|
23456
23620
|
name,
|
|
23457
|
-
...
|
|
23458
|
-
...
|
|
23459
|
-
...
|
|
23460
|
-
});
|
|
23621
|
+
...resolved.platform !== void 0 && { platform: resolved.platform },
|
|
23622
|
+
...resolved.entryPoint !== void 0 && { entryPoint: resolved.entryPoint },
|
|
23623
|
+
...resolved.workingDir !== void 0 && { workingDir: resolved.workingDir }
|
|
23624
|
+
}), name);
|
|
23461
23625
|
containerId = id;
|
|
23462
23626
|
stopLogStream = opts.streamLogs === false ? void 0 : streamLogs(id);
|
|
23463
23627
|
try {
|
|
@@ -23486,11 +23650,14 @@ function createFrontDoorLambdaRunner(lambda, opts) {
|
|
|
23486
23650
|
async stop() {
|
|
23487
23651
|
if (stopped) return;
|
|
23488
23652
|
stopped = true;
|
|
23653
|
+
const pendingContainer = startGuard.stop();
|
|
23489
23654
|
try {
|
|
23490
23655
|
stopLogStream?.();
|
|
23491
23656
|
} catch (err) {
|
|
23492
23657
|
logger.debug(`stopLogStream(${displayIdent(lambda.logicalId)}) failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
23493
23658
|
}
|
|
23659
|
+
const pendingId = await pendingContainer;
|
|
23660
|
+
containerId ??= pendingId;
|
|
23494
23661
|
if (containerId) {
|
|
23495
23662
|
try {
|
|
23496
23663
|
await removeContainer(containerId);
|
|
@@ -23499,22 +23666,7 @@ function createFrontDoorLambdaRunner(lambda, opts) {
|
|
|
23499
23666
|
}
|
|
23500
23667
|
containerId = void 0;
|
|
23501
23668
|
}
|
|
23502
|
-
|
|
23503
|
-
rmSync(plan.inlineTmpDir, {
|
|
23504
|
-
recursive: true,
|
|
23505
|
-
force: true
|
|
23506
|
-
});
|
|
23507
|
-
} catch (err) {
|
|
23508
|
-
logger.debug(`Failed to remove inline-code tmpdir ${plan.inlineTmpDir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
23509
|
-
}
|
|
23510
|
-
if (plan?.assetTmpDir) try {
|
|
23511
|
-
rmSync(plan.assetTmpDir, {
|
|
23512
|
-
recursive: true,
|
|
23513
|
-
force: true
|
|
23514
|
-
});
|
|
23515
|
-
} catch (err) {
|
|
23516
|
-
logger.debug(`Failed to remove zip-asset tmpdir ${plan.assetTmpDir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
23517
|
-
}
|
|
23669
|
+
removePlanTmpDirs(plan);
|
|
23518
23670
|
}
|
|
23519
23671
|
};
|
|
23520
23672
|
}
|
|
@@ -24141,7 +24293,14 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
|
|
|
24141
24293
|
let frontDoorLambdaRunners = [];
|
|
24142
24294
|
let watcher;
|
|
24143
24295
|
let reloadQueue;
|
|
24296
|
+
let sharedNetworkPending;
|
|
24297
|
+
let signalled = false;
|
|
24298
|
+
let stopping = false;
|
|
24299
|
+
const throwIfStopping = () => {
|
|
24300
|
+
if (stopping) throw new LocalStartServiceError("Shutting down: the boot is not continued.");
|
|
24301
|
+
};
|
|
24144
24302
|
const cleanup = singleFlight(async () => {
|
|
24303
|
+
stopping = true;
|
|
24145
24304
|
await stopWatchReloads({
|
|
24146
24305
|
watcher,
|
|
24147
24306
|
queue: reloadQueue,
|
|
@@ -24159,6 +24318,9 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
|
|
|
24159
24318
|
frontDoorServers = [];
|
|
24160
24319
|
await Promise.allSettled(frontDoorLambdaRunners.map((r) => r.stop().catch((err) => getLogger().warn(`front-door Lambda target teardown failed: ${err instanceof Error ? err.message : String(err)}`))));
|
|
24161
24320
|
frontDoorLambdaRunners = [];
|
|
24321
|
+
const pendingNetwork = await sharedNetworkPending;
|
|
24322
|
+
sharedNetwork ??= pendingNetwork;
|
|
24323
|
+
sharedNetworkPending = void 0;
|
|
24162
24324
|
if (profileCredsFile) {
|
|
24163
24325
|
try {
|
|
24164
24326
|
await profileCredsFile.dispose();
|
|
@@ -24177,6 +24339,20 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
|
|
|
24177
24339
|
}
|
|
24178
24340
|
}, (err) => getLogger().warn(`service cleanup failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
24179
24341
|
try {
|
|
24342
|
+
const onSignal = createShutdownSignalHandler({
|
|
24343
|
+
cleanup: async () => {
|
|
24344
|
+
signalled = true;
|
|
24345
|
+
await cleanup();
|
|
24346
|
+
},
|
|
24347
|
+
stoppingMessage: () => "Stopping service(s)...",
|
|
24348
|
+
forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' and 'docker network ls --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
|
|
24349
|
+
info: (m) => logger.info(m),
|
|
24350
|
+
warn: (m) => logger.warn(m)
|
|
24351
|
+
});
|
|
24352
|
+
sigintHandler = () => onSignal("SIGINT");
|
|
24353
|
+
sigtermHandler = () => onSignal("SIGTERM");
|
|
24354
|
+
process.on("SIGINT", sigintHandler);
|
|
24355
|
+
process.on("SIGTERM", sigtermHandler);
|
|
24180
24356
|
await activateWorkloadAwsWiring(options);
|
|
24181
24357
|
warnIfEmulateRoleViaUnused(options.emulateRoleVia, {
|
|
24182
24358
|
roleFlag: "--assume-role",
|
|
@@ -24227,16 +24403,20 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
|
|
|
24227
24403
|
const taskRoleMode = isTaskRoleInEffect(options);
|
|
24228
24404
|
const sidecarCredentials = taskRoleMode ? void 0 : await resolveSharedSidecarCredentials(options);
|
|
24229
24405
|
try {
|
|
24230
|
-
|
|
24406
|
+
const creating = createSharedSvcNetwork({
|
|
24231
24407
|
prefix: options.cluster,
|
|
24232
24408
|
skipPull,
|
|
24233
24409
|
cluster: options.cluster,
|
|
24234
24410
|
...taskRoleMode && { taskRole: true },
|
|
24235
24411
|
...sidecarCredentials !== void 0 && { credentials: sidecarCredentials }
|
|
24236
24412
|
});
|
|
24413
|
+
sharedNetworkPending = creating.catch(() => void 0);
|
|
24414
|
+
sharedNetwork = await creating;
|
|
24415
|
+
sharedNetworkPending = void 0;
|
|
24237
24416
|
} catch (err) {
|
|
24238
24417
|
throw new LocalStartServiceError(`Failed to create shared service network: ${err instanceof Error ? err.message : String(err)}`);
|
|
24239
24418
|
}
|
|
24419
|
+
throwIfStopping();
|
|
24240
24420
|
if (options.profile && sidecarCredentials) profileCredsFile = await writeProfileCredentialsFile(options.profile, sidecarCredentials);
|
|
24241
24421
|
const discovery = {
|
|
24242
24422
|
registry,
|
|
@@ -24244,22 +24424,13 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
|
|
|
24244
24424
|
sharedNetwork
|
|
24245
24425
|
};
|
|
24246
24426
|
if (frontDoor && frontDoor.listeners.length > 0) {
|
|
24247
|
-
const built = await buildFrontDoor(frontDoor, options, logger, extraStateProviders)
|
|
24427
|
+
const built = await buildFrontDoor(frontDoor, options, logger, extraStateProviders, (r) => {
|
|
24428
|
+
frontDoorLambdaRunners.push(r);
|
|
24429
|
+
if (stopping) r.stop().catch(() => void 0);
|
|
24430
|
+
});
|
|
24248
24431
|
frontDoorServers = built.servers;
|
|
24249
24432
|
frontDoorByService = built.frontDoorByService;
|
|
24250
|
-
frontDoorLambdaRunners = built.lambdaRunners;
|
|
24251
24433
|
}
|
|
24252
|
-
const onSignal = createShutdownSignalHandler({
|
|
24253
|
-
cleanup,
|
|
24254
|
-
stoppingMessage: () => "Stopping service(s)...",
|
|
24255
|
-
forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' and 'docker network ls --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
|
|
24256
|
-
info: (m) => logger.info(m),
|
|
24257
|
-
warn: (m) => logger.warn(m)
|
|
24258
|
-
});
|
|
24259
|
-
sigintHandler = () => onSignal("SIGINT");
|
|
24260
|
-
sigtermHandler = () => onSignal("SIGTERM");
|
|
24261
|
-
process.on("SIGINT", sigintHandler);
|
|
24262
|
-
process.on("SIGTERM", sigtermHandler);
|
|
24263
24434
|
const { tags: imageOverrideTags, overrides: imageOverrideMap } = await resolveAndBuildImageOverrides({
|
|
24264
24435
|
perTarget: perTarget.map((pt) => pt.boot.target),
|
|
24265
24436
|
stacks,
|
|
@@ -24267,7 +24438,10 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
|
|
|
24267
24438
|
extraStateProviders,
|
|
24268
24439
|
logger
|
|
24269
24440
|
});
|
|
24270
|
-
for (const pt of perTarget)
|
|
24441
|
+
for (const pt of perTarget) {
|
|
24442
|
+
throwIfStopping();
|
|
24443
|
+
pt.controller = await bootOneTarget(pt.boot, pt.runState, stacks, options, discovery, skipPull, extraStateProviders, profileCredsFile, frontDoorByService.get(pt.boot.target), strategy.suppressLoadBalancerWarning === true, imageOverrideTags.get(pt.boot.target));
|
|
24444
|
+
}
|
|
24271
24445
|
if (perTarget.length > 0) {
|
|
24272
24446
|
const summary = perTarget.map((pt) => `${pt.controller.service.serviceName} (${pt.controller.activeReplicaCount()} replica(s))`).join(", ");
|
|
24273
24447
|
logger.info(`Service(s) running: ${summary}.`);
|
|
@@ -24331,6 +24505,7 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
|
|
|
24331
24505
|
await new Promise(() => {});
|
|
24332
24506
|
} finally {
|
|
24333
24507
|
await cleanup();
|
|
24508
|
+
if (signalled) await new Promise(() => void 0);
|
|
24334
24509
|
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
24335
24510
|
if (sigtermHandler) process.off("SIGTERM", sigtermHandler);
|
|
24336
24511
|
}
|
|
@@ -24692,7 +24867,7 @@ async function resolveAlbLambdaTargetEnv(plan, options, extraStateProviders) {
|
|
|
24692
24867
|
for (const [logicalId, lambda] of lambdas) out.set(logicalId, await resolveLambdaContainerEnv(lambda, envOptions, profileCredentials, extraStateProviders));
|
|
24693
24868
|
return out;
|
|
24694
24869
|
}
|
|
24695
|
-
async function buildFrontDoor(plan, options, logger, extraStateProviders) {
|
|
24870
|
+
async function buildFrontDoor(plan, options, logger, extraStateProviders, onLambdaRunner) {
|
|
24696
24871
|
const containerHost = options.containerHost;
|
|
24697
24872
|
const servers = [];
|
|
24698
24873
|
const poolRegistry = /* @__PURE__ */ new Map();
|
|
@@ -24713,6 +24888,7 @@ async function buildFrontDoor(plan, options, logger, extraStateProviders) {
|
|
|
24713
24888
|
...containerEnv !== void 0 && containerEnv.sensitiveEnvKeys.length > 0 && { sensitiveEnvKeys: new Set(containerEnv.sensitiveEnvKeys) }
|
|
24714
24889
|
});
|
|
24715
24890
|
lambdaRegistry.set(t.lambda.logicalId, runner);
|
|
24891
|
+
onLambdaRunner?.(runner);
|
|
24716
24892
|
}
|
|
24717
24893
|
const boundRunner = runner;
|
|
24718
24894
|
return {
|
|
@@ -29344,6 +29520,7 @@ async function bootLambdaUrlOrigins(distribution, stacks, opts) {
|
|
|
29344
29520
|
containerEnv: containerEnv.env,
|
|
29345
29521
|
...containerEnv.sensitiveEnvKeys.length > 0 && { sensitiveEnvKeys: new Set(containerEnv.sensitiveEnvKeys) }
|
|
29346
29522
|
});
|
|
29523
|
+
opts.runnerSink?.push(runner);
|
|
29347
29524
|
logger.info(`Booting Lambda Function URL origin container for ${functionLogicalId} (the backing Lambda runs locally via RIE)...`);
|
|
29348
29525
|
await runner.start();
|
|
29349
29526
|
} catch (err) {
|
|
@@ -29366,6 +29543,14 @@ async function drainWebFunctionServes(serves) {
|
|
|
29366
29543
|
await Promise.all(batch.map((s) => s.teardown().catch(() => void 0)));
|
|
29367
29544
|
}
|
|
29368
29545
|
}
|
|
29546
|
+
async function drainLambdaRunners(runners) {
|
|
29547
|
+
let done = 0;
|
|
29548
|
+
while (done < runners.length) {
|
|
29549
|
+
const batch = runners.slice(done);
|
|
29550
|
+
done = runners.length;
|
|
29551
|
+
await Promise.all(batch.map((r) => r.stop().catch(() => void 0)));
|
|
29552
|
+
}
|
|
29553
|
+
}
|
|
29369
29554
|
const WEB_FUNCTION_ORIGIN_READY_TIMEOUT_MS = 6e4;
|
|
29370
29555
|
async function bootWebFunctionOrigins(distribution, stacks, opts) {
|
|
29371
29556
|
const logger = getLogger();
|
|
@@ -29434,6 +29619,7 @@ async function bootLambdaEdgeFunctions(distribution, stacks, opts) {
|
|
|
29434
29619
|
containerEnv: containerEnv.env,
|
|
29435
29620
|
...containerEnv.sensitiveEnvKeys.length > 0 && { sensitiveEnvKeys: new Set(containerEnv.sensitiveEnvKeys) }
|
|
29436
29621
|
});
|
|
29622
|
+
opts.runnerSink?.push(runner);
|
|
29437
29623
|
logger.info(`Booting Lambda@Edge container for ${functionLogicalId} (the function runs locally via RIE)...`);
|
|
29438
29624
|
await runner.start();
|
|
29439
29625
|
runners.push(runner);
|
|
@@ -29610,12 +29796,13 @@ async function localStartCloudFrontCommand(target, options, extraStateProviders,
|
|
|
29610
29796
|
await attachKvsModules(initial.distribution, initial.stacks, options, profileCredentials, logger, extraStateProviders);
|
|
29611
29797
|
const bootOpts = buildLambdaBootOptions(options, profileCredentials, extraStateProviders);
|
|
29612
29798
|
const webFunctionServes = [];
|
|
29799
|
+
const bootRunners = [];
|
|
29613
29800
|
let bootAborted = false;
|
|
29614
29801
|
const onBootSignal = (signal) => {
|
|
29615
29802
|
if (bootAborted) return;
|
|
29616
29803
|
bootAborted = true;
|
|
29617
|
-
logger.info(`Received ${signal} during start-up; removing the web function containers...`);
|
|
29618
|
-
drainWebFunctionServes(webFunctionServes).then(() => process.exit(signalExitCode(signal)));
|
|
29804
|
+
logger.info(`Received ${signal} during start-up; removing the web function containers and the Lambda containers started so far...`);
|
|
29805
|
+
Promise.all([drainWebFunctionServes(webFunctionServes), drainLambdaRunners(bootRunners)]).then(() => process.exit(signalExitCode(signal)));
|
|
29619
29806
|
};
|
|
29620
29807
|
const bootSigint = () => onBootSignal("SIGINT");
|
|
29621
29808
|
const bootSigterm = () => onBootSignal("SIGTERM");
|
|
@@ -29623,14 +29810,18 @@ async function localStartCloudFrontCommand(target, options, extraStateProviders,
|
|
|
29623
29810
|
process.off("SIGINT", bootSigint);
|
|
29624
29811
|
process.off("SIGTERM", bootSigterm);
|
|
29625
29812
|
};
|
|
29626
|
-
|
|
29627
|
-
|
|
29628
|
-
process.on("SIGTERM", bootSigterm);
|
|
29629
|
-
}
|
|
29630
|
-
const { invokers: lambdaInvokers, runners: lambdaRunners } = await bootLambdaUrlOrigins(initial.distribution, initial.stacks, bootOpts);
|
|
29631
|
-
const { invokers: edgeInvokers, runners: edgeRunners } = await bootLambdaEdgeFunctions(initial.distribution, initial.stacks, bootOpts);
|
|
29813
|
+
process.on("SIGINT", bootSigint);
|
|
29814
|
+
process.on("SIGTERM", bootSigterm);
|
|
29632
29815
|
let server;
|
|
29633
29816
|
try {
|
|
29817
|
+
const { invokers: lambdaInvokers } = await bootLambdaUrlOrigins(initial.distribution, initial.stacks, {
|
|
29818
|
+
...bootOpts,
|
|
29819
|
+
runnerSink: bootRunners
|
|
29820
|
+
});
|
|
29821
|
+
const { invokers: edgeInvokers } = await bootLambdaEdgeFunctions(initial.distribution, initial.stacks, {
|
|
29822
|
+
...bootOpts,
|
|
29823
|
+
runnerSink: bootRunners
|
|
29824
|
+
});
|
|
29634
29825
|
const webFunctions = await bootWebFunctionOrigins(initial.distribution, initial.stacks, {
|
|
29635
29826
|
...bootOpts,
|
|
29636
29827
|
sink: webFunctionServes
|
|
@@ -29651,7 +29842,7 @@ async function localStartCloudFrontCommand(target, options, extraStateProviders,
|
|
|
29651
29842
|
...webFunctions.targets.size > 0 && { webFunctionOrigins: webFunctions.targets }
|
|
29652
29843
|
});
|
|
29653
29844
|
} catch (err) {
|
|
29654
|
-
await Promise.all([...
|
|
29845
|
+
await Promise.all([...bootRunners.map((r) => r.stop().catch(() => void 0)), ...webFunctionServes.map((s) => s.teardown().catch(() => void 0))]);
|
|
29655
29846
|
if (bootAborted) return await new Promise(() => void 0);
|
|
29656
29847
|
disarmBootSignals();
|
|
29657
29848
|
throw err;
|
|
@@ -29703,7 +29894,7 @@ async function localStartCloudFrontCommand(target, options, extraStateProviders,
|
|
|
29703
29894
|
try {
|
|
29704
29895
|
await server.close();
|
|
29705
29896
|
} catch {}
|
|
29706
|
-
await Promise.all([...
|
|
29897
|
+
await Promise.all([...bootRunners.map((r) => r.stop().catch((err) => {
|
|
29707
29898
|
logger.debug(`Lambda runner stop failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
29708
29899
|
})), ...webFunctionServes.map((s) => s.teardown().catch((err) => {
|
|
29709
29900
|
logger.debug(`Web function server teardown failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -30077,6 +30268,21 @@ function resolveAgentCoreServePlan(protocol) {
|
|
|
30077
30268
|
};
|
|
30078
30269
|
}
|
|
30079
30270
|
async function localStartAgentCoreCommand(target, options, extraStateProviders, hostSynthesizer) {
|
|
30271
|
+
let boot;
|
|
30272
|
+
try {
|
|
30273
|
+
await serveAgentCore(target, options, extraStateProviders, hostSynthesizer, (b) => {
|
|
30274
|
+
boot = b;
|
|
30275
|
+
});
|
|
30276
|
+
} catch (err) {
|
|
30277
|
+
if (boot) {
|
|
30278
|
+
await boot.teardown().catch(() => void 0);
|
|
30279
|
+
if (boot.signalled()) await new Promise(() => void 0);
|
|
30280
|
+
boot.detachSignals();
|
|
30281
|
+
}
|
|
30282
|
+
throw err;
|
|
30283
|
+
}
|
|
30284
|
+
}
|
|
30285
|
+
async function serveAgentCore(target, options, extraStateProviders, hostSynthesizer, registerBoot) {
|
|
30080
30286
|
const logger = getLogger();
|
|
30081
30287
|
if (options.verbose) logger.setLevel("debug");
|
|
30082
30288
|
let containerId;
|
|
@@ -30088,9 +30294,12 @@ async function localStartAgentCoreCommand(target, options, extraStateProviders,
|
|
|
30088
30294
|
let reloadQueue;
|
|
30089
30295
|
let shuttingDown = false;
|
|
30090
30296
|
let tornDown = false;
|
|
30091
|
-
const
|
|
30092
|
-
|
|
30297
|
+
const startGuard = createContainerStartGuard({ cancelledCode: "LOCAL_START_AGENTCORE_CANCELLED" });
|
|
30298
|
+
let teardownPromise;
|
|
30299
|
+
const teardown = () => teardownPromise ??= doTeardown();
|
|
30300
|
+
const doTeardown = async () => {
|
|
30093
30301
|
tornDown = true;
|
|
30302
|
+
const pendingContainer = startGuard.stop();
|
|
30094
30303
|
await stopWatchReloads({
|
|
30095
30304
|
watcher,
|
|
30096
30305
|
queue: reloadQueue,
|
|
@@ -30106,6 +30315,7 @@ async function localStartAgentCoreCommand(target, options, extraStateProviders,
|
|
|
30106
30315
|
} catch (err) {
|
|
30107
30316
|
logger.debug(`streamLogs stop failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
30108
30317
|
}
|
|
30318
|
+
containerId ??= await pendingContainer;
|
|
30109
30319
|
if (containerId) try {
|
|
30110
30320
|
await removeContainer(containerId);
|
|
30111
30321
|
} catch (err) {
|
|
@@ -30118,6 +30328,28 @@ async function localStartAgentCoreCommand(target, options, extraStateProviders,
|
|
|
30118
30328
|
await profileCredsFile.dispose();
|
|
30119
30329
|
} catch {}
|
|
30120
30330
|
};
|
|
30331
|
+
const shutdown = createShutdownSignalHandler({
|
|
30332
|
+
cleanup: async () => {
|
|
30333
|
+
shuttingDown = true;
|
|
30334
|
+
await teardown().catch(() => void 0);
|
|
30335
|
+
},
|
|
30336
|
+
stoppingMessage: (signal) => `Received ${signal}, shutting down...`,
|
|
30337
|
+
forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
|
|
30338
|
+
info: (m) => logger.info(m),
|
|
30339
|
+
warn: (m) => logger.warn(m)
|
|
30340
|
+
});
|
|
30341
|
+
const onSigint = () => shutdown("SIGINT");
|
|
30342
|
+
const onSigterm = () => shutdown("SIGTERM");
|
|
30343
|
+
process.on("SIGINT", onSigint);
|
|
30344
|
+
process.on("SIGTERM", onSigterm);
|
|
30345
|
+
registerBoot({
|
|
30346
|
+
teardown,
|
|
30347
|
+
detachSignals: () => {
|
|
30348
|
+
process.off("SIGINT", onSigint);
|
|
30349
|
+
process.off("SIGTERM", onSigterm);
|
|
30350
|
+
},
|
|
30351
|
+
signalled: () => shuttingDown
|
|
30352
|
+
});
|
|
30121
30353
|
await activateWorkloadAwsWiring(options);
|
|
30122
30354
|
warnIfEmulateRoleViaUnused(options.emulateRoleVia, {
|
|
30123
30355
|
roleFlag: "--assume-role",
|
|
@@ -30171,31 +30403,20 @@ async function localStartAgentCoreCommand(target, options, extraStateProviders,
|
|
|
30171
30403
|
const containerHost = options.containerHost;
|
|
30172
30404
|
const containerName = `${getEmbedConfig().resourceNamePrefix}-agentcore-${process.pid}-${Math.random().toString(36).slice(2, 8)}`;
|
|
30173
30405
|
logger.info(`Starting agent container (image=${image}, port=${containerHostPort} -> ${plan.containerPortLabel})...`);
|
|
30174
|
-
|
|
30406
|
+
const bootPort = containerHostPort;
|
|
30407
|
+
containerId = await startGuard.run(() => runDetached({
|
|
30175
30408
|
image,
|
|
30176
30409
|
mounts: [],
|
|
30177
30410
|
env: dockerEnv,
|
|
30178
30411
|
cmd: [],
|
|
30179
|
-
hostPort:
|
|
30412
|
+
hostPort: bootPort,
|
|
30180
30413
|
host: containerHost,
|
|
30181
30414
|
platform: options.platform,
|
|
30182
30415
|
name: containerName,
|
|
30183
30416
|
...plan.containerPort !== void 0 && { containerPort: plan.containerPort },
|
|
30184
30417
|
...sensitiveEnvKeys.size > 0 && { sensitiveEnvKeys }
|
|
30185
|
-
});
|
|
30418
|
+
}), containerName);
|
|
30186
30419
|
stopLogs = streamLogs(containerId);
|
|
30187
|
-
const shutdown = createShutdownSignalHandler({
|
|
30188
|
-
cleanup: async () => {
|
|
30189
|
-
shuttingDown = true;
|
|
30190
|
-
await teardown().catch(() => void 0);
|
|
30191
|
-
},
|
|
30192
|
-
stoppingMessage: (signal) => `Received ${signal}, shutting down...`,
|
|
30193
|
-
forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
|
|
30194
|
-
info: (m) => logger.info(m),
|
|
30195
|
-
warn: (m) => logger.warn(m)
|
|
30196
|
-
});
|
|
30197
|
-
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
30198
|
-
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
30199
30420
|
try {
|
|
30200
30421
|
if (plan.readyPath === void 0) await waitForAgentCorePing(containerHost, containerHostPort, options.timeout);
|
|
30201
30422
|
else await waitForAgentCoreHttpReady(containerHost, containerHostPort, plan.readyPath, options.timeout);
|
|
@@ -37022,4 +37243,4 @@ function addStudioSpecificOptions(cmd) {
|
|
|
37022
37243
|
}
|
|
37023
37244
|
|
|
37024
37245
|
export { postHook as $, AGENTCORE_A2A_PROTOCOL as $a, probeHostGatewaySupport as $i, addImageOverrideOptions as $n, loopbackForwarderPlan as $o, resolveApiTargetSubset as $r, classifyS3Error as $t, microvmFidelityWarnings as A, createLocalStateProvider as Aa, translateLambdaResponse as Ai, stripCloudFrontImport as An, readEnvCallerCredentials as Ao, A2A_CONTAINER_PORT as Ar, readContainerLogTail as At, MICROVM_WS_BASE_PROTOCOL as B, resolveWatchConfig as Ba, ConnectionRegistry as Bi, createLocalStartAlbCommand as Bn, HOST_DEFAULT_CREDENTIALS_MISS_TTL_MS as Bo, AGENTCORE_SESSION_ID_HEADER as Br, parseWebFunctionBuildConfig as Bt, addListSpecificOptions as C, substituteAgainstState as Ca, attachAuthorizers as Ci, WEB_FUNCTION_REVISION_TYPE as Cn, resolveDynamicReferencesInEnv as Co, setShadowReadyTimeoutMs as Cr, parseKvsFileOverrides as Ct, buildMicrovmLambdaView as D, materializeLayerFromArn as Da, isFunctionUrlOacFronted as Di, compileCloudFrontFunction as Dn, SECOND_ASSUME_MESSAGE as Do, createLocalInvokeAgentCoreCommand as Dr, WEB_FUNCTION_CONTAINER_PORT as Dt, addStartMicrovmSpecificOptions as E, substituteEnvVarsFromStateAsync as Ea, buildCorsConfigFromCloudFrontChain as Ei, resolveWebFunctionTarget as En, awsEndpointOptions as Eo, addInvokeAgentCoreSpecificOptions as Er, RecentOutput as Et, microvmImageTag as F, resolveCfnRegion as Fa, pickResponseTemplate as Fi, findFileAssetForObjectKey as Fn, AUTH_OFF_PLACEHOLDER_CREDENTIALS as Fo, MCP_PROTOCOL_VERSION as Fr, buildNodeEntryFileStart as Ft, startMicrovmFrontDoor as G, discoverWebSocketApis as Ga, buildDisconnectEvent as Gi, addStartServiceSpecificOptions as Gn, collectHostEndpointOverrides as Go, SUPPORTED_CODE_RUNTIMES as Gr, readWebFunctionServiceConfig as Gt, PROXY_PORT_HEADER as H, countTargets as Ha, handleConnectionsRequest as Hi, resolveAlbTarget as Hn, applyWorkloadAwsWiringToEnv as Ho, waitForAgentCoreHttpReady as Hr, WEB_FUNCTION_HTTP_ENDPOINT_ENV as Ht, planMicrovmPorts as I, resolveCfnStackName as Ia, selectIntegrationResponse as Ii, isBucketDeploymentResource as In, CA_TRUST_ENV_KEYS as Io, mcpInvokeOnce as Ir, defaultWebFunctionPlatform as It, MICROVM_HOOK_PATH_PREFIX as J, parseSelectionExpressionPath as Ja, createFileWatcher as Ji, addRunTaskSpecificOptions as Jn, getActiveWorkloadAwsWiring as Jo, renderCodeDockerfile as Jr, idFromArn as Jt, stripMicrovmProxyHeaders as K, discoverWebSocketApisOrThrow as Ka, buildMessageEvent as Ki, createLocalStartServiceCommand as Kn, displayEndpointValue as Ko, buildAgentCoreCodeImage as Kr, webFunctionAssumeRole as Kt, readExposedPorts as L, CfnLocalStateProvider as La, tryParseStatus as Li, resolveBucketDeploymentObjectKey as Ln, DEFAULT_AWS_EMULATOR_URL as Lo, parseSseForJsonRpc as Lr, resolveWebFunctionRuntime as Lt, DEFAULT_TERMINATE_HOOK_TIMEOUT_MS as M, isCfnFlagPresent as Ma, buildHttpApiV2Event as Mi, createLocalFileKvsDataSource as Mn, resetWorkloadIdentity as Mo, a2aInvokeOnce as Mr, waitForWebFunctionReady as Mt, LocalMicrovm as N, rejectExplicitCfnStackWithMultipleStacks as Na, buildRestV1Event as Ni, createUnboundCloudFrontModule as Nn, workloadClientConfig as No, MCP_CONTAINER_PORT as Nr, watchContainerExit as Nt, createLocalStartMicrovmCommand as O, LocalStateSourceError as Oa, matchPreflight as Oi, runViewerRequest as On, assumedRoleRecorded as Oo, bridgeAgentCoreWs as Or, containerFailure as Ot, buildMicrovmImage as P, resolveCfnFallbackRegion as Pa, evaluateResponseParameters as Pi, bucketDeploymentSourceObjectKeys as Pn, workloadStsClientConfig as Po, MCP_PATH as Pr, WEB_FUNCTION_RUNTIMES as Pt, pollBuildHook as Q, resolveLambdaArnIntrinsic as Qa, HOST_GATEWAY_MIN_VERSION as Qi, addEcsAssumeRoleOptions as Qn, logMixedModeForWorkload as Qo, createWatchPredicates as Qr, resolveDeployedOriginBucket as Qt, setContainerPaused as R, collectSsmParameterRefs as Ra, VtlEvaluationError as Ri, addAlbSpecificOptions as Rn, EMULATOR_SCRUBBED_ENV_KEYS as Ro, AGENTCORE_SIGV4_SERVICE as Rr, supportedWebFunctionRuntimes as Rt, StudioEventBus as S, containsCrossStackIntrinsic as Sa, invokeTokenAuthorizer as Si, WEB_FUNCTION_ENDPOINT_TYPE as Sn, parseDynamicReference as So, SOFT_RELOAD_COMPLETION_LOG_SUFFIX as Sr, normalizeKvsFileKeys as St, formatTargetListing as T, substituteEnvVarsFromState as Ta, buildCorsConfigByApiId as Ti, WebFunctionResolutionError as Tn, addAwsEndpointOptions as To, attachContainerLogStreamer as Tr, resolveCloudFrontTarget as Tt, rewriteUpgradeResponseHead as U, listTargets as Ua, parseConnectionsPath as Ui, isApplicationLoadBalancer as Un, awsEmulatorEnvName as Uo, waitForAgentCorePing as Ur, buildWebFunctionLambdaView as Ut, MicrovmStateError as V, resolveSingleTarget as Va, buildMgmtEndpointEnvUrl as Vi, parseLbPortOverrides as Vn, activateWorkloadAwsWiring as Vo, invokeAgentCore as Vr, resolveWebFunctionArtifact as Vt, selectTargetPort as W, availableWebSocketApiIdentifiers as Wa, buildConnectEvent as Wi, resolveAlbFrontDoor as Wn, awsEmulatorSqsHostBlocks as Wo, downloadAndExtractS3Bundle as Wr, finalizeWebFunctionEnv as Wt, callRuntimeHook as X, discoverRoutes as Xa, createLocalInvokeCommand as Xi, MAX_TASKS_SUBNET_RANGE_CAP as Xn, getContainerJavaTruststorePath as Xo, addStartApiSpecificOptions as Xr, createDeployedKvsDataSource as Xt, MicrovmHookError as Y, webSocketApiMatchesIdentifier as Ya, addInvokeSpecificOptions as Yi, createLocalRunTaskCommand as Yn, getContainerCaBundlePath as Yo, toCmdArgv as Yr, resolveKvsModulesForDistribution as Yt, generateMicrovmId as Z, pickRefLogicalId as Za, HOST_DOCKER_INTERNAL_GATEWAY as Zi, addCommonEcsServiceOptions as Zn, javaTruststoreToolOptions as Zo, createLocalStartApiCommand as Zr, resolveDeployedKvsArnByName as Zt, filterStudioTargetGroups as _, resolveRuntimeFileExtension as _a, verifyJwtViaDiscovery as _i, pickKvsLogicalIdFromArn as _n, containsDynamicReference as _o, isLocalCdkAssetImage as _r, sqsEmulatorOriginOf as _s, attachAgentCoreWsBridge as _t, createLocalStudioCommand as a, buildLoopbackForwarderDockerArgs as aa, filterRoutesByApiIdentifiers as ai, serveLambdaUrlOrigin as an, pickAgentCoreCandidateStack as ao, resolveSharedSidecarCredentials as ar, resolveAwsEmulatorOption as as, disposeMicrovmCodeArtifact as at, renderStudioHtml as b, assertEcsTaskCommandsResolved as ba, evaluateCachedLambdaPolicy as bi, pickWebFunctionEndpointLogicalIdFromOrigin as bn, keysNotFromTemplate as bo, CloudMapRegistry as br, buildStsClientConfig as bs, addStartCloudFrontSpecificOptions as bt, startStudioProxy as c, ensureForwarderImage as ca, startApiServer as ci, buildEdgeRequestEvent as cn, formatStateRemedy as co, buildImageOverrideTag as cr, setActiveWorkloadAwsWiring as cs, resolveMicrovmImageTarget as ct, createStudioDispatcher as d, buildContainerImage as da, defaultCredentialsLoader as di, httpHeadersToEdge as dn, LocalInvokeBuildError as do, mergeForService as dr, MIXED_MODE_RESIGN_BODY_CAP_BYTES as ds, createLocalStartWebFunctionCommand as dt, resolveHostGatewayExtraHosts as ea, createAuthorizerCache as ei, createS3OriginReader as en, AGENTCORE_AGUI_PROTOCOL as eo, buildEcsImageResolutionContext$1 as er, mergeJavaToolOptions as es, runHookBody as et, filterStudioCustomResources as f, dockerRegistryEnv as fa, buildCognitoJwksUrl as fi, CLOUDFRONT_DISTRIBUTION_TYPE as fn, ambientDefaultRegion as fo, parseImageOverrideFlags as fr, REAL_SQS_QUEUE_URL as fs, addStartAgentCoreSpecificOptions as ft, annotatePinnedEcsTargets as g, resolveRuntimeCodeMountPath as ga, verifyJwtAuthorizer as gi, pickFunctionUrlLogicalIdFromOrigin as gn, DynamicReferenceResolver as go, imageOverrideKeyAliases as gr, rewriteSqsQueueUrlsInEnv as gs, startAgentCoreHttpServer as gt, annotateEcsTaskPinnedTargets as h, stripEcrCredentials as ha, verifyCognitoJwt as hi, isCloudFrontDistribution as hn, DynamicReferenceResolutionError as ho, describePinnedImageUri as hr, repointLocalSqsQueueUrlsInEnv as hs, selectServeInboundAuth as ht, coerceStopRequest as i, awaitLoopbackForwarderStatus as ia, filterRoutesByApiIdentifier as ii, serveFromStaticOrigin as in, AgentCoreResolutionError as io, resolveEcsAssumeRoleOption as ir, readProfileEndpointSettings as is, MicrovmResolutionError as it, readRunHookPayload as j, groupWorkloadsRoutedApart as ja, applyAuthorizerOverlay as ji, createCloudFrontModule as jn, recordAssumedRole as jo, A2A_PATH as jr, startWebFunctionContainer as jt, finalizeMicrovmEnv as k, UNNAMED_WORKLOAD as ka, matchRoute as ki, runViewerResponse as kn, deployAccountStsClientConfig as ko, invokeAgentCoreWs as kr, planWebFunctionContainer as kt, relayServeRequest as l, startLoopbackForwarder as la, resolveSelectionExpression as li, buildEdgeResponseEvent as ln, substituteImagePlaceholders as lo, canonicalizeImageOverrideKeys as lr, takeAwsEmulatorStateSourceHint as ls, s3KeyOfUri as lt, annotateAlbPinnedBackingServices as m, noImplicitEcrPullArgs as ma, createJwksCache as mi, extractKvsAssociations as mn, setAmbientDefaultRegion as mo, runImageOverrideBuilds as mr, realSqsHostnames as ms, buildAgentCoreServeAuthCheck as mt, coerceRunRequest as n, withWorkloadAwsWiring as na, buildStageMap as ni, startCloudFrontServer as nn, AGENTCORE_MCP_PROTOCOL as no, parseMaxTasks as nr, probeAwsEmulatorHealth as ns, MICROVM_DEFAULT_INGRESS_PORT as nt, resolveServeBaseUrl as o, buildNamespaceOwnerForwarderDockerArgs as oa, groupRoutesByServer as oi, applyEdgeRequestResult as on, resolveAgentCoreTarget as oo, runEcsServiceEmulator as or, resolveHostDefaultCredentials as os, readMicrovmImageConfig as ot, isCustomResourceLambdaTarget as p, isEcrRegistryConfigKey as pa, buildJwksUrlFromIssuer as pi, describeS3OriginDomain as pn, namedEnvAwsRegion as po, resolveImageOverrides as pr, isRealAwsHost as ps, createLocalStartAgentCoreCommand as pt, MAX_RUN_HOOK_PAYLOAD_BYTES as q, filterWebSocketApisByIdentifiers as qa, classifySourceChange as qi, serviceStrategy as qn, effectiveLoopbackPorts as qo, computeCodeImageTag as qr, webFunctionFidelityWarnings as qt, coerceServeRequest as r, LOOPBACK_FORWARDER_IMAGE as ra, availableApiIdentifiers as ri, resolveErrorResponseCandidates as rn, AGENTCORE_RUNTIME_TYPE as ro, parseRestartPolicy as rr, readEmulatorRunFiles as rs, MICROVM_IMAGE_TYPE as rt, createStudioServeManager as s, describeForwarderFailure as sa, readMtlsMaterialsFromDisk as si, applyEdgeResponseResult as sn, derivePseudoParametersFromRegion as so, ImageOverrideError as sr, resolveWorkloadAwsWiring as ss, resolveMicrovmCodeArtifact as st, addStudioSpecificOptions as t, attachLoopbackForwarder as ta, attachStageContext as ti, matchBehavior as tn, AGENTCORE_HTTP_PROTOCOL as to, ecsClusterOption as tr, parseAwsEndpoint as ts, waitForAppAnswer as tt, reinvoke as u, architectureToPlatform as ua, resolveServiceIntegrationParameters as ui, edgeHeadersToHttp as un, tryResolveImageFnJoin as uo, enforceImageOverrideOrphans as ur, writeCaBundleFile as us, addStartWebFunctionSpecificOptions as ut, startStudioServer as v, resolveRuntimeImage as va, buildMethodArn as vi, pickLambdaEdgeFunctionLogicalId as vn, deployedFillMayBeSecret as vo, listPinnedTargets as vr, buildJavaTrustStore as vs, startAgentCoreWsBridge as vt, createLocalListCommand as w, substituteAgainstStateAsync as wa, applyCorsResponseHeaders as wi, WEB_FUNCTION_TYPE as wn, withoutKeys as wo, getContainerNetworkIp as wr, parseOriginOverrides as wt, createStudioStore as x, assertEcsTaskImagesResolvable as xa, invokeRequestAuthorizer as xi, resolveCloudFrontDistribution as xn, keysOverriddenBy as xo, DEFAULT_SHADOW_READY_TIMEOUT_MS as xr, resolveProfileCredentials as xs, createLocalStartCloudFrontCommand as xt, toStudioTargetGroups as y, EcsTaskResolutionError as ya, computeRequestIdentityHash as yi, pickTargetFunctionLogicalId as yn, firstUsableRegion as yo, buildCloudMapIndex as yr, createMixedModeTlsMaterials as ys, LocalStartCloudFrontError as yt, MICROVM_CONTROL_PATH as z, resolveSsmParameters as za, bufferToBody as zi, albStrategy as zn, HOST_CA_TRUST_ENV_KEYS as zo, signAgentCoreInvocation as zr, disposeWebFunctionArtifact as zt };
|
|
37025
|
-
//# sourceMappingURL=local-studio-
|
|
37246
|
+
//# sourceMappingURL=local-studio-B0Wlk_VO.js.map
|