cdk-local 0.163.0 → 0.163.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 +56 -56
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -1
- package/dist/local-studio-BsnTY1vH.d.ts.map +1 -1
- package/dist/{local-studio-aUkwJL4M.js → local-studio-LTgy7a7a.js} +476 -310
- package/dist/local-studio-LTgy7a7a.js.map +1 -0
- package/package.json +1 -1
- package/dist/local-studio-aUkwJL4M.js.map +0 -1
|
@@ -10504,6 +10504,97 @@ function createFileWatcher(options) {
|
|
|
10504
10504
|
} };
|
|
10505
10505
|
}
|
|
10506
10506
|
|
|
10507
|
+
//#endregion
|
|
10508
|
+
//#region src/local/reload-queue.ts
|
|
10509
|
+
async function stopWatchReloads(args) {
|
|
10510
|
+
const closing = args.watcher ? args.watcher.close().catch((err) => args.onWatcherCloseError?.(err)) : Promise.resolve();
|
|
10511
|
+
const draining = args.queue ? args.queue.stop() : Promise.resolve();
|
|
10512
|
+
await closing;
|
|
10513
|
+
await draining;
|
|
10514
|
+
}
|
|
10515
|
+
function createReloadQueue(options) {
|
|
10516
|
+
const abort = new AbortController();
|
|
10517
|
+
let stopped = false;
|
|
10518
|
+
let current;
|
|
10519
|
+
let pending;
|
|
10520
|
+
let started = 0;
|
|
10521
|
+
let finished = 0;
|
|
10522
|
+
const runBatch = async (batch) => {
|
|
10523
|
+
try {
|
|
10524
|
+
await (async () => options.run(batch, abort.signal))();
|
|
10525
|
+
} catch (err) {
|
|
10526
|
+
try {
|
|
10527
|
+
options.onError?.(err);
|
|
10528
|
+
} catch {}
|
|
10529
|
+
}
|
|
10530
|
+
};
|
|
10531
|
+
const start = (paths) => {
|
|
10532
|
+
(async () => {
|
|
10533
|
+
let next = paths;
|
|
10534
|
+
while (next) {
|
|
10535
|
+
started += 1;
|
|
10536
|
+
current = runBatch(next);
|
|
10537
|
+
await current;
|
|
10538
|
+
finished += 1;
|
|
10539
|
+
next = !stopped && pending ? [...pending] : void 0;
|
|
10540
|
+
pending = void 0;
|
|
10541
|
+
}
|
|
10542
|
+
current = void 0;
|
|
10543
|
+
})();
|
|
10544
|
+
};
|
|
10545
|
+
const idle = async () => {
|
|
10546
|
+
const target = started + (pending ? 1 : 0);
|
|
10547
|
+
while (current && finished < target) await current;
|
|
10548
|
+
};
|
|
10549
|
+
return {
|
|
10550
|
+
schedule(changedPaths) {
|
|
10551
|
+
if (stopped) return;
|
|
10552
|
+
if (!current) {
|
|
10553
|
+
start(changedPaths);
|
|
10554
|
+
return;
|
|
10555
|
+
}
|
|
10556
|
+
const wasPending = pending !== void 0;
|
|
10557
|
+
pending ??= /* @__PURE__ */ new Set();
|
|
10558
|
+
for (const p of changedPaths) pending.add(p);
|
|
10559
|
+
if (wasPending) options.onCoalesced?.(pending.size);
|
|
10560
|
+
},
|
|
10561
|
+
async stop() {
|
|
10562
|
+
if (!stopped) {
|
|
10563
|
+
stopped = true;
|
|
10564
|
+
pending = void 0;
|
|
10565
|
+
abort.abort();
|
|
10566
|
+
}
|
|
10567
|
+
await idle();
|
|
10568
|
+
},
|
|
10569
|
+
idle,
|
|
10570
|
+
get stopped() {
|
|
10571
|
+
return stopped;
|
|
10572
|
+
}
|
|
10573
|
+
};
|
|
10574
|
+
}
|
|
10575
|
+
|
|
10576
|
+
//#endregion
|
|
10577
|
+
//#region src/utils/shutdown-signal.ts
|
|
10578
|
+
function createShutdownSignalHandler(options) {
|
|
10579
|
+
const exit = options.exit ?? ((code) => process.exit(code));
|
|
10580
|
+
const writeStderr = options.writeStderr ?? ((text) => void process.stderr.write(text));
|
|
10581
|
+
let count = 0;
|
|
10582
|
+
return (signal, exitCode) => {
|
|
10583
|
+
count += 1;
|
|
10584
|
+
if (count === 1) {
|
|
10585
|
+
options.info(options.stoppingMessage(signal));
|
|
10586
|
+
options.cleanup().then(() => exit(exitCode));
|
|
10587
|
+
return;
|
|
10588
|
+
}
|
|
10589
|
+
if (count === 2) {
|
|
10590
|
+
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).`);
|
|
10591
|
+
return;
|
|
10592
|
+
}
|
|
10593
|
+
writeStderr(`Force-exit on repeated ${signal}; container cleanup skipped. ${options.forceExitHint}\n`);
|
|
10594
|
+
exit(130);
|
|
10595
|
+
};
|
|
10596
|
+
}
|
|
10597
|
+
|
|
10507
10598
|
//#endregion
|
|
10508
10599
|
//#region src/local/authorizer-cache.ts
|
|
10509
10600
|
function createAuthorizerCache(opts = {}) {
|
|
@@ -10897,7 +10988,7 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
|
|
|
10897
10988
|
}
|
|
10898
10989
|
process.stdout.write("^C to stop and clean up containers.\n");
|
|
10899
10990
|
let watcher;
|
|
10900
|
-
let
|
|
10991
|
+
let reloadQueue;
|
|
10901
10992
|
if (options.watch) {
|
|
10902
10993
|
const watchRoot = process.cwd();
|
|
10903
10994
|
const { ignored, shouldTrigger, excludePatterns } = createWatchPredicates({
|
|
@@ -10905,105 +10996,97 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
|
|
|
10905
10996
|
output: options.output,
|
|
10906
10997
|
watchConfig: resolveWatchConfig()
|
|
10907
10998
|
});
|
|
10999
|
+
const queue = createReloadQueue({
|
|
11000
|
+
run: (_changedPaths, signal) => reloadAllServers({
|
|
11001
|
+
synthesizeAndBuild,
|
|
11002
|
+
servers,
|
|
11003
|
+
buildPool,
|
|
11004
|
+
logger,
|
|
11005
|
+
signal
|
|
11006
|
+
}),
|
|
11007
|
+
onError: (err) => logger.warn(`Reload failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
11008
|
+
});
|
|
11009
|
+
reloadQueue = queue;
|
|
10908
11010
|
watcher = createFileWatcher({
|
|
10909
11011
|
paths: [watchRoot],
|
|
10910
11012
|
ignored,
|
|
10911
11013
|
shouldTrigger,
|
|
10912
|
-
onChange: () => {
|
|
11014
|
+
onChange: (changedPaths) => {
|
|
10913
11015
|
logger.info("Detected source change; reloading...");
|
|
10914
|
-
|
|
10915
|
-
synthesizeAndBuild,
|
|
10916
|
-
servers,
|
|
10917
|
-
buildPool,
|
|
10918
|
-
logger
|
|
10919
|
-
})).catch(() => void 0);
|
|
11016
|
+
queue.schedule(changedPaths);
|
|
10920
11017
|
}
|
|
10921
11018
|
});
|
|
10922
11019
|
logger.info(`Watching ${watchRoot} for source changes (excluding ${excludePatterns.join(", ")}).`);
|
|
10923
11020
|
}
|
|
10924
|
-
|
|
10925
|
-
|
|
10926
|
-
|
|
10927
|
-
|
|
10928
|
-
|
|
10929
|
-
|
|
10930
|
-
|
|
10931
|
-
await
|
|
10932
|
-
|
|
10933
|
-
|
|
10934
|
-
|
|
10935
|
-
|
|
10936
|
-
|
|
10937
|
-
|
|
10938
|
-
|
|
10939
|
-
|
|
10940
|
-
|
|
10941
|
-
|
|
10942
|
-
|
|
10943
|
-
|
|
10944
|
-
|
|
10945
|
-
|
|
10946
|
-
|
|
10947
|
-
|
|
10948
|
-
|
|
10949
|
-
|
|
10950
|
-
|
|
10951
|
-
|
|
11021
|
+
const shutdown = createShutdownSignalHandler({
|
|
11022
|
+
cleanup: singleFlight(async () => {
|
|
11023
|
+
await stopWatchReloads({
|
|
11024
|
+
watcher,
|
|
11025
|
+
queue: reloadQueue,
|
|
11026
|
+
onWatcherCloseError: (err) => logger.warn(`watcher.close() failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
11027
|
+
});
|
|
11028
|
+
await Promise.allSettled(wsServers.map(async (ws) => {
|
|
11029
|
+
try {
|
|
11030
|
+
await ws.attached.close();
|
|
11031
|
+
} catch (err) {
|
|
11032
|
+
logger.warn(`WebSocket close() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
11033
|
+
}
|
|
11034
|
+
}));
|
|
11035
|
+
await Promise.allSettled(servers.map(async ({ server, group }) => {
|
|
11036
|
+
try {
|
|
11037
|
+
await server.close();
|
|
11038
|
+
} catch (err) {
|
|
11039
|
+
logger.warn(`server.close() failed for ${group.displayName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
11040
|
+
}
|
|
11041
|
+
}));
|
|
11042
|
+
await Promise.allSettled(wsServers.map(async (ws) => {
|
|
11043
|
+
try {
|
|
11044
|
+
await ws.server.close();
|
|
11045
|
+
} catch (err) {
|
|
11046
|
+
logger.warn(`WebSocket server.close() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
11047
|
+
}
|
|
11048
|
+
}));
|
|
11049
|
+
await Promise.allSettled(servers.map(async ({ server, group }) => {
|
|
11050
|
+
try {
|
|
11051
|
+
await server.getServerState().pool.dispose();
|
|
11052
|
+
} catch (err) {
|
|
11053
|
+
logger.warn(`pool.dispose() failed for ${group.displayName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
11054
|
+
}
|
|
11055
|
+
}));
|
|
11056
|
+
await Promise.allSettled(wsServers.map(async (ws) => {
|
|
11057
|
+
try {
|
|
11058
|
+
await ws.server.getServerState().pool.dispose();
|
|
11059
|
+
} catch (err) {
|
|
11060
|
+
logger.warn(`WebSocket pool.dispose() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
11061
|
+
}
|
|
11062
|
+
}));
|
|
11063
|
+
for (const dir of inlineTmpDirs) try {
|
|
11064
|
+
rmSync(dir, {
|
|
11065
|
+
recursive: true,
|
|
11066
|
+
force: true
|
|
11067
|
+
});
|
|
10952
11068
|
} catch (err) {
|
|
10953
|
-
logger.warn(`
|
|
11069
|
+
logger.warn(`Failed to remove inline-code tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
10954
11070
|
}
|
|
10955
|
-
|
|
10956
|
-
|
|
10957
|
-
|
|
10958
|
-
|
|
11071
|
+
for (const dir of layerTmpDirs) try {
|
|
11072
|
+
rmSync(dir, {
|
|
11073
|
+
recursive: true,
|
|
11074
|
+
force: true
|
|
11075
|
+
});
|
|
10959
11076
|
} catch (err) {
|
|
10960
|
-
logger.warn(`
|
|
11077
|
+
logger.warn(`Failed to remove merged-layers tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
10961
11078
|
}
|
|
10962
|
-
|
|
10963
|
-
|
|
10964
|
-
try {
|
|
10965
|
-
await ws.server.getServerState().pool.dispose();
|
|
11079
|
+
if (profileCredsFile) try {
|
|
11080
|
+
await profileCredsFile.dispose();
|
|
10966
11081
|
} catch (err) {
|
|
10967
|
-
logger.warn(`
|
|
11082
|
+
logger.warn(`Failed to remove profile credentials tmpdir ${profileCredsFile.hostPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
10968
11083
|
}
|
|
10969
|
-
})
|
|
10970
|
-
|
|
10971
|
-
|
|
10972
|
-
|
|
10973
|
-
|
|
10974
|
-
});
|
|
10975
|
-
} catch (err) {
|
|
10976
|
-
logger.warn(`Failed to remove inline-code tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
10977
|
-
}
|
|
10978
|
-
for (const dir of layerTmpDirs) try {
|
|
10979
|
-
rmSync(dir, {
|
|
10980
|
-
recursive: true,
|
|
10981
|
-
force: true
|
|
10982
|
-
});
|
|
10983
|
-
} catch (err) {
|
|
10984
|
-
logger.warn(`Failed to remove merged-layers tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
10985
|
-
}
|
|
10986
|
-
if (profileCredsFile) try {
|
|
10987
|
-
await profileCredsFile.dispose();
|
|
10988
|
-
} catch (err) {
|
|
10989
|
-
logger.warn(`Failed to remove profile credentials tmpdir ${profileCredsFile.hostPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
10990
|
-
}
|
|
11084
|
+
}),
|
|
11085
|
+
stoppingMessage: (signal) => `Received ${signal}, shutting down...`,
|
|
11086
|
+
forceExitHint: `Orphan containers may remain — run 'docker ps --filter name=${getEmbedConfig().resourceNamePrefix}-' and 'docker rm -f' to clean up.`,
|
|
11087
|
+
info: (m) => logger.info(m),
|
|
11088
|
+
warn: (m) => logger.warn(m)
|
|
10991
11089
|
});
|
|
10992
|
-
const shutdown = async (signal, exitCode) => {
|
|
10993
|
-
if (shutdownStarted) {
|
|
10994
|
-
if (!forceExitArmed) {
|
|
10995
|
-
forceExitArmed = true;
|
|
10996
|
-
logger.warn(`Received second ${signal}; force-exiting. Orphan containers may remain — run 'docker ps --filter name=${getEmbedConfig().resourceNamePrefix}-' and 'docker rm -f' to clean up.`);
|
|
10997
|
-
process.exit(130);
|
|
10998
|
-
}
|
|
10999
|
-
return;
|
|
11000
|
-
}
|
|
11001
|
-
shutdownStarted = true;
|
|
11002
|
-
firstSignal = signal;
|
|
11003
|
-
firstExitCode = exitCode;
|
|
11004
|
-
await runCleanup();
|
|
11005
|
-
process.exit(firstExitCode);
|
|
11006
|
-
};
|
|
11007
11090
|
process.on("SIGINT", () => {
|
|
11008
11091
|
shutdown("SIGINT", 130);
|
|
11009
11092
|
});
|
|
@@ -11721,7 +11804,7 @@ function warnSsrfRiskyIntegrations(routes, logger) {
|
|
|
11721
11804
|
}
|
|
11722
11805
|
}
|
|
11723
11806
|
async function reloadAllServers(args) {
|
|
11724
|
-
const { synthesizeAndBuild, servers, buildPool, logger } = args;
|
|
11807
|
+
const { synthesizeAndBuild, servers, buildPool, logger, signal } = args;
|
|
11725
11808
|
let material;
|
|
11726
11809
|
try {
|
|
11727
11810
|
material = await synthesizeAndBuild();
|
|
@@ -11729,6 +11812,10 @@ async function reloadAllServers(args) {
|
|
|
11729
11812
|
logger.warn(`cdk synth failed during reload; keeping previous version. (${err instanceof Error ? err.message : String(err)})`);
|
|
11730
11813
|
return;
|
|
11731
11814
|
}
|
|
11815
|
+
if (signal?.aborted) {
|
|
11816
|
+
logger.info("Reload cancelled: shutting down.");
|
|
11817
|
+
return;
|
|
11818
|
+
}
|
|
11732
11819
|
const newGroups = groupRoutesByServer(material.routes);
|
|
11733
11820
|
const newByKey = new Map(newGroups.map((g) => [g.serverKey, g]));
|
|
11734
11821
|
const oldKeys = new Set(servers.map((s) => s.group.serverKey));
|
|
@@ -13423,9 +13510,12 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
|
|
|
13423
13510
|
let containerId;
|
|
13424
13511
|
let stopLogs;
|
|
13425
13512
|
let sigintHandler;
|
|
13513
|
+
let sigtermHandler;
|
|
13426
13514
|
let profileCredsFile;
|
|
13427
13515
|
let stateProvider;
|
|
13516
|
+
let stopWatch;
|
|
13428
13517
|
const cleanup = singleFlight(async () => {
|
|
13518
|
+
if (stopWatch) await stopWatch();
|
|
13429
13519
|
if (stateProvider) try {
|
|
13430
13520
|
stateProvider.dispose();
|
|
13431
13521
|
} catch (err) {
|
|
@@ -13530,10 +13620,17 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
|
|
|
13530
13620
|
...sensitiveEnvKeys.size > 0 && { sensitiveEnvKeys }
|
|
13531
13621
|
});
|
|
13532
13622
|
stopLogs = streamLogs(containerId);
|
|
13533
|
-
|
|
13534
|
-
cleanup
|
|
13535
|
-
|
|
13623
|
+
const onSignal = createShutdownSignalHandler({
|
|
13624
|
+
cleanup,
|
|
13625
|
+
stoppingMessage: (signal) => `Received ${signal}, removing the agent container...`,
|
|
13626
|
+
forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
|
|
13627
|
+
info: (m) => logger.info(m),
|
|
13628
|
+
warn: (m) => logger.warn(m)
|
|
13629
|
+
});
|
|
13630
|
+
sigintHandler = () => onSignal("SIGINT", 130);
|
|
13631
|
+
sigtermHandler = () => onSignal("SIGTERM", 143);
|
|
13536
13632
|
process.on("SIGINT", sigintHandler);
|
|
13633
|
+
process.on("SIGTERM", sigtermHandler);
|
|
13537
13634
|
if (isMcp && mcpRequest) {
|
|
13538
13635
|
logger.info(`MCP request: ${mcpRequest.method}`);
|
|
13539
13636
|
const mcp = await mcpInvokeOnce(containerHost, hostPort, mcpRequest, { requestTimeoutMs: options.timeout });
|
|
@@ -13560,7 +13657,10 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
|
|
|
13560
13657
|
synthOpts,
|
|
13561
13658
|
stacks,
|
|
13562
13659
|
...authorization && { authorization },
|
|
13563
|
-
|
|
13660
|
+
registerStop: (stop) => {
|
|
13661
|
+
stopWatch = stop;
|
|
13662
|
+
},
|
|
13663
|
+
rebuild: async (signal) => {
|
|
13564
13664
|
if (stopLogs) {
|
|
13565
13665
|
try {
|
|
13566
13666
|
stopLogs();
|
|
@@ -13581,6 +13681,7 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
|
|
|
13581
13681
|
await resolveFromS3BucketIntrinsic(newResolved, stateProvider, newLoaded, newImageContext);
|
|
13582
13682
|
const newImage = await resolveAgentCoreImage(newResolved, options, newLoaded, stateProvider);
|
|
13583
13683
|
const { env: newEnv, sensitiveEnvKeys: newSensitive } = await buildContainerEnv(newResolved, options, profileCredentials, profileCredsFile, stateProvider, newLoaded, newImageContext);
|
|
13684
|
+
if (signal?.aborted) throw new CdkLocalError("Reload cancelled: shutting down.", "LOCAL_INVOKE_AGENTCORE_WATCH_CANCELLED");
|
|
13584
13685
|
const newHostPort = await pickFreePort();
|
|
13585
13686
|
const newName = `${getEmbedConfig().resourceNamePrefix}-agentcore-${process.pid}-${Math.random().toString(36).slice(2, 8)}`;
|
|
13586
13687
|
logger.info(`Reload: starting agent container (image=${newImage}, port=${newHostPort} -> 8080)...`);
|
|
@@ -13637,8 +13738,9 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
|
|
|
13637
13738
|
emitResult(result);
|
|
13638
13739
|
}
|
|
13639
13740
|
} finally {
|
|
13640
|
-
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
13641
13741
|
await cleanup();
|
|
13742
|
+
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
13743
|
+
if (sigtermHandler) process.off("SIGTERM", sigtermHandler);
|
|
13642
13744
|
}
|
|
13643
13745
|
}
|
|
13644
13746
|
async function resolveInboundAuthorization(resolved, options) {
|
|
@@ -14190,7 +14292,7 @@ async function runAgentCoreWatchLoop(args) {
|
|
|
14190
14292
|
const waitForPing = args.__waitForPing ?? waitForAgentCorePing;
|
|
14191
14293
|
let currentHostPort = args.hostPort;
|
|
14192
14294
|
let currentStacks = args.stacks;
|
|
14193
|
-
let
|
|
14295
|
+
let reloadQueue;
|
|
14194
14296
|
let currentAbort;
|
|
14195
14297
|
let pendingReload = false;
|
|
14196
14298
|
let reloadFailed = false;
|
|
@@ -14211,8 +14313,8 @@ async function runAgentCoreWatchLoop(args) {
|
|
|
14211
14313
|
});
|
|
14212
14314
|
const cdkOutDir = args.options.output;
|
|
14213
14315
|
const assetLoader = new AssetManifestLoader();
|
|
14214
|
-
|
|
14215
|
-
|
|
14316
|
+
reloadQueue = createReloadQueue({
|
|
14317
|
+
run: async (changedPaths, signal) => {
|
|
14216
14318
|
let verdict = {
|
|
14217
14319
|
kind: "rebuild",
|
|
14218
14320
|
reason: "classifier not consulted"
|
|
@@ -14247,6 +14349,7 @@ async function runAgentCoreWatchLoop(args) {
|
|
|
14247
14349
|
reason: "classifier context unavailable; falling back to rebuild"
|
|
14248
14350
|
};
|
|
14249
14351
|
}
|
|
14352
|
+
if (signal.aborted) return;
|
|
14250
14353
|
pendingReload = true;
|
|
14251
14354
|
logger.warn("cdkl invoke-agentcore --watch: source change detected; closing the active /ws socket so the client can reconnect to the rebuilt container.");
|
|
14252
14355
|
currentAbort?.abort();
|
|
@@ -14256,20 +14359,32 @@ async function runAgentCoreWatchLoop(args) {
|
|
|
14256
14359
|
currentStacks = newStacks;
|
|
14257
14360
|
logger.info("Reload: soft-reloaded the agent container (docker cp + docker restart; container ID + host port preserved).");
|
|
14258
14361
|
} else {
|
|
14259
|
-
const { containerId: _newId, hostPort: newHostPort, stacks: newStacks } = await args.rebuild();
|
|
14362
|
+
const { containerId: _newId, hostPort: newHostPort, stacks: newStacks } = await args.rebuild(signal);
|
|
14260
14363
|
currentHostPort = newHostPort;
|
|
14261
14364
|
currentStacks = newStacks;
|
|
14262
14365
|
logger.info(`Reload: rebuilt the agent container.`);
|
|
14263
14366
|
}
|
|
14264
14367
|
} catch (err) {
|
|
14368
|
+
if (signal.aborted) {
|
|
14369
|
+
logger.info("Reload cancelled: shutting down.");
|
|
14370
|
+
reloadFailed = true;
|
|
14371
|
+
currentAbort?.abort();
|
|
14372
|
+
return;
|
|
14373
|
+
}
|
|
14265
14374
|
logger.error(`Reload failed: ${err instanceof Error ? err.message : String(err)}. The previous container may already be torn down; exiting --watch loop. Re-run cdkl invoke-agentcore --watch to recover.`);
|
|
14266
14375
|
reloadFailed = true;
|
|
14267
14376
|
currentAbort?.abort();
|
|
14268
14377
|
}
|
|
14269
|
-
}
|
|
14270
|
-
|
|
14271
|
-
});
|
|
14378
|
+
},
|
|
14379
|
+
onError: (err) => logger.error(`Reload chain threw: ${err instanceof Error ? err.message : String(err)}`)
|
|
14272
14380
|
});
|
|
14381
|
+
const queue = reloadQueue;
|
|
14382
|
+
const watcher = watcherFactory((changedPaths) => queue.schedule(changedPaths));
|
|
14383
|
+
args.registerStop?.(() => stopWatchReloads({
|
|
14384
|
+
watcher,
|
|
14385
|
+
queue,
|
|
14386
|
+
onWatcherCloseError: (err) => logger.warn(`Watcher close failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
14387
|
+
}));
|
|
14273
14388
|
try {
|
|
14274
14389
|
let firstIteration = true;
|
|
14275
14390
|
while (true) {
|
|
@@ -14298,17 +14413,17 @@ async function runAgentCoreWatchLoop(args) {
|
|
|
14298
14413
|
currentAbort = void 0;
|
|
14299
14414
|
}
|
|
14300
14415
|
if (!pendingReload) {
|
|
14301
|
-
await
|
|
14416
|
+
await queue.idle();
|
|
14302
14417
|
if (!pendingReload) break;
|
|
14303
14418
|
}
|
|
14304
|
-
await
|
|
14419
|
+
await queue.idle();
|
|
14305
14420
|
}
|
|
14306
14421
|
} finally {
|
|
14307
|
-
|
|
14308
|
-
|
|
14309
|
-
|
|
14310
|
-
logger.warn(`Watcher close failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
14311
|
-
}
|
|
14422
|
+
await stopWatchReloads({
|
|
14423
|
+
watcher,
|
|
14424
|
+
queue,
|
|
14425
|
+
onWatcherCloseError: (err) => logger.warn(`Watcher close failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
14426
|
+
});
|
|
14312
14427
|
}
|
|
14313
14428
|
}
|
|
14314
14429
|
const execFileAsync$6 = promisify(execFile);
|
|
@@ -15135,7 +15250,8 @@ async function runEcsTask(task, options, state) {
|
|
|
15135
15250
|
...mergedAddHostFlags.length > 0 ? { addHostFlags: mergedAddHostFlags } : {},
|
|
15136
15251
|
...(options.networkAliasesByContainer?.get(container.name)?.length ?? 0) > 0 ? { networkAliases: options.networkAliasesByContainer.get(container.name) } : {},
|
|
15137
15252
|
...options.containerNameAliasOmitted?.has(container.name) ? { omitContainerNameAlias: true } : {},
|
|
15138
|
-
...options.profileCredentialsFile && { profileCredentialsFile: options.profileCredentialsFile }
|
|
15253
|
+
...options.profileCredentialsFile && { profileCredentialsFile: options.profileCredentialsFile },
|
|
15254
|
+
...options.defaultCredentials && { defaultCredentials: options.defaultCredentials }
|
|
15139
15255
|
});
|
|
15140
15256
|
dockerCmds.set(container.name, {
|
|
15141
15257
|
args: built.args,
|
|
@@ -15473,6 +15589,16 @@ async function resolvePrivilegedHostPortRemaps(opts) {
|
|
|
15473
15589
|
}
|
|
15474
15590
|
return remaps;
|
|
15475
15591
|
}
|
|
15592
|
+
const OWN_CREDENTIAL_SOURCE_KEYS = [
|
|
15593
|
+
"AWS_ACCESS_KEY_ID",
|
|
15594
|
+
"AWS_SECRET_ACCESS_KEY",
|
|
15595
|
+
"AWS_SESSION_TOKEN",
|
|
15596
|
+
"AWS_PROFILE",
|
|
15597
|
+
"AWS_SHARED_CREDENTIALS_FILE",
|
|
15598
|
+
"AWS_WEB_IDENTITY_TOKEN_FILE",
|
|
15599
|
+
"AWS_CONTAINER_CREDENTIALS_FULL_URI",
|
|
15600
|
+
"AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
|
|
15601
|
+
];
|
|
15476
15602
|
function buildDockerRunArgs(opts) {
|
|
15477
15603
|
const { task, container, image, network, volumeByName, secrets, containerHost, roleArn } = opts;
|
|
15478
15604
|
const args = ["run", "-d"];
|
|
@@ -15581,6 +15707,13 @@ function buildDockerRunArgs(opts) {
|
|
|
15581
15707
|
applyEnvOverrideMap(finalEnv, overrides["Parameters"]);
|
|
15582
15708
|
applyEnvOverrideMap(finalEnv, overrides[container.name]);
|
|
15583
15709
|
}
|
|
15710
|
+
const defaultCredentials = opts.defaultCredentials;
|
|
15711
|
+
const optedOut = [overrides?.["Parameters"], overrides?.[container.name]].some((m) => m !== void 0 && Object.hasOwn(m, "AWS_ACCESS_KEY_ID") && m["AWS_ACCESS_KEY_ID"] === null);
|
|
15712
|
+
if (defaultCredentials && wiring?.mode !== "emulator" && !optedOut && !OWN_CREDENTIAL_SOURCE_KEYS.some((k) => finalEnv[k])) {
|
|
15713
|
+
finalEnv["AWS_ACCESS_KEY_ID"] = defaultCredentials.accessKeyId;
|
|
15714
|
+
finalEnv["AWS_SECRET_ACCESS_KEY"] = defaultCredentials.secretAccessKey;
|
|
15715
|
+
if (defaultCredentials.sessionToken) finalEnv["AWS_SESSION_TOKEN"] = defaultCredentials.sessionToken;
|
|
15716
|
+
}
|
|
15584
15717
|
if (wiring) finalEnv = applyWorkloadAwsWiringToEnv(finalEnv, wiring.mode === "emulator" ? wiring : {
|
|
15585
15718
|
...wiring,
|
|
15586
15719
|
env: {}
|
|
@@ -19011,24 +19144,21 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
|
|
|
19011
19144
|
setShadowReadyTimeoutMs(resolveShadowReadyTimeoutMs(options, getEmbedConfig().envPrefix));
|
|
19012
19145
|
let perTarget = [];
|
|
19013
19146
|
let sigintHandler;
|
|
19014
|
-
let
|
|
19147
|
+
let sigtermHandler;
|
|
19015
19148
|
let sharedNetwork;
|
|
19016
19149
|
let profileCredsFile;
|
|
19017
19150
|
let frontDoorServers = [];
|
|
19018
19151
|
let frontDoorByService = /* @__PURE__ */ new Map();
|
|
19019
19152
|
let frontDoorLambdaRunners = [];
|
|
19020
19153
|
let watcher;
|
|
19021
|
-
let
|
|
19154
|
+
let reloadQueue;
|
|
19022
19155
|
const cleanup = singleFlight(async () => {
|
|
19023
|
-
|
|
19024
|
-
|
|
19025
|
-
|
|
19026
|
-
|
|
19027
|
-
|
|
19028
|
-
|
|
19029
|
-
watcher = void 0;
|
|
19030
|
-
}
|
|
19031
|
-
await reloadChain.catch(() => void 0);
|
|
19156
|
+
await stopWatchReloads({
|
|
19157
|
+
watcher,
|
|
19158
|
+
queue: reloadQueue,
|
|
19159
|
+
onWatcherCloseError: (err) => getLogger().warn(`watcher.close() failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
19160
|
+
});
|
|
19161
|
+
watcher = void 0;
|
|
19032
19162
|
await Promise.allSettled(perTarget.map(async (pt) => {
|
|
19033
19163
|
if (pt.controller) await pt.controller.shutdown();
|
|
19034
19164
|
else {
|
|
@@ -19126,17 +19256,17 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
|
|
|
19126
19256
|
frontDoorByService = built.frontDoorByService;
|
|
19127
19257
|
frontDoorLambdaRunners = built.lambdaRunners;
|
|
19128
19258
|
}
|
|
19129
|
-
|
|
19130
|
-
|
|
19131
|
-
|
|
19132
|
-
|
|
19133
|
-
|
|
19134
|
-
|
|
19135
|
-
|
|
19136
|
-
|
|
19137
|
-
|
|
19259
|
+
const onSignal = createShutdownSignalHandler({
|
|
19260
|
+
cleanup,
|
|
19261
|
+
stoppingMessage: () => "Stopping service(s)...",
|
|
19262
|
+
forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' and 'docker network ls --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
|
|
19263
|
+
info: (m) => logger.info(m),
|
|
19264
|
+
warn: (m) => logger.warn(m)
|
|
19265
|
+
});
|
|
19266
|
+
sigintHandler = () => onSignal("SIGINT", 130);
|
|
19267
|
+
sigtermHandler = () => onSignal("SIGTERM", 130);
|
|
19138
19268
|
process.on("SIGINT", sigintHandler);
|
|
19139
|
-
process.on("SIGTERM",
|
|
19269
|
+
process.on("SIGTERM", sigtermHandler);
|
|
19140
19270
|
const { tags: imageOverrideTags, overrides: imageOverrideMap } = await resolveAndBuildImageOverrides({
|
|
19141
19271
|
perTarget: perTarget.map((pt) => pt.boot.target),
|
|
19142
19272
|
stacks,
|
|
@@ -19170,47 +19300,50 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
|
|
|
19170
19300
|
output: options.output,
|
|
19171
19301
|
watchConfig: resolveWatchConfig()
|
|
19172
19302
|
});
|
|
19303
|
+
reloadQueue = createReloadQueue({
|
|
19304
|
+
run: (changedPaths, signal) => reloadAllServices({
|
|
19305
|
+
perTarget,
|
|
19306
|
+
synthesizer,
|
|
19307
|
+
synthOpts,
|
|
19308
|
+
strategy,
|
|
19309
|
+
resolvedTargets,
|
|
19310
|
+
cloudMapIndexByStack,
|
|
19311
|
+
options,
|
|
19312
|
+
discovery,
|
|
19313
|
+
skipPull,
|
|
19314
|
+
extraStateProviders,
|
|
19315
|
+
profileCredsFile,
|
|
19316
|
+
frontDoorByService,
|
|
19317
|
+
changedPaths,
|
|
19318
|
+
imageOverrideTags,
|
|
19319
|
+
imageOverrideMap,
|
|
19320
|
+
logger,
|
|
19321
|
+
signal
|
|
19322
|
+
}),
|
|
19323
|
+
onError: (err) => logger.error(`reloadAllServices threw: ${err instanceof Error ? err.message : String(err)}`),
|
|
19324
|
+
onCoalesced: (n) => logger.debug(`Reload in progress; ${n} changed path(s) queued for one follow-up reload.`)
|
|
19325
|
+
});
|
|
19326
|
+
const queue = reloadQueue;
|
|
19173
19327
|
watcher = createFileWatcher({
|
|
19174
19328
|
paths: [watchRoot],
|
|
19175
19329
|
ignored,
|
|
19176
19330
|
shouldTrigger,
|
|
19177
19331
|
onChange: (changedPaths) => {
|
|
19178
19332
|
logger.info(`Detected source change (${changedPaths.length} path(s)); reloading service(s)...`);
|
|
19179
|
-
|
|
19180
|
-
perTarget,
|
|
19181
|
-
synthesizer,
|
|
19182
|
-
synthOpts,
|
|
19183
|
-
strategy,
|
|
19184
|
-
resolvedTargets,
|
|
19185
|
-
cloudMapIndexByStack,
|
|
19186
|
-
options,
|
|
19187
|
-
discovery,
|
|
19188
|
-
skipPull,
|
|
19189
|
-
extraStateProviders,
|
|
19190
|
-
profileCredsFile,
|
|
19191
|
-
frontDoorByService,
|
|
19192
|
-
changedPaths,
|
|
19193
|
-
imageOverrideTags,
|
|
19194
|
-
imageOverrideMap,
|
|
19195
|
-
logger
|
|
19196
|
-
})).catch((err) => {
|
|
19197
|
-
logger.error(`reloadAllServices threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
19198
|
-
});
|
|
19333
|
+
queue.schedule(changedPaths);
|
|
19199
19334
|
}
|
|
19200
19335
|
});
|
|
19201
19336
|
logger.info(`Watching ${watchRoot} for source changes (excluding ${excludePatterns.join(", ")}).`);
|
|
19202
19337
|
}
|
|
19203
19338
|
await new Promise(() => {});
|
|
19204
19339
|
} finally {
|
|
19205
|
-
if (sigintHandler) {
|
|
19206
|
-
process.off("SIGINT", sigintHandler);
|
|
19207
|
-
process.off("SIGTERM", sigintHandler);
|
|
19208
|
-
}
|
|
19209
19340
|
await cleanup();
|
|
19341
|
+
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
19342
|
+
if (sigtermHandler) process.off("SIGTERM", sigtermHandler);
|
|
19210
19343
|
}
|
|
19211
19344
|
}
|
|
19212
19345
|
async function reloadAllServices(args) {
|
|
19213
|
-
const { perTarget, synthesizer, synthOpts, strategy, resolvedTargets, cloudMapIndexByStack, options, discovery, skipPull, extraStateProviders, profileCredsFile, frontDoorByService, changedPaths, imageOverrideTags: boottimeImageOverrideTags, imageOverrideMap, logger } = args;
|
|
19346
|
+
const { signal, perTarget, synthesizer, synthOpts, strategy, resolvedTargets, cloudMapIndexByStack, options, discovery, skipPull, extraStateProviders, profileCredsFile, frontDoorByService, changedPaths, imageOverrideTags: boottimeImageOverrideTags, imageOverrideMap, logger } = args;
|
|
19214
19347
|
let stacks;
|
|
19215
19348
|
try {
|
|
19216
19349
|
let checkSelectedStacks;
|
|
@@ -19220,12 +19353,16 @@ async function reloadAllServices(args) {
|
|
|
19220
19353
|
logger.warn(`cdk synth failed during reload; keeping previous version. (${err instanceof Error ? err.message : String(err)})`);
|
|
19221
19354
|
return;
|
|
19222
19355
|
}
|
|
19356
|
+
if (reloadCancelled(signal, logger)) return;
|
|
19223
19357
|
const imageOverrideTags = new Map(boottimeImageOverrideTags);
|
|
19224
|
-
for (const [target, entry] of imageOverrideMap.entries())
|
|
19225
|
-
|
|
19226
|
-
|
|
19227
|
-
|
|
19228
|
-
|
|
19358
|
+
for (const [target, entry] of imageOverrideMap.entries()) {
|
|
19359
|
+
if (reloadCancelled(signal, logger)) return;
|
|
19360
|
+
try {
|
|
19361
|
+
const newTag = (await runImageOverrideBuilds(/* @__PURE__ */ new Map([[target, entry]]))).get(target);
|
|
19362
|
+
if (newTag !== void 0) imageOverrideTags.set(target, newTag);
|
|
19363
|
+
} catch (err) {
|
|
19364
|
+
logger.warn(`Reload of ${displayStackName(target)}: --image-override rebuild failed; keeping the previous local image. (${err instanceof Error ? err.message : String(err)})`);
|
|
19365
|
+
}
|
|
19229
19366
|
}
|
|
19230
19367
|
const { boots: newBoots, warnings } = strategy.resolveBoots(stacks, resolvedTargets);
|
|
19231
19368
|
for (const w of warnings) logger.warn(w);
|
|
@@ -19239,6 +19376,7 @@ async function reloadAllServices(args) {
|
|
|
19239
19376
|
const cdkOutDir = options.output;
|
|
19240
19377
|
const assetLoader = new AssetManifestLoader();
|
|
19241
19378
|
for (const pt of perTarget) {
|
|
19379
|
+
if (reloadCancelled(signal, logger)) return;
|
|
19242
19380
|
const newBoot = newBootByTarget.get(pt.boot.target);
|
|
19243
19381
|
if (!newBoot) {
|
|
19244
19382
|
logger.warn(`Reload: target ${displayStackName(pt.boot.target)} no longer resolves to a service in the synthesized app; keeping the previous replica(s) serving.`);
|
|
@@ -19287,11 +19425,18 @@ async function reloadAllServices(args) {
|
|
|
19287
19425
|
suppressLoadBalancerWarning: strategy.suppressLoadBalancerWarning === true,
|
|
19288
19426
|
verdict,
|
|
19289
19427
|
...imageOverrideTags.get(newBoot.target) !== void 0 && { imageOverrideTag: imageOverrideTags.get(newBoot.target) },
|
|
19290
|
-
logger
|
|
19428
|
+
logger,
|
|
19429
|
+
...signal && { signal }
|
|
19291
19430
|
});
|
|
19292
19431
|
}
|
|
19432
|
+
if (reloadCancelled(signal, logger)) return;
|
|
19293
19433
|
logger.info("Reload complete.");
|
|
19294
19434
|
}
|
|
19435
|
+
function reloadCancelled(signal, logger) {
|
|
19436
|
+
if (!signal?.aborted) return false;
|
|
19437
|
+
logger.info("Reload cancelled: shutting down.");
|
|
19438
|
+
return true;
|
|
19439
|
+
}
|
|
19295
19440
|
async function loadAssetContextForTarget(args) {
|
|
19296
19441
|
const { target, controller, stacks, cdkOutDir, assetLoader, logger } = args;
|
|
19297
19442
|
const parsed = parseEcsTarget(target);
|
|
@@ -19358,7 +19503,7 @@ async function loadAssetContextForTarget(args) {
|
|
|
19358
19503
|
};
|
|
19359
19504
|
}
|
|
19360
19505
|
async function rollOneTarget(args) {
|
|
19361
|
-
const { controller, newBoot, stacks, options, discovery, skipPull, extraStateProviders, profileCredsFile, frontDoorPools, suppressLoadBalancerWarning, verdict, imageOverrideTag, logger } = args;
|
|
19506
|
+
const { signal, controller, newBoot, stacks, options, discovery, skipPull, extraStateProviders, profileCredsFile, frontDoorPools, suppressLoadBalancerWarning, verdict, imageOverrideTag, logger } = args;
|
|
19362
19507
|
const candidate = pickCandidateStack$1(newBoot.target, stacks);
|
|
19363
19508
|
const stateProvider = createLocalStateProvider(options, candidate?.stackName ?? "", await resolveCfnFallbackRegion(options, candidate?.region), extraStateProviders);
|
|
19364
19509
|
try {
|
|
@@ -19383,6 +19528,7 @@ async function rollOneTarget(args) {
|
|
|
19383
19528
|
if (verdict.kind === "soft-reload") logger.info(`Reload of ${displayStackName(newBoot.target)}: soft-reloading ${oldReplicas.length} replica(s) one at a time (docker cp source → restart → TCP-ready probe; no rebuild).`);
|
|
19384
19529
|
else logger.info(`Reload of ${displayStackName(newBoot.target)}: rolling ${oldReplicas.length} replica(s) one at a time (start new shadow → swap registrations → stop old).`);
|
|
19385
19530
|
for (const oldInstance of oldReplicas) {
|
|
19531
|
+
if (signal?.aborted) return;
|
|
19386
19532
|
const idx = controller.runState.replicas.indexOf(oldInstance);
|
|
19387
19533
|
if (idx === -1) {
|
|
19388
19534
|
logger.warn(`Reload of ${displayStackName(newBoot.target)}: replica r${oldInstance.index} (gen ${oldInstance.generation}) vanished before its roll; skipping.`);
|
|
@@ -20083,9 +20229,10 @@ async function localRunTaskCommand(target, options, extraStateProviders) {
|
|
|
20083
20229
|
if (options.verbose) logger.setLevel("debug");
|
|
20084
20230
|
const state = createEcsRunState();
|
|
20085
20231
|
let sigintHandler;
|
|
20086
|
-
let
|
|
20232
|
+
let sigtermHandler;
|
|
20087
20233
|
let stateProvider;
|
|
20088
20234
|
let profileCredsFile;
|
|
20235
|
+
let detachedTaskStarted = false;
|
|
20089
20236
|
let cleanupPromise;
|
|
20090
20237
|
const cleanup = async () => {
|
|
20091
20238
|
if (!cleanupPromise) cleanupPromise = (async () => {
|
|
@@ -20160,17 +20307,17 @@ async function localRunTaskCommand(target, options, extraStateProviders) {
|
|
|
20160
20307
|
}
|
|
20161
20308
|
}
|
|
20162
20309
|
} else if (!stateProvider && taskNeeds.needsCrossStackResolver) logger.warn("Container Environment / Secrets entries contain Fn::ImportValue / Fn::GetStackOutput intrinsics. Pass a state-source flag (e.g. --from-cfn-stack or a host-provided extension) to substitute them against deployed state.");
|
|
20163
|
-
|
|
20164
|
-
|
|
20165
|
-
|
|
20166
|
-
|
|
20167
|
-
|
|
20168
|
-
|
|
20169
|
-
|
|
20170
|
-
|
|
20171
|
-
|
|
20310
|
+
const onSignal = createShutdownSignalHandler({
|
|
20311
|
+
cleanup,
|
|
20312
|
+
stoppingMessage: () => "Stopping task...",
|
|
20313
|
+
forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' and 'docker network ls --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
|
|
20314
|
+
info: (m) => logger.info(m),
|
|
20315
|
+
warn: (m) => logger.warn(m)
|
|
20316
|
+
});
|
|
20317
|
+
sigintHandler = () => onSignal("SIGINT", 130);
|
|
20318
|
+
sigtermHandler = () => onSignal("SIGTERM", 130);
|
|
20172
20319
|
process.on("SIGINT", sigintHandler);
|
|
20173
|
-
process.on("SIGTERM",
|
|
20320
|
+
process.on("SIGTERM", sigtermHandler);
|
|
20174
20321
|
const effectiveAssumeRole = resolveEcsAssumeRoleOption(options);
|
|
20175
20322
|
let assumedCredentials;
|
|
20176
20323
|
let resolvedRoleArn;
|
|
@@ -20183,7 +20330,7 @@ async function localRunTaskCommand(target, options, extraStateProviders) {
|
|
|
20183
20330
|
assumedCredentials = await assumeTaskRole(resolvedRoleArn, options.region, options.profile);
|
|
20184
20331
|
}
|
|
20185
20332
|
const sidecarCredentials = await resolveSidecarCredentials(options, assumedCredentials);
|
|
20186
|
-
|
|
20333
|
+
const credsDelivery = containerCredentialDelivery(options, sidecarCredentials, assumedCredentials);
|
|
20187
20334
|
const envOverrides = readEnvOverridesFile(options.envVars);
|
|
20188
20335
|
const runOpts = {
|
|
20189
20336
|
cluster: options.cluster,
|
|
@@ -20203,11 +20350,7 @@ async function localRunTaskCommand(target, options, extraStateProviders) {
|
|
|
20203
20350
|
if (options.profile) runOpts.profile = options.profile;
|
|
20204
20351
|
const hostPortOverrides = parseHostPortOverrides(options.hostPort);
|
|
20205
20352
|
if (Object.keys(hostPortOverrides).length > 0) runOpts.hostPortOverrides = hostPortOverrides;
|
|
20206
|
-
if (
|
|
20207
|
-
hostPath: profileCredsFile.hostPath,
|
|
20208
|
-
containerPath: profileCredsFile.containerPath,
|
|
20209
|
-
profileName: profileCredsFile.profileName
|
|
20210
|
-
};
|
|
20353
|
+
if (credsDelivery === "env" && sidecarCredentials) runOpts.defaultCredentials = sidecarCredentials;
|
|
20211
20354
|
const imageOverrideResult = await resolveRunTaskImageOverride({
|
|
20212
20355
|
task,
|
|
20213
20356
|
target: resolvedTarget,
|
|
@@ -20222,7 +20365,16 @@ async function localRunTaskCommand(target, options, extraStateProviders) {
|
|
|
20222
20365
|
};
|
|
20223
20366
|
const hostGatewayExtraHosts = await resolveHostGatewayExtraHosts();
|
|
20224
20367
|
if (hostGatewayExtraHosts.length > 0) runOpts.hostGatewayExtraHosts = hostGatewayExtraHosts;
|
|
20368
|
+
if (credsDelivery === "profile-file" && options.profile && sidecarCredentials) {
|
|
20369
|
+
profileCredsFile = await writeProfileCredentialsFile(options.profile, sidecarCredentials);
|
|
20370
|
+
runOpts.profileCredentialsFile = {
|
|
20371
|
+
hostPath: profileCredsFile.hostPath,
|
|
20372
|
+
containerPath: profileCredsFile.containerPath,
|
|
20373
|
+
profileName: profileCredsFile.profileName
|
|
20374
|
+
};
|
|
20375
|
+
}
|
|
20225
20376
|
const result = await runEcsTask(task, runOpts, state);
|
|
20377
|
+
detachedTaskStarted = options.detach;
|
|
20226
20378
|
if (options.detach) {
|
|
20227
20379
|
logger.info(`Task containers started in detached mode; ${getEmbedConfig().binaryName} is exiting.`);
|
|
20228
20380
|
logger.info(`Use 'docker ps --filter network=${result.state.network?.networkName ?? "<network>"}' to inspect; tear down with 'docker rm -f' and 'docker network rm'.`);
|
|
@@ -20232,18 +20384,17 @@ async function localRunTaskCommand(target, options, extraStateProviders) {
|
|
|
20232
20384
|
const containers = result.state.startedContainers.filter((c) => joinedNames.has(c.name)).map((c) => c.id.slice(0, 12)).join(", ");
|
|
20233
20385
|
logger.info(`Under the loopback AWS endpoint, task containers share the network of a forwarder container, so that filter does not list them. Task container ids: ${containers}. Remove them before the forwarders (${joinedForwarders.map((f) => f.name).join(", ")}).`);
|
|
20234
20386
|
}
|
|
20235
|
-
|
|
20387
|
+
if (profileCredsFile) logger.info(`The task containers read the --profile credentials from ${path.dirname(profileCredsFile.hostPath)}; remove that directory after removing them.`);
|
|
20236
20388
|
return;
|
|
20237
20389
|
}
|
|
20238
20390
|
if (result.essentialContainerName) logger.info(`Essential container ${displayIdent(result.essentialContainerName)} exited with code ${result.exitCode}.`);
|
|
20239
20391
|
if (result.exitCode !== 0) process.exitCode = result.exitCode;
|
|
20240
20392
|
} finally {
|
|
20241
|
-
if (sigintHandler) {
|
|
20242
|
-
process.off("SIGINT", sigintHandler);
|
|
20243
|
-
process.off("SIGTERM", sigintHandler);
|
|
20244
|
-
}
|
|
20245
20393
|
if (stateProvider) stateProvider.dispose();
|
|
20246
20394
|
if (!options.detach) await cleanup();
|
|
20395
|
+
else if (!detachedTaskStarted && profileCredsFile) await profileCredsFile.dispose().catch(() => void 0);
|
|
20396
|
+
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
20397
|
+
if (sigtermHandler) process.off("SIGTERM", sigtermHandler);
|
|
20247
20398
|
}
|
|
20248
20399
|
}
|
|
20249
20400
|
var PlaceholderAccountError = class PlaceholderAccountError extends Error {
|
|
@@ -20369,6 +20520,11 @@ async function resolveSidecarCredentials(options, assumedCredentials) {
|
|
|
20369
20520
|
if (options.profile) return resolveProfileCredentials(options.profile);
|
|
20370
20521
|
return resolveHostDefaultCredentials();
|
|
20371
20522
|
}
|
|
20523
|
+
function containerCredentialDelivery(options, sidecarCredentials, assumedCredentials) {
|
|
20524
|
+
if (!sidecarCredentials || assumedCredentials) return void 0;
|
|
20525
|
+
if (getActiveWorkloadAwsWiring()?.mode === "emulator") return void 0;
|
|
20526
|
+
return options.profile ? "profile-file" : "env";
|
|
20527
|
+
}
|
|
20372
20528
|
function createLocalRunTaskCommand(opts = {}) {
|
|
20373
20529
|
setEmbedConfig(opts.embedConfig);
|
|
20374
20530
|
const cmd = new Command("run-task").description("Run an AWS::ECS::TaskDefinition locally — pulls/builds images, sets up a per-task docker network with the AWS-published metadata-endpoints sidecar, and starts every container in dependsOn order. Target accepts a CDK display path (MyStack/MyService/TaskDef) or stack-qualified logical ID (MyStack:MyServiceTaskDefXYZ1234). Single-stack apps may omit the stack prefix. Omit <target> in an interactive terminal to pick the task definition from a list.").argument("[target]", "CDK display path or stack-qualified logical ID of the AWS::ECS::TaskDefinition to run (omit to pick interactively in a TTY)").action(withErrorHandling(async (target, options) => {
|
|
@@ -24414,7 +24570,7 @@ async function localStartCloudFrontCommand(target, options, extraStateProviders,
|
|
|
24414
24570
|
process.stdout.write(`CloudFront distribution serving on ${server.url} (${displayIdent(initial.distribution.logicalId)})\n`);
|
|
24415
24571
|
process.stdout.write("^C to stop.\n");
|
|
24416
24572
|
let watcher;
|
|
24417
|
-
let
|
|
24573
|
+
let reloadQueue;
|
|
24418
24574
|
if (options.watch) {
|
|
24419
24575
|
const watchRoot = process.cwd();
|
|
24420
24576
|
const { ignored, shouldTrigger, excludePatterns } = createWatchPredicates({
|
|
@@ -24422,37 +24578,37 @@ async function localStartCloudFrontCommand(target, options, extraStateProviders,
|
|
|
24422
24578
|
output: options.output,
|
|
24423
24579
|
watchConfig: resolveWatchConfig()
|
|
24424
24580
|
});
|
|
24581
|
+
const queue = createReloadQueue({ run: async (_changedPaths, signal) => {
|
|
24582
|
+
try {
|
|
24583
|
+
const reloaded = await synthAndResolve();
|
|
24584
|
+
if (signal.aborted) return;
|
|
24585
|
+
annotateDeployedS3Origins(reloaded.distribution, deployedS3.buckets);
|
|
24586
|
+
for (const reader of deployedS3.readers.values()) reader.clearCache();
|
|
24587
|
+
warnUnsupported(reloaded.distribution, extraStateProviders);
|
|
24588
|
+
await attachKvsModules(reloaded.distribution, reloaded.stacks, options, profileCredentials, logger, extraStateProviders);
|
|
24589
|
+
server.update(reloaded.distribution);
|
|
24590
|
+
logger.info("Reload complete.");
|
|
24591
|
+
} catch (err) {
|
|
24592
|
+
logger.warn(`Reload failed; keeping the previous version serving: ${err instanceof Error ? err.message : String(err)}`);
|
|
24593
|
+
}
|
|
24594
|
+
} });
|
|
24595
|
+
reloadQueue = queue;
|
|
24425
24596
|
watcher = createFileWatcher({
|
|
24426
24597
|
paths: [watchRoot],
|
|
24427
24598
|
ignored,
|
|
24428
24599
|
shouldTrigger,
|
|
24429
|
-
onChange: () => {
|
|
24600
|
+
onChange: (changedPaths) => {
|
|
24430
24601
|
logger.info("Detected source change; reloading...");
|
|
24431
|
-
|
|
24432
|
-
try {
|
|
24433
|
-
const reloaded = await synthAndResolve();
|
|
24434
|
-
annotateDeployedS3Origins(reloaded.distribution, deployedS3.buckets);
|
|
24435
|
-
for (const reader of deployedS3.readers.values()) reader.clearCache();
|
|
24436
|
-
warnUnsupported(reloaded.distribution, extraStateProviders);
|
|
24437
|
-
await attachKvsModules(reloaded.distribution, reloaded.stacks, options, profileCredentials, logger, extraStateProviders);
|
|
24438
|
-
server.update(reloaded.distribution);
|
|
24439
|
-
logger.info("Reload complete.");
|
|
24440
|
-
} catch (err) {
|
|
24441
|
-
logger.warn(`Reload failed; keeping the previous version serving: ${err instanceof Error ? err.message : String(err)}`);
|
|
24442
|
-
}
|
|
24443
|
-
}).catch(() => void 0);
|
|
24602
|
+
queue.schedule(changedPaths);
|
|
24444
24603
|
}
|
|
24445
24604
|
});
|
|
24446
24605
|
logger.info(`Watching ${watchRoot} for source changes (excluding ${excludePatterns.join(", ")}).`);
|
|
24447
24606
|
}
|
|
24448
|
-
|
|
24449
|
-
|
|
24450
|
-
|
|
24451
|
-
|
|
24452
|
-
|
|
24453
|
-
if (watcher) try {
|
|
24454
|
-
await watcher.close();
|
|
24455
|
-
} catch {}
|
|
24607
|
+
const teardown = async () => {
|
|
24608
|
+
await stopWatchReloads({
|
|
24609
|
+
watcher,
|
|
24610
|
+
queue: reloadQueue
|
|
24611
|
+
});
|
|
24456
24612
|
try {
|
|
24457
24613
|
await server.close();
|
|
24458
24614
|
} catch {}
|
|
@@ -24462,10 +24618,16 @@ async function localStartCloudFrontCommand(target, options, extraStateProviders,
|
|
|
24462
24618
|
logger.debug(`Web function server teardown failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
24463
24619
|
}))]);
|
|
24464
24620
|
await Promise.all([...deployedS3.readers.values()].map((reader) => reader.close()));
|
|
24465
|
-
process.exit(exitCode);
|
|
24466
24621
|
};
|
|
24467
|
-
|
|
24468
|
-
|
|
24622
|
+
const shutdown = createShutdownSignalHandler({
|
|
24623
|
+
cleanup: () => teardown().catch(() => void 0),
|
|
24624
|
+
stoppingMessage: (signal) => `Received ${signal}, shutting down...`,
|
|
24625
|
+
forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
|
|
24626
|
+
info: (m) => logger.info(m),
|
|
24627
|
+
warn: (m) => logger.warn(m)
|
|
24628
|
+
});
|
|
24629
|
+
process.on("SIGINT", () => shutdown("SIGINT", 130));
|
|
24630
|
+
process.on("SIGTERM", () => shutdown("SIGTERM", 0));
|
|
24469
24631
|
await new Promise(() => void 0);
|
|
24470
24632
|
}
|
|
24471
24633
|
function createLocalStartCloudFrontCommand(opts = {}) {
|
|
@@ -24836,20 +24998,17 @@ async function localStartAgentCoreCommand(target, options, extraStateProviders,
|
|
|
24836
24998
|
let profileCredsFile;
|
|
24837
24999
|
let stateProvider;
|
|
24838
25000
|
let watcher;
|
|
24839
|
-
let
|
|
25001
|
+
let reloadQueue;
|
|
24840
25002
|
let shuttingDown = false;
|
|
24841
25003
|
let tornDown = false;
|
|
24842
25004
|
const teardown = async () => {
|
|
24843
25005
|
if (tornDown) return;
|
|
24844
25006
|
tornDown = true;
|
|
24845
|
-
|
|
24846
|
-
|
|
24847
|
-
|
|
24848
|
-
logger.debug(`watcher close failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
24849
|
-
}
|
|
24850
|
-
try {
|
|
24851
|
-
await reloadChain;
|
|
24852
|
-
} catch {}
|
|
25007
|
+
await stopWatchReloads({
|
|
25008
|
+
watcher,
|
|
25009
|
+
queue: reloadQueue,
|
|
25010
|
+
onWatcherCloseError: (err) => logger.debug(`watcher close failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
25011
|
+
});
|
|
24853
25012
|
if (server) try {
|
|
24854
25013
|
await server.close();
|
|
24855
25014
|
} catch (err) {
|
|
@@ -24934,15 +25093,18 @@ async function localStartAgentCoreCommand(target, options, extraStateProviders,
|
|
|
24934
25093
|
...sensitiveEnvKeys.size > 0 && { sensitiveEnvKeys }
|
|
24935
25094
|
});
|
|
24936
25095
|
stopLogs = streamLogs(containerId);
|
|
24937
|
-
const shutdown =
|
|
24938
|
-
|
|
24939
|
-
|
|
24940
|
-
|
|
24941
|
-
|
|
24942
|
-
|
|
24943
|
-
|
|
24944
|
-
|
|
24945
|
-
|
|
25096
|
+
const shutdown = createShutdownSignalHandler({
|
|
25097
|
+
cleanup: async () => {
|
|
25098
|
+
shuttingDown = true;
|
|
25099
|
+
await teardown().catch(() => void 0);
|
|
25100
|
+
},
|
|
25101
|
+
stoppingMessage: (signal) => `Received ${signal}, shutting down...`,
|
|
25102
|
+
forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
|
|
25103
|
+
info: (m) => logger.info(m),
|
|
25104
|
+
warn: (m) => logger.warn(m)
|
|
25105
|
+
});
|
|
25106
|
+
process.on("SIGINT", () => shutdown("SIGINT", 130));
|
|
25107
|
+
process.on("SIGTERM", () => shutdown("SIGTERM", 0));
|
|
24946
25108
|
try {
|
|
24947
25109
|
if (plan.readyPath === void 0) await waitForAgentCorePing(containerHost, containerHostPort, options.timeout);
|
|
24948
25110
|
else await waitForAgentCoreHttpReady(containerHost, containerHostPort, plan.readyPath, options.timeout);
|
|
@@ -25012,95 +25174,99 @@ async function localStartAgentCoreCommand(target, options, extraStateProviders,
|
|
|
25012
25174
|
watchConfig: resolveWatchConfig()
|
|
25013
25175
|
});
|
|
25014
25176
|
logger.info(`Watching ${watchRoot} for source changes (excluding ${excludePatterns.join(", ")}). The warm container reloads in place; the serve stays up.`);
|
|
25177
|
+
reloadQueue = createReloadQueue({
|
|
25178
|
+
run: async (changedPaths) => {
|
|
25179
|
+
if (tornDown || shuttingDown) return;
|
|
25180
|
+
let freshStacks;
|
|
25181
|
+
let freshResolved;
|
|
25182
|
+
let freshLoaded;
|
|
25183
|
+
let freshImageContext;
|
|
25184
|
+
let verdict;
|
|
25185
|
+
let nextAssetHash = currentAssetHash;
|
|
25186
|
+
try {
|
|
25187
|
+
const synthRes = await synthesizer.synthesize(synthOpts);
|
|
25188
|
+
freshStacks = synthRes.stacks;
|
|
25189
|
+
synthRes.checkSelectedStacks?.([resolved.stack.stackName]);
|
|
25190
|
+
const freshCandidate = pickAgentCoreCandidateStack(resolvedTarget, freshStacks);
|
|
25191
|
+
const ctx = stateProvider && freshCandidate ? await buildAgentCoreImageContext(freshCandidate, stateProvider, options) : {
|
|
25192
|
+
context: void 0,
|
|
25193
|
+
loaded: void 0
|
|
25194
|
+
};
|
|
25195
|
+
freshImageContext = ctx.context;
|
|
25196
|
+
freshLoaded = ctx.loaded;
|
|
25197
|
+
freshResolved = resolveAgentCoreTarget(resolvedTarget, freshStacks, freshImageContext);
|
|
25198
|
+
await resolveFromS3BucketIntrinsic(freshResolved, stateProvider, freshLoaded, freshImageContext);
|
|
25199
|
+
const assetCtx = await loadAgentCoreAssetContext({
|
|
25200
|
+
resolvedTarget,
|
|
25201
|
+
resolved: freshResolved,
|
|
25202
|
+
stacks: freshStacks,
|
|
25203
|
+
cdkOutDir,
|
|
25204
|
+
assetLoader,
|
|
25205
|
+
oldAssetHash: currentAssetHash
|
|
25206
|
+
});
|
|
25207
|
+
if (assetCtx?.newAssetHash !== void 0) nextAssetHash = assetCtx.newAssetHash;
|
|
25208
|
+
verdict = classifySourceChange(changedPaths, assetCtx);
|
|
25209
|
+
logger.info(`Detected source change (${changedPaths.length} path(s)); verdict=${verdict.kind} (${verdict.reason}).`);
|
|
25210
|
+
} catch (err) {
|
|
25211
|
+
logger.error(`Reload: re-synth / classify failed (${err instanceof Error ? err.message : String(err)}); skipping this change. The serve stays up against the current container.`);
|
|
25212
|
+
return;
|
|
25213
|
+
}
|
|
25214
|
+
if (tornDown || shuttingDown) return;
|
|
25215
|
+
try {
|
|
25216
|
+
if (verdict.kind === "soft-reload") {
|
|
25217
|
+
if (!containerId) throw new CdkLocalError("Reload: no live container to docker cp / docker restart into.", "LOCAL_START_AGENTCORE_WATCH_NO_CONTAINER");
|
|
25218
|
+
await softReloadAgentContainer(containerId, verdict.newAssetSourceDir);
|
|
25219
|
+
await waitReady(containerHostPort);
|
|
25220
|
+
logger.info("Reload: soft-reloaded the agent container (docker cp + docker restart; container ID + host port preserved).");
|
|
25221
|
+
} else {
|
|
25222
|
+
if (stopLogs) {
|
|
25223
|
+
try {
|
|
25224
|
+
stopLogs();
|
|
25225
|
+
} catch {}
|
|
25226
|
+
stopLogs = void 0;
|
|
25227
|
+
}
|
|
25228
|
+
if (containerId) {
|
|
25229
|
+
await removeContainer(containerId);
|
|
25230
|
+
containerId = void 0;
|
|
25231
|
+
}
|
|
25232
|
+
const newImage = await resolveAgentCoreImage(freshResolved, options, freshLoaded, stateProvider);
|
|
25233
|
+
const { env: newEnv, sensitiveEnvKeys: newSensitive } = await buildContainerEnv(freshResolved, options, profileCredentials, profileCredsFile, stateProvider, freshLoaded, freshImageContext);
|
|
25234
|
+
if (tornDown || shuttingDown) return;
|
|
25235
|
+
const newPort = await pickFreePort();
|
|
25236
|
+
const newName = `${getEmbedConfig().resourceNamePrefix}-agentcore-${process.pid}-${Math.random().toString(36).slice(2, 8)}`;
|
|
25237
|
+
logger.info(`Reload: starting agent container (image=${newImage}, port=${newPort} -> ${plan.containerPortLabel})...`);
|
|
25238
|
+
containerId = await runDetached({
|
|
25239
|
+
image: newImage,
|
|
25240
|
+
mounts: [],
|
|
25241
|
+
env: newEnv,
|
|
25242
|
+
cmd: [],
|
|
25243
|
+
hostPort: newPort,
|
|
25244
|
+
host: containerHost,
|
|
25245
|
+
platform: options.platform,
|
|
25246
|
+
name: newName,
|
|
25247
|
+
...plan.containerPort !== void 0 && { containerPort: plan.containerPort },
|
|
25248
|
+
...newSensitive.size > 0 && { sensitiveEnvKeys: newSensitive }
|
|
25249
|
+
});
|
|
25250
|
+
stopLogs = streamLogs(containerId);
|
|
25251
|
+
containerHostPort = newPort;
|
|
25252
|
+
await waitReady(newPort);
|
|
25253
|
+
server?.setContainerPort(newPort);
|
|
25254
|
+
logger.info(`Reload: rebuilt the agent container; serve re-pointed to port ${newPort}.`);
|
|
25255
|
+
}
|
|
25256
|
+
currentAssetHash = nextAssetHash;
|
|
25257
|
+
logger.info("Reload complete.");
|
|
25258
|
+
} catch (err) {
|
|
25259
|
+
logger.error(`Reload failed: ${err instanceof Error ? err.message : String(err)}. The serve stays up; edit + save again to retry.`);
|
|
25260
|
+
}
|
|
25261
|
+
},
|
|
25262
|
+
onError: (err) => logger.error(`Reload failed: ${err instanceof Error ? err.message : String(err)}.`)
|
|
25263
|
+
});
|
|
25264
|
+
const queue = reloadQueue;
|
|
25015
25265
|
watcher = createFileWatcher({
|
|
25016
25266
|
paths: [watchRoot],
|
|
25017
25267
|
ignored,
|
|
25018
25268
|
shouldTrigger,
|
|
25019
|
-
onChange: (changedPaths) =>
|
|
25020
|
-
reloadChain = reloadChain.then(async () => {
|
|
25021
|
-
if (tornDown || shuttingDown) return;
|
|
25022
|
-
let freshStacks;
|
|
25023
|
-
let freshResolved;
|
|
25024
|
-
let freshLoaded;
|
|
25025
|
-
let freshImageContext;
|
|
25026
|
-
let verdict;
|
|
25027
|
-
let nextAssetHash = currentAssetHash;
|
|
25028
|
-
try {
|
|
25029
|
-
const synthRes = await synthesizer.synthesize(synthOpts);
|
|
25030
|
-
freshStacks = synthRes.stacks;
|
|
25031
|
-
synthRes.checkSelectedStacks?.([resolved.stack.stackName]);
|
|
25032
|
-
const freshCandidate = pickAgentCoreCandidateStack(resolvedTarget, freshStacks);
|
|
25033
|
-
const ctx = stateProvider && freshCandidate ? await buildAgentCoreImageContext(freshCandidate, stateProvider, options) : {
|
|
25034
|
-
context: void 0,
|
|
25035
|
-
loaded: void 0
|
|
25036
|
-
};
|
|
25037
|
-
freshImageContext = ctx.context;
|
|
25038
|
-
freshLoaded = ctx.loaded;
|
|
25039
|
-
freshResolved = resolveAgentCoreTarget(resolvedTarget, freshStacks, freshImageContext);
|
|
25040
|
-
await resolveFromS3BucketIntrinsic(freshResolved, stateProvider, freshLoaded, freshImageContext);
|
|
25041
|
-
const assetCtx = await loadAgentCoreAssetContext({
|
|
25042
|
-
resolvedTarget,
|
|
25043
|
-
resolved: freshResolved,
|
|
25044
|
-
stacks: freshStacks,
|
|
25045
|
-
cdkOutDir,
|
|
25046
|
-
assetLoader,
|
|
25047
|
-
oldAssetHash: currentAssetHash
|
|
25048
|
-
});
|
|
25049
|
-
if (assetCtx?.newAssetHash !== void 0) nextAssetHash = assetCtx.newAssetHash;
|
|
25050
|
-
verdict = classifySourceChange(changedPaths, assetCtx);
|
|
25051
|
-
logger.info(`Detected source change (${changedPaths.length} path(s)); verdict=${verdict.kind} (${verdict.reason}).`);
|
|
25052
|
-
} catch (err) {
|
|
25053
|
-
logger.error(`Reload: re-synth / classify failed (${err instanceof Error ? err.message : String(err)}); skipping this change. The serve stays up against the current container.`);
|
|
25054
|
-
return;
|
|
25055
|
-
}
|
|
25056
|
-
if (tornDown || shuttingDown) return;
|
|
25057
|
-
try {
|
|
25058
|
-
if (verdict.kind === "soft-reload") {
|
|
25059
|
-
if (!containerId) throw new CdkLocalError("Reload: no live container to docker cp / docker restart into.", "LOCAL_START_AGENTCORE_WATCH_NO_CONTAINER");
|
|
25060
|
-
await softReloadAgentContainer(containerId, verdict.newAssetSourceDir);
|
|
25061
|
-
await waitReady(containerHostPort);
|
|
25062
|
-
logger.info("Reload: soft-reloaded the agent container (docker cp + docker restart; container ID + host port preserved).");
|
|
25063
|
-
} else {
|
|
25064
|
-
if (stopLogs) {
|
|
25065
|
-
try {
|
|
25066
|
-
stopLogs();
|
|
25067
|
-
} catch {}
|
|
25068
|
-
stopLogs = void 0;
|
|
25069
|
-
}
|
|
25070
|
-
if (containerId) {
|
|
25071
|
-
await removeContainer(containerId);
|
|
25072
|
-
containerId = void 0;
|
|
25073
|
-
}
|
|
25074
|
-
const newImage = await resolveAgentCoreImage(freshResolved, options, freshLoaded, stateProvider);
|
|
25075
|
-
const { env: newEnv, sensitiveEnvKeys: newSensitive } = await buildContainerEnv(freshResolved, options, profileCredentials, profileCredsFile, stateProvider, freshLoaded, freshImageContext);
|
|
25076
|
-
const newPort = await pickFreePort();
|
|
25077
|
-
const newName = `${getEmbedConfig().resourceNamePrefix}-agentcore-${process.pid}-${Math.random().toString(36).slice(2, 8)}`;
|
|
25078
|
-
logger.info(`Reload: starting agent container (image=${newImage}, port=${newPort} -> ${plan.containerPortLabel})...`);
|
|
25079
|
-
containerId = await runDetached({
|
|
25080
|
-
image: newImage,
|
|
25081
|
-
mounts: [],
|
|
25082
|
-
env: newEnv,
|
|
25083
|
-
cmd: [],
|
|
25084
|
-
hostPort: newPort,
|
|
25085
|
-
host: containerHost,
|
|
25086
|
-
platform: options.platform,
|
|
25087
|
-
name: newName,
|
|
25088
|
-
...plan.containerPort !== void 0 && { containerPort: plan.containerPort },
|
|
25089
|
-
...newSensitive.size > 0 && { sensitiveEnvKeys: newSensitive }
|
|
25090
|
-
});
|
|
25091
|
-
stopLogs = streamLogs(containerId);
|
|
25092
|
-
containerHostPort = newPort;
|
|
25093
|
-
await waitReady(newPort);
|
|
25094
|
-
server?.setContainerPort(newPort);
|
|
25095
|
-
logger.info(`Reload: rebuilt the agent container; serve re-pointed to port ${newPort}.`);
|
|
25096
|
-
}
|
|
25097
|
-
currentAssetHash = nextAssetHash;
|
|
25098
|
-
logger.info("Reload complete.");
|
|
25099
|
-
} catch (err) {
|
|
25100
|
-
logger.error(`Reload failed: ${err instanceof Error ? err.message : String(err)}. The serve stays up; edit + save again to retry.`);
|
|
25101
|
-
}
|
|
25102
|
-
});
|
|
25103
|
-
}
|
|
25269
|
+
onChange: (changedPaths) => queue.schedule(changedPaths)
|
|
25104
25270
|
});
|
|
25105
25271
|
}
|
|
25106
25272
|
await new Promise(() => void 0);
|
|
@@ -31773,4 +31939,4 @@ function addStudioSpecificOptions(cmd) {
|
|
|
31773
31939
|
|
|
31774
31940
|
//#endregion
|
|
31775
31941
|
export { postHook as $, addAwsEndpointOptions as $a, parseConnectionsPath as $i, addImageOverrideOptions as $n, addStartApiSpecificOptions as $r, classifyS3Error as $t, microvmFidelityWarnings as A, parseSelectionExpressionPath as Aa, applyCorsResponseHeaders as Ai, stripCloudFrontImport as An, A2A_CONTAINER_PORT as Ar, readContainerLogTail as At, MICROVM_WS_BASE_PROTOCOL as B, AgentCoreResolutionError as Ba, evaluateResponseParameters as Bi, createLocalStartAlbCommand as Bn, AGENTCORE_SESSION_ID_HEADER as Br, parseWebFunctionBuildConfig as Bt, addListSpecificOptions as C, resolveSingleTarget as Ca, verifyJwtViaDiscovery as Ci, WEB_FUNCTION_REVISION_TYPE as Cn, setShadowReadyTimeoutMs as Cr, parseKvsFileOverrides as Ct, buildMicrovmLambdaView as D, discoverWebSocketApis as Da, invokeRequestAuthorizer as Di, compileCloudFrontFunction as Dn, createLocalInvokeAgentCoreCommand as Dr, WEB_FUNCTION_CONTAINER_PORT as Dt, addStartMicrovmSpecificOptions as E, availableWebSocketApiIdentifiers as Ea, evaluateCachedLambdaPolicy as Ei, resolveWebFunctionTarget as En, addInvokeAgentCoreSpecificOptions as Er, RecentOutput as Et, microvmImageTag as F, AGENTCORE_A2A_PROTOCOL as Fa, matchRoute as Fi, findFileAssetForObjectKey as Fn, MCP_PROTOCOL_VERSION as Fr, buildNodeEntryFileStart as Ft, startMicrovmFrontDoor as G, containsDynamicReference as Ga, HOST_DOCKER_INTERNAL_GATEWAY as Gi, addStartServiceSpecificOptions as Gn, SUPPORTED_CODE_RUNTIMES as Gr, readWebFunctionServiceConfig as Gt, PROXY_PORT_HEADER as H, resolveAgentCoreTarget as Ha, selectIntegrationResponse as Hi, resolveAlbTarget as Hn, waitForAgentCoreHttpReady as Hr, WEB_FUNCTION_HTTP_ENDPOINT_ENV as Ht, planMicrovmPorts as I, AGENTCORE_AGUI_PROTOCOL as Ia, translateLambdaResponse as Ii, isBucketDeploymentResource as In, mcpInvokeOnce as Ir, defaultWebFunctionPlatform as It, MICROVM_HOOK_PATH_PREFIX as J, keysNotFromTemplate as Ja, resolveHostGatewayExtraHosts as Ji, addRunTaskSpecificOptions as Jn, renderCodeDockerfile as Jr, idFromArn as Jt, stripMicrovmProxyHeaders as K, deployedFillMayBeSecret as Ka, HOST_GATEWAY_MIN_VERSION as Ki, createLocalStartServiceCommand as Kn, buildAgentCoreCodeImage as Kr, webFunctionAssumeRole as Kt, readExposedPorts as L, AGENTCORE_HTTP_PROTOCOL as La, applyAuthorizerOverlay as Li, resolveBucketDeploymentObjectKey as Ln, parseSseForJsonRpc as Lr, resolveWebFunctionRuntime as Lt, DEFAULT_TERMINATE_HOOK_TIMEOUT_MS as M, discoverRoutes as Ma, buildCorsConfigFromCloudFrontChain as Mi, createLocalFileKvsDataSource as Mn, a2aInvokeOnce as Mr, waitForWebFunctionReady as Mt, LocalMicrovm as N, pickRefLogicalId as Na, isFunctionUrlOacFronted as Ni, createUnboundCloudFrontModule as Nn, MCP_CONTAINER_PORT as Nr, watchContainerExit as Nt, createLocalStartMicrovmCommand as O, discoverWebSocketApisOrThrow as Oa, invokeTokenAuthorizer as Oi, runViewerRequest as On, bridgeAgentCoreWs as Or, containerFailure as Ot, buildMicrovmImage as P, resolveLambdaArnIntrinsic as Pa, matchPreflight as Pi, bucketDeploymentSourceObjectKeys as Pn, MCP_PATH as Pr, WEB_FUNCTION_RUNTIMES as Pt, pollBuildHook as Q, withoutKeys as Qa, handleConnectionsRequest as Qi, addEcsAssumeRoleOptions as Qn, createLocalInvokeCommand as Qr, resolveDeployedOriginBucket as Qt, setContainerPaused as R, AGENTCORE_MCP_PROTOCOL as Ra, buildHttpApiV2Event as Ri, addAlbSpecificOptions as Rn, AGENTCORE_SIGV4_SERVICE as Rr, supportedWebFunctionRuntimes as Rt, StudioEventBus as S, resolveWatchConfig as Sa, verifyJwtAuthorizer as Si, WEB_FUNCTION_ENDPOINT_TYPE as Sn, SOFT_RELOAD_COMPLETION_LOG_SUFFIX as Sr, normalizeKvsFileKeys as St, formatTargetListing as T, listTargets as Ta, computeRequestIdentityHash as Ti, WebFunctionResolutionError as Tn, attachContainerLogStreamer as Tr, resolveCloudFrontTarget as Tt, rewriteUpgradeResponseHead as U, DynamicReferenceResolutionError as Ua, tryParseStatus as Ui, isApplicationLoadBalancer as Un, waitForAgentCorePing as Ur, buildWebFunctionLambdaView as Ut, MicrovmStateError as V, pickAgentCoreCandidateStack as Va, pickResponseTemplate as Vi, parseLbPortOverrides as Vn, invokeAgentCore as Vr, resolveWebFunctionArtifact as Vt, selectTargetPort as W, DynamicReferenceResolver as Wa, VtlEvaluationError as Wi, resolveAlbFrontDoor as Wn, downloadAndExtractS3Bundle as Wr, finalizeWebFunctionEnv as Wt, callRuntimeHook as X, parseDynamicReference as Xa, ConnectionRegistry as Xi, MAX_TASKS_SUBNET_RANGE_CAP as Xn, classifySourceChange as Xr, createDeployedKvsDataSource as Xt, MicrovmHookError as Y, keysOverriddenBy as Ya, bufferToBody as Yi, createLocalRunTaskCommand as Yn, toCmdArgv as Yr, resolveKvsModulesForDistribution as Yt, generateMicrovmId as Z, resolveDynamicReferencesInEnv as Za, buildMgmtEndpointEnvUrl as Zi, addCommonEcsServiceOptions as Zn, addInvokeSpecificOptions as Zr, resolveDeployedKvsArnByName as Zt, filterStudioTargetGroups as _, resolveCfnRegion as _a, defaultCredentialsLoader as _i, pickKvsLogicalIdFromArn as _n, isLocalCdkAssetImage as _r, attachAgentCoreWsBridge as _t, createLocalStudioCommand as a, resolveRuntimeImage as aa, attachStageContext as ai, serveLambdaUrlOrigin as an, resolveSharedSidecarCredentials as ar, disposeMicrovmCodeArtifact as at, renderStudioHtml as b, collectSsmParameterRefs as ba, createJwksCache as bi, pickWebFunctionEndpointLogicalIdFromOrigin as bn, CloudMapRegistry as br, addStartCloudFrontSpecificOptions as bt, startStudioProxy as c, substituteAgainstState as ca, resolveEnvVars$1 as ci, buildEdgeRequestEvent as cn, buildImageOverrideTag as cr, resolveMicrovmImageTarget as ct, createStudioDispatcher as d, substituteEnvVarsFromStateAsync as da, filterRoutesByApiIdentifiers as di, httpHeadersToEdge as dn, mergeForService as dr, createLocalStartWebFunctionCommand as dt, buildConnectEvent as ea, createLocalStartApiCommand as ei, createS3OriginReader as en, awsEndpointOptions as eo, buildEcsImageResolutionContext$1 as er, runHookBody as et, filterStudioCustomResources as f, LocalStateSourceError as fa, groupRoutesByServer as fi, CLOUDFRONT_DISTRIBUTION_TYPE as fn, parseImageOverrideFlags as fr, addStartAgentCoreSpecificOptions as ft, annotatePinnedEcsTargets as g, resolveCfnFallbackRegion as ga, resolveServiceIntegrationParameters as gi, pickFunctionUrlLogicalIdFromOrigin as gn, imageOverrideKeyAliases as gr, startAgentCoreHttpServer as gt, annotateEcsTaskPinnedTargets as h, rejectExplicitCfnStackWithMultipleStacks as ha, resolveSelectionExpression as hi, isCloudFrontDistribution as hn, describePinnedImageUri as hr, selectServeInboundAuth as ht, coerceStopRequest as i, resolveRuntimeFileExtension as ia, createFileWatcher as ii, serveFromStaticOrigin as in, resolveEcsAssumeRoleOption as ir, MicrovmResolutionError as it, readRunHookPayload as j, webSocketApiMatchesIdentifier as ja, buildCorsConfigByApiId as ji, createCloudFrontModule as jn, A2A_PATH as jr, startWebFunctionContainer as jt, finalizeMicrovmEnv as k, filterWebSocketApisByIdentifiers as ka, attachAuthorizers as ki, runViewerResponse as kn, invokeAgentCoreWs as kr, planWebFunctionContainer as kt, relayServeRequest as l, substituteAgainstStateAsync as la, availableApiIdentifiers as li, buildEdgeResponseEvent as ln, canonicalizeImageOverrideKeys as lr, s3KeyOfUri as lt, annotateAlbPinnedBackingServices as m, isCfnFlagPresent as ma, startApiServer as mi, extractKvsAssociations as mn, runImageOverrideBuilds as mr, buildAgentCoreServeAuthCheck as mt, coerceRunRequest as n, buildMessageEvent as na, resolveApiTargetSubset as ni, startCloudFrontServer as nn, parseMaxTasks as nr, MICROVM_DEFAULT_INGRESS_PORT as nt, resolveServeBaseUrl as o, EcsTaskResolutionError as oa, buildStageMap as oi, applyEdgeRequestResult as on, runEcsServiceEmulator as or, readMicrovmImageConfig as ot, isCustomResourceLambdaTarget as p, createLocalStateProvider as pa, readMtlsMaterialsFromDisk as pi, describeS3OriginDomain as pn, resolveImageOverrides as pr, createLocalStartAgentCoreCommand as pt, MAX_RUN_HOOK_PAYLOAD_BYTES as q, firstUsableRegion as qa, probeHostGatewaySupport as qi, serviceStrategy as qn, computeCodeImageTag as qr, webFunctionFidelityWarnings as qt, coerceServeRequest as r, resolveRuntimeCodeMountPath as ra, createAuthorizerCache as ri, resolveErrorResponseCandidates as rn, parseRestartPolicy as rr, MICROVM_IMAGE_TYPE as rt, createStudioServeManager as s, assertEcsTaskImagesResolvable as sa, materializeLayerFromArn as si, applyEdgeResponseResult as sn, ImageOverrideError as sr, resolveMicrovmCodeArtifact as st, addStudioSpecificOptions as t, buildDisconnectEvent as ta, createWatchPredicates as ti, matchBehavior as tn, ecsClusterOption as tr, waitForAppAnswer as tt, reinvoke as u, substituteEnvVarsFromState as ua, filterRoutesByApiIdentifier as ui, edgeHeadersToHttp as un, enforceImageOverrideOrphans as ur, addStartWebFunctionSpecificOptions as ut, startStudioServer as v, resolveCfnStackName as va, buildCognitoJwksUrl as vi, pickLambdaEdgeFunctionLogicalId as vn, listPinnedTargets as vr, startAgentCoreWsBridge as vt, createLocalListCommand as w, countTargets as wa, buildMethodArn as wi, WEB_FUNCTION_TYPE as wn, getContainerNetworkIp as wr, parseOriginOverrides as wt, createStudioStore as x, resolveSsmParameters as xa, verifyCognitoJwt as xi, resolveCloudFrontDistribution as xn, DEFAULT_SHADOW_READY_TIMEOUT_MS as xr, createLocalStartCloudFrontCommand as xt, toStudioTargetGroups as y, CfnLocalStateProvider as ya, buildJwksUrlFromIssuer as yi, pickTargetFunctionLogicalId as yn, buildCloudMapIndex as yr, LocalStartCloudFrontError as yt, MICROVM_CONTROL_PATH as z, AGENTCORE_RUNTIME_TYPE as za, buildRestV1Event as zi, albStrategy as zn, signAgentCoreInvocation as zr, disposeWebFunctionArtifact as zt };
|
|
31776
|
-
//# sourceMappingURL=local-studio-
|
|
31942
|
+
//# sourceMappingURL=local-studio-LTgy7a7a.js.map
|