cdk-local 0.162.1 → 0.163.1
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/README.md +1 -1
- package/dist/cli.js +2 -2
- package/dist/{docker-runner-CLlVjU7l.js → docker-runner-DzPTb4Ai.js} +48 -22
- package/dist/{docker-runner-CLlVjU7l.js.map → docker-runner-DzPTb4Ai.js.map} +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/internal.d.ts +86 -70
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +4 -4
- package/dist/{local-studio-BVVcAPV8.d.ts → local-studio-BsnTY1vH.d.ts} +54 -4
- package/dist/local-studio-BsnTY1vH.d.ts.map +1 -0
- package/dist/{local-studio-D8eIrFzx.js → local-studio-CFf6tO1e.js} +477 -316
- package/dist/local-studio-CFf6tO1e.js.map +1 -0
- package/dist/{workload-identity-ITM3p2Ed.js → workload-identity-D5zkhVcF.js} +708 -16
- package/dist/workload-identity-D5zkhVcF.js.map +1 -0
- package/package.json +1 -1
- package/dist/local-studio-BVVcAPV8.d.ts.map +0 -1
- package/dist/local-studio-D8eIrFzx.js.map +0 -1
- package/dist/workload-identity-ITM3p2Ed.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { a as displayIdent, c as getEmbedConfig, i as STACK_REF_MAX_CODE_POINTS, o as displayStackName, s as displayToolOutput, t as getLogger, u as setEmbedConfig } from "./logger-Co5XVwco.js";
|
|
2
|
-
import {
|
|
2
|
+
import { $ as buildProxyClientConfig, C as effectiveLoopbackPorts, F as resolveHostDefaultCredentials, G as createMixedModeStateProvider, Q as awsEndpointOverrideClientConfig, at as isWildcardHostname, b as awsEmulatorEnvName, ct as hostFromAuthority, d as workloadStsClientConfig, it as isLoopbackHostname, l as warnWorkloadCredentialsStripped, n as accountLookupStsClientConfig, nt as proxyAwareFetch, ot as formatAuthority, r as applyWorkloadEnvCredentials, st as formatHostForAuthority, u as workloadClientConfig, v as activateWorkloadAwsWiring, w as getActiveWorkloadAwsWiring, y as applyWorkloadAwsWiringToEnv } from "./workload-identity-D5zkhVcF.js";
|
|
3
3
|
import { c as clampErrorName, d as flattenToOneLine, f as isAwsServiceException, l as describeAwsFailureForWarn, m as stringifyThrown, o as renderAssemblyPathEscape, p as sanitizeServiceExceptionMessage, r as displayUntrustedValue, s as resolveAssemblyPath, t as absoluteAssemblyPathEscape, u as describeCredentialLoadFailure } from "./assembly-path-R96uhMm1.js";
|
|
4
|
-
import { $ as buildStsClientConfig, A as buildDockerImage, B as InteractiveTtyRequiredError, D as isImageInLocalCache, E as warnIfEmulatedPlatform, F as derivePseudoParametersFromRegion, G as withErrorHandling, H as LocalStartServiceError, I as formatStateRemedy, J as applyRoleArnIfSet, K as defineOwnKey, L as substituteImagePlaceholders, M as describeExitWithoutArgv, N as parseEcrRegistryHost, O as parseEcrUri, P as derivePartitionAndUrlSuffix, Q as refusedRoleArnMessage, R as tryResolveImageFnJoin, T as buildContainerImage, U as RouteDiscoveryError, V as LocalInvokeBuildError, W as TargetSelectionCancelledError, X as describeRejectedRoleArn, Y as assumeRoleCredentials, Z as isIamRoleArn, a as describeRefusedSensitiveEnvKeys, c as execEnvForSecrets, d as rememberForwardedPorts, et as resolveProfileCredentials, f as removeContainer, h as streamLogs, i as attachLoopbackForwarder, j as resolveAssetSourcePath, k as pullEcrImage, l as pickFreePort, m as startNamespaceOwnerForwarder, n as SENSITIVE_ENV_KEYS, p as runDetached, q as AssumeRoleFailure, r as appendEnvFlags, s as ensureDockerAvailable, t as DockerRunnerError, u as pullImage, w as architectureToPlatform, z as CdkLocalError } from "./docker-runner-
|
|
4
|
+
import { $ as buildStsClientConfig, A as buildDockerImage, B as InteractiveTtyRequiredError, D as isImageInLocalCache, E as warnIfEmulatedPlatform, F as derivePseudoParametersFromRegion, G as withErrorHandling, H as LocalStartServiceError, I as formatStateRemedy, J as applyRoleArnIfSet, K as defineOwnKey, L as substituteImagePlaceholders, M as describeExitWithoutArgv, N as parseEcrRegistryHost, O as parseEcrUri, P as derivePartitionAndUrlSuffix, Q as refusedRoleArnMessage, R as tryResolveImageFnJoin, T as buildContainerImage, U as RouteDiscoveryError, V as LocalInvokeBuildError, W as TargetSelectionCancelledError, X as describeRejectedRoleArn, Y as assumeRoleCredentials, Z as isIamRoleArn, a as describeRefusedSensitiveEnvKeys, c as execEnvForSecrets, d as rememberForwardedPorts, et as resolveProfileCredentials, f as removeContainer, h as streamLogs, i as attachLoopbackForwarder, j as resolveAssetSourcePath, k as pullEcrImage, l as pickFreePort, m as startNamespaceOwnerForwarder, n as SENSITIVE_ENV_KEYS, p as runDetached, q as AssumeRoleFailure, r as appendEnvFlags, s as ensureDockerAvailable, t as DockerRunnerError, u as pullImage, w as architectureToPlatform, z as CdkLocalError } from "./docker-runner-DzPTb4Ai.js";
|
|
5
5
|
import { a as isDockerClientEnvKey, c as runDockerStreaming, i as getDockerCmd, n as finchSecretArgvRefusal, o as isMalformedEnvKey, u as warnFinchArgvExposure } from "./docker-cmd-Cjg3jGYF.js";
|
|
6
6
|
import { chmodSync, cpSync, createWriteStream, existsSync, lstatSync, mkdirSync, mkdtempSync, promises, readFileSync, readdirSync, readlinkSync, realpathSync, rmSync, statSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
7
7
|
import { Command, InvalidArgumentError, Option } from "commander";
|
|
@@ -2983,7 +2983,7 @@ async function resolveSsmParameters(client, refs, label) {
|
|
|
2983
2983
|
//#endregion
|
|
2984
2984
|
//#region src/local/cfn-local-state-provider.ts
|
|
2985
2985
|
var CfnLocalStateProvider = class {
|
|
2986
|
-
label
|
|
2986
|
+
label;
|
|
2987
2987
|
cfnStackName;
|
|
2988
2988
|
region;
|
|
2989
2989
|
client;
|
|
@@ -2991,18 +2991,25 @@ var CfnLocalStateProvider = class {
|
|
|
2991
2991
|
ssmClient;
|
|
2992
2992
|
agentCoreControlClient;
|
|
2993
2993
|
clientOptions;
|
|
2994
|
+
endpointOverride;
|
|
2994
2995
|
disposed = false;
|
|
2995
2996
|
lastLoadError;
|
|
2996
2997
|
constructor(opts) {
|
|
2997
2998
|
this.cfnStackName = opts.cfnStackName;
|
|
2998
2999
|
this.region = opts.region;
|
|
2999
3000
|
this.clientOptions = { region: opts.region };
|
|
3000
|
-
|
|
3001
|
+
this.endpointOverride = opts.endpointOverride;
|
|
3002
|
+
this.label = opts.label ?? "--from-cfn-stack";
|
|
3003
|
+
if (opts.profile !== void 0 && !opts.endpointOverride) this.clientOptions.profile = opts.profile;
|
|
3004
|
+
}
|
|
3005
|
+
overrideClientConfig() {
|
|
3006
|
+
return this.endpointOverride ? awsEndpointOverrideClientConfig(this.endpointOverride) : {};
|
|
3001
3007
|
}
|
|
3002
3008
|
getClient() {
|
|
3003
3009
|
if (this.disposed) throw new Error("CfnLocalStateProvider used after dispose()");
|
|
3004
3010
|
if (!this.client) this.client = new CloudFormationClient({
|
|
3005
3011
|
...workloadClientConfig({ profile: this.clientOptions.profile }),
|
|
3012
|
+
...this.overrideClientConfig(),
|
|
3006
3013
|
region: this.region,
|
|
3007
3014
|
...this.clientOptions.profile !== void 0 && { profile: this.clientOptions.profile }
|
|
3008
3015
|
});
|
|
@@ -3012,6 +3019,7 @@ var CfnLocalStateProvider = class {
|
|
|
3012
3019
|
if (this.disposed) throw new Error("CfnLocalStateProvider used after dispose()");
|
|
3013
3020
|
if (!this.lambdaClient) this.lambdaClient = new LambdaClient({
|
|
3014
3021
|
...workloadClientConfig({ profile: this.clientOptions.profile }),
|
|
3022
|
+
...this.overrideClientConfig(),
|
|
3015
3023
|
region: this.region,
|
|
3016
3024
|
...this.clientOptions.profile !== void 0 && { profile: this.clientOptions.profile }
|
|
3017
3025
|
});
|
|
@@ -3021,6 +3029,7 @@ var CfnLocalStateProvider = class {
|
|
|
3021
3029
|
if (this.disposed) throw new Error("CfnLocalStateProvider used after dispose()");
|
|
3022
3030
|
if (!this.agentCoreControlClient) this.agentCoreControlClient = new BedrockAgentCoreControlClient({
|
|
3023
3031
|
...workloadClientConfig({ profile: this.clientOptions.profile }),
|
|
3032
|
+
...this.overrideClientConfig(),
|
|
3024
3033
|
region: this.region,
|
|
3025
3034
|
...this.clientOptions.profile !== void 0 && { profile: this.clientOptions.profile }
|
|
3026
3035
|
});
|
|
@@ -3030,6 +3039,7 @@ var CfnLocalStateProvider = class {
|
|
|
3030
3039
|
if (this.disposed) throw new Error("CfnLocalStateProvider used after dispose()");
|
|
3031
3040
|
if (!this.ssmClient) this.ssmClient = new SSMClient({
|
|
3032
3041
|
...workloadClientConfig({ profile: this.clientOptions.profile }),
|
|
3042
|
+
...this.overrideClientConfig(),
|
|
3033
3043
|
region: this.region,
|
|
3034
3044
|
...this.clientOptions.profile !== void 0 && { profile: this.clientOptions.profile }
|
|
3035
3045
|
});
|
|
@@ -3292,7 +3302,7 @@ function rejectExplicitCfnStackWithMultipleStacks(options, routedStackCount) {
|
|
|
3292
3302
|
if (typeof options.fromCfnStack !== "string") return;
|
|
3293
3303
|
throw new LocalStateSourceError(`--from-cfn-stack <name> cannot be used with multiple routed stacks (got ${routedStackCount}). An explicit CFn stack name applies to one stack only and would silently mismap logical IDs across siblings. Use bare --from-cfn-stack (each stack uses its own name as the CFn stack name) or run one ${getEmbedConfig().binaryName} invocation per stack.`);
|
|
3294
3304
|
}
|
|
3295
|
-
function createLocalStateProvider(options, stackName, synthRegion, extraStateProviders) {
|
|
3305
|
+
function createLocalStateProvider(options, stackName, synthRegion, extraStateProviders, behavior = {}) {
|
|
3296
3306
|
const cfnStackOpt = options.fromCfnStack;
|
|
3297
3307
|
const cfnFlagPresent = isCfnFlagPresent(options);
|
|
3298
3308
|
const activeExtras = [];
|
|
@@ -3302,11 +3312,27 @@ function createLocalStateProvider(options, stackName, synthRegion, extraStatePro
|
|
|
3302
3312
|
if (cfnFlagPresent && activeExtras.length > 0) throw new LocalStateSourceError(`--from-cfn-stack is mutually exclusive with ${activeExtras.map(toFlagName).join(", ")}. Pick one state source.`);
|
|
3303
3313
|
if (activeExtras.length > 1) throw new LocalStateSourceError(`state-source flags are mutually exclusive: ${activeExtras.map(toFlagName).join(", ")}. Pick one.`);
|
|
3304
3314
|
if (cfnStackOpt === "") throw new LocalStateSourceError("--from-cfn-stack requires a non-empty stack name when an explicit value is provided. Drop the value to use the resolved stack name, or pass --from-cfn-stack <name>.");
|
|
3305
|
-
if (cfnFlagPresent)
|
|
3306
|
-
cfnStackName
|
|
3307
|
-
region
|
|
3308
|
-
|
|
3309
|
-
|
|
3315
|
+
if (cfnFlagPresent) {
|
|
3316
|
+
const cfnStackName = resolveCfnStackName(cfnStackOpt, stackName);
|
|
3317
|
+
const region = resolveCfnRegion(options, synthRegion);
|
|
3318
|
+
const real = new CfnLocalStateProvider({
|
|
3319
|
+
cfnStackName,
|
|
3320
|
+
region,
|
|
3321
|
+
...options.profile !== void 0 && { profile: options.profile }
|
|
3322
|
+
});
|
|
3323
|
+
const mixed = behavior.realAwsOnly ? void 0 : getActiveWorkloadAwsWiring()?.mixed;
|
|
3324
|
+
if (!mixed) return real;
|
|
3325
|
+
return createMixedModeStateProvider({
|
|
3326
|
+
real,
|
|
3327
|
+
emulator: new CfnLocalStateProvider({
|
|
3328
|
+
cfnStackName,
|
|
3329
|
+
region,
|
|
3330
|
+
endpointOverride: mixed.emulatorClientOverride,
|
|
3331
|
+
label: "--from-cfn-stack (AWS Emulator)"
|
|
3332
|
+
}),
|
|
3333
|
+
emulatedServices: mixed.services
|
|
3334
|
+
});
|
|
3335
|
+
}
|
|
3310
3336
|
if (activeExtras.length === 1) {
|
|
3311
3337
|
const factory = extraStateProviders[activeExtras[0]];
|
|
3312
3338
|
return factory(options);
|
|
@@ -10478,6 +10504,97 @@ function createFileWatcher(options) {
|
|
|
10478
10504
|
} };
|
|
10479
10505
|
}
|
|
10480
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
|
+
|
|
10481
10598
|
//#endregion
|
|
10482
10599
|
//#region src/local/authorizer-cache.ts
|
|
10483
10600
|
function createAuthorizerCache(opts = {}) {
|
|
@@ -10871,7 +10988,7 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
|
|
|
10871
10988
|
}
|
|
10872
10989
|
process.stdout.write("^C to stop and clean up containers.\n");
|
|
10873
10990
|
let watcher;
|
|
10874
|
-
let
|
|
10991
|
+
let reloadQueue;
|
|
10875
10992
|
if (options.watch) {
|
|
10876
10993
|
const watchRoot = process.cwd();
|
|
10877
10994
|
const { ignored, shouldTrigger, excludePatterns } = createWatchPredicates({
|
|
@@ -10879,105 +10996,97 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
|
|
|
10879
10996
|
output: options.output,
|
|
10880
10997
|
watchConfig: resolveWatchConfig()
|
|
10881
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;
|
|
10882
11010
|
watcher = createFileWatcher({
|
|
10883
11011
|
paths: [watchRoot],
|
|
10884
11012
|
ignored,
|
|
10885
11013
|
shouldTrigger,
|
|
10886
|
-
onChange: () => {
|
|
11014
|
+
onChange: (changedPaths) => {
|
|
10887
11015
|
logger.info("Detected source change; reloading...");
|
|
10888
|
-
|
|
10889
|
-
synthesizeAndBuild,
|
|
10890
|
-
servers,
|
|
10891
|
-
buildPool,
|
|
10892
|
-
logger
|
|
10893
|
-
})).catch(() => void 0);
|
|
11016
|
+
queue.schedule(changedPaths);
|
|
10894
11017
|
}
|
|
10895
11018
|
});
|
|
10896
11019
|
logger.info(`Watching ${watchRoot} for source changes (excluding ${excludePatterns.join(", ")}).`);
|
|
10897
11020
|
}
|
|
10898
|
-
|
|
10899
|
-
|
|
10900
|
-
|
|
10901
|
-
|
|
10902
|
-
|
|
10903
|
-
|
|
10904
|
-
|
|
10905
|
-
await
|
|
10906
|
-
|
|
10907
|
-
|
|
10908
|
-
|
|
10909
|
-
|
|
10910
|
-
|
|
10911
|
-
|
|
10912
|
-
|
|
10913
|
-
|
|
10914
|
-
|
|
10915
|
-
|
|
10916
|
-
|
|
10917
|
-
|
|
10918
|
-
|
|
10919
|
-
|
|
10920
|
-
|
|
10921
|
-
|
|
10922
|
-
|
|
10923
|
-
|
|
10924
|
-
|
|
10925
|
-
|
|
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
|
+
});
|
|
10926
11068
|
} catch (err) {
|
|
10927
|
-
logger.warn(`
|
|
11069
|
+
logger.warn(`Failed to remove inline-code tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
10928
11070
|
}
|
|
10929
|
-
|
|
10930
|
-
|
|
10931
|
-
|
|
10932
|
-
|
|
11071
|
+
for (const dir of layerTmpDirs) try {
|
|
11072
|
+
rmSync(dir, {
|
|
11073
|
+
recursive: true,
|
|
11074
|
+
force: true
|
|
11075
|
+
});
|
|
10933
11076
|
} catch (err) {
|
|
10934
|
-
logger.warn(`
|
|
11077
|
+
logger.warn(`Failed to remove merged-layers tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
10935
11078
|
}
|
|
10936
|
-
|
|
10937
|
-
|
|
10938
|
-
try {
|
|
10939
|
-
await ws.server.getServerState().pool.dispose();
|
|
11079
|
+
if (profileCredsFile) try {
|
|
11080
|
+
await profileCredsFile.dispose();
|
|
10940
11081
|
} catch (err) {
|
|
10941
|
-
logger.warn(`
|
|
11082
|
+
logger.warn(`Failed to remove profile credentials tmpdir ${profileCredsFile.hostPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
10942
11083
|
}
|
|
10943
|
-
})
|
|
10944
|
-
|
|
10945
|
-
|
|
10946
|
-
|
|
10947
|
-
|
|
10948
|
-
});
|
|
10949
|
-
} catch (err) {
|
|
10950
|
-
logger.warn(`Failed to remove inline-code tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
10951
|
-
}
|
|
10952
|
-
for (const dir of layerTmpDirs) try {
|
|
10953
|
-
rmSync(dir, {
|
|
10954
|
-
recursive: true,
|
|
10955
|
-
force: true
|
|
10956
|
-
});
|
|
10957
|
-
} catch (err) {
|
|
10958
|
-
logger.warn(`Failed to remove merged-layers tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
10959
|
-
}
|
|
10960
|
-
if (profileCredsFile) try {
|
|
10961
|
-
await profileCredsFile.dispose();
|
|
10962
|
-
} catch (err) {
|
|
10963
|
-
logger.warn(`Failed to remove profile credentials tmpdir ${profileCredsFile.hostPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
10964
|
-
}
|
|
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)
|
|
10965
11089
|
});
|
|
10966
|
-
const shutdown = async (signal, exitCode) => {
|
|
10967
|
-
if (shutdownStarted) {
|
|
10968
|
-
if (!forceExitArmed) {
|
|
10969
|
-
forceExitArmed = true;
|
|
10970
|
-
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.`);
|
|
10971
|
-
process.exit(130);
|
|
10972
|
-
}
|
|
10973
|
-
return;
|
|
10974
|
-
}
|
|
10975
|
-
shutdownStarted = true;
|
|
10976
|
-
firstSignal = signal;
|
|
10977
|
-
firstExitCode = exitCode;
|
|
10978
|
-
await runCleanup();
|
|
10979
|
-
process.exit(firstExitCode);
|
|
10980
|
-
};
|
|
10981
11090
|
process.on("SIGINT", () => {
|
|
10982
11091
|
shutdown("SIGINT", 130);
|
|
10983
11092
|
});
|
|
@@ -11695,7 +11804,7 @@ function warnSsrfRiskyIntegrations(routes, logger) {
|
|
|
11695
11804
|
}
|
|
11696
11805
|
}
|
|
11697
11806
|
async function reloadAllServers(args) {
|
|
11698
|
-
const { synthesizeAndBuild, servers, buildPool, logger } = args;
|
|
11807
|
+
const { synthesizeAndBuild, servers, buildPool, logger, signal } = args;
|
|
11699
11808
|
let material;
|
|
11700
11809
|
try {
|
|
11701
11810
|
material = await synthesizeAndBuild();
|
|
@@ -11703,6 +11812,10 @@ async function reloadAllServers(args) {
|
|
|
11703
11812
|
logger.warn(`cdk synth failed during reload; keeping previous version. (${err instanceof Error ? err.message : String(err)})`);
|
|
11704
11813
|
return;
|
|
11705
11814
|
}
|
|
11815
|
+
if (signal?.aborted) {
|
|
11816
|
+
logger.info("Reload cancelled: shutting down.");
|
|
11817
|
+
return;
|
|
11818
|
+
}
|
|
11706
11819
|
const newGroups = groupRoutesByServer(material.routes);
|
|
11707
11820
|
const newByKey = new Map(newGroups.map((g) => [g.serverKey, g]));
|
|
11708
11821
|
const oldKeys = new Set(servers.map((s) => s.group.serverKey));
|
|
@@ -13397,9 +13510,12 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
|
|
|
13397
13510
|
let containerId;
|
|
13398
13511
|
let stopLogs;
|
|
13399
13512
|
let sigintHandler;
|
|
13513
|
+
let sigtermHandler;
|
|
13400
13514
|
let profileCredsFile;
|
|
13401
13515
|
let stateProvider;
|
|
13516
|
+
let stopWatch;
|
|
13402
13517
|
const cleanup = singleFlight(async () => {
|
|
13518
|
+
if (stopWatch) await stopWatch();
|
|
13403
13519
|
if (stateProvider) try {
|
|
13404
13520
|
stateProvider.dispose();
|
|
13405
13521
|
} catch (err) {
|
|
@@ -13504,10 +13620,17 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
|
|
|
13504
13620
|
...sensitiveEnvKeys.size > 0 && { sensitiveEnvKeys }
|
|
13505
13621
|
});
|
|
13506
13622
|
stopLogs = streamLogs(containerId);
|
|
13507
|
-
|
|
13508
|
-
cleanup
|
|
13509
|
-
|
|
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);
|
|
13510
13632
|
process.on("SIGINT", sigintHandler);
|
|
13633
|
+
process.on("SIGTERM", sigtermHandler);
|
|
13511
13634
|
if (isMcp && mcpRequest) {
|
|
13512
13635
|
logger.info(`MCP request: ${mcpRequest.method}`);
|
|
13513
13636
|
const mcp = await mcpInvokeOnce(containerHost, hostPort, mcpRequest, { requestTimeoutMs: options.timeout });
|
|
@@ -13534,7 +13657,10 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
|
|
|
13534
13657
|
synthOpts,
|
|
13535
13658
|
stacks,
|
|
13536
13659
|
...authorization && { authorization },
|
|
13537
|
-
|
|
13660
|
+
registerStop: (stop) => {
|
|
13661
|
+
stopWatch = stop;
|
|
13662
|
+
},
|
|
13663
|
+
rebuild: async (signal) => {
|
|
13538
13664
|
if (stopLogs) {
|
|
13539
13665
|
try {
|
|
13540
13666
|
stopLogs();
|
|
@@ -13555,6 +13681,7 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
|
|
|
13555
13681
|
await resolveFromS3BucketIntrinsic(newResolved, stateProvider, newLoaded, newImageContext);
|
|
13556
13682
|
const newImage = await resolveAgentCoreImage(newResolved, options, newLoaded, stateProvider);
|
|
13557
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");
|
|
13558
13685
|
const newHostPort = await pickFreePort();
|
|
13559
13686
|
const newName = `${getEmbedConfig().resourceNamePrefix}-agentcore-${process.pid}-${Math.random().toString(36).slice(2, 8)}`;
|
|
13560
13687
|
logger.info(`Reload: starting agent container (image=${newImage}, port=${newHostPort} -> 8080)...`);
|
|
@@ -13611,8 +13738,9 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
|
|
|
13611
13738
|
emitResult(result);
|
|
13612
13739
|
}
|
|
13613
13740
|
} finally {
|
|
13614
|
-
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
13615
13741
|
await cleanup();
|
|
13742
|
+
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
13743
|
+
if (sigtermHandler) process.off("SIGTERM", sigtermHandler);
|
|
13616
13744
|
}
|
|
13617
13745
|
}
|
|
13618
13746
|
async function resolveInboundAuthorization(resolved, options) {
|
|
@@ -14164,7 +14292,7 @@ async function runAgentCoreWatchLoop(args) {
|
|
|
14164
14292
|
const waitForPing = args.__waitForPing ?? waitForAgentCorePing;
|
|
14165
14293
|
let currentHostPort = args.hostPort;
|
|
14166
14294
|
let currentStacks = args.stacks;
|
|
14167
|
-
let
|
|
14295
|
+
let reloadQueue;
|
|
14168
14296
|
let currentAbort;
|
|
14169
14297
|
let pendingReload = false;
|
|
14170
14298
|
let reloadFailed = false;
|
|
@@ -14185,8 +14313,8 @@ async function runAgentCoreWatchLoop(args) {
|
|
|
14185
14313
|
});
|
|
14186
14314
|
const cdkOutDir = args.options.output;
|
|
14187
14315
|
const assetLoader = new AssetManifestLoader();
|
|
14188
|
-
|
|
14189
|
-
|
|
14316
|
+
reloadQueue = createReloadQueue({
|
|
14317
|
+
run: async (changedPaths, signal) => {
|
|
14190
14318
|
let verdict = {
|
|
14191
14319
|
kind: "rebuild",
|
|
14192
14320
|
reason: "classifier not consulted"
|
|
@@ -14221,6 +14349,7 @@ async function runAgentCoreWatchLoop(args) {
|
|
|
14221
14349
|
reason: "classifier context unavailable; falling back to rebuild"
|
|
14222
14350
|
};
|
|
14223
14351
|
}
|
|
14352
|
+
if (signal.aborted) return;
|
|
14224
14353
|
pendingReload = true;
|
|
14225
14354
|
logger.warn("cdkl invoke-agentcore --watch: source change detected; closing the active /ws socket so the client can reconnect to the rebuilt container.");
|
|
14226
14355
|
currentAbort?.abort();
|
|
@@ -14230,20 +14359,32 @@ async function runAgentCoreWatchLoop(args) {
|
|
|
14230
14359
|
currentStacks = newStacks;
|
|
14231
14360
|
logger.info("Reload: soft-reloaded the agent container (docker cp + docker restart; container ID + host port preserved).");
|
|
14232
14361
|
} else {
|
|
14233
|
-
const { containerId: _newId, hostPort: newHostPort, stacks: newStacks } = await args.rebuild();
|
|
14362
|
+
const { containerId: _newId, hostPort: newHostPort, stacks: newStacks } = await args.rebuild(signal);
|
|
14234
14363
|
currentHostPort = newHostPort;
|
|
14235
14364
|
currentStacks = newStacks;
|
|
14236
14365
|
logger.info(`Reload: rebuilt the agent container.`);
|
|
14237
14366
|
}
|
|
14238
14367
|
} catch (err) {
|
|
14368
|
+
if (signal.aborted) {
|
|
14369
|
+
logger.info("Reload cancelled: shutting down.");
|
|
14370
|
+
reloadFailed = true;
|
|
14371
|
+
currentAbort?.abort();
|
|
14372
|
+
return;
|
|
14373
|
+
}
|
|
14239
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.`);
|
|
14240
14375
|
reloadFailed = true;
|
|
14241
14376
|
currentAbort?.abort();
|
|
14242
14377
|
}
|
|
14243
|
-
}
|
|
14244
|
-
|
|
14245
|
-
});
|
|
14378
|
+
},
|
|
14379
|
+
onError: (err) => logger.error(`Reload chain threw: ${err instanceof Error ? err.message : String(err)}`)
|
|
14246
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
|
+
}));
|
|
14247
14388
|
try {
|
|
14248
14389
|
let firstIteration = true;
|
|
14249
14390
|
while (true) {
|
|
@@ -14272,17 +14413,17 @@ async function runAgentCoreWatchLoop(args) {
|
|
|
14272
14413
|
currentAbort = void 0;
|
|
14273
14414
|
}
|
|
14274
14415
|
if (!pendingReload) {
|
|
14275
|
-
await
|
|
14416
|
+
await queue.idle();
|
|
14276
14417
|
if (!pendingReload) break;
|
|
14277
14418
|
}
|
|
14278
|
-
await
|
|
14419
|
+
await queue.idle();
|
|
14279
14420
|
}
|
|
14280
14421
|
} finally {
|
|
14281
|
-
|
|
14282
|
-
|
|
14283
|
-
|
|
14284
|
-
logger.warn(`Watcher close failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
14285
|
-
}
|
|
14422
|
+
await stopWatchReloads({
|
|
14423
|
+
watcher,
|
|
14424
|
+
queue,
|
|
14425
|
+
onWatcherCloseError: (err) => logger.warn(`Watcher close failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
14426
|
+
});
|
|
14286
14427
|
}
|
|
14287
14428
|
}
|
|
14288
14429
|
const execFileAsync$6 = promisify(execFile);
|
|
@@ -16461,10 +16602,10 @@ const defaultDockerStartImpl = async (containerId, opts = {}) => {
|
|
|
16461
16602
|
const { getDockerCmd } = await import("./docker-cmd-Cjg3jGYF.js").then((n) => n.t);
|
|
16462
16603
|
await promisify(execFile)(getDockerCmd(), ["start", containerId]);
|
|
16463
16604
|
if (opts.joinedForwarder) return;
|
|
16464
|
-
const { getActiveWorkloadAwsWiring } = await import("./workload-identity-
|
|
16605
|
+
const { getActiveWorkloadAwsWiring } = await import("./workload-identity-D5zkhVcF.js").then((n) => n.R);
|
|
16465
16606
|
const wiring = getActiveWorkloadAwsWiring();
|
|
16466
16607
|
if (wiring) {
|
|
16467
|
-
const { attachLoopbackForwarder } = await import("./docker-runner-
|
|
16608
|
+
const { attachLoopbackForwarder } = await import("./docker-runner-DzPTb4Ai.js").then((n) => n.o);
|
|
16468
16609
|
await attachLoopbackForwarder(containerId, wiring);
|
|
16469
16610
|
}
|
|
16470
16611
|
};
|
|
@@ -18985,24 +19126,21 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
|
|
|
18985
19126
|
setShadowReadyTimeoutMs(resolveShadowReadyTimeoutMs(options, getEmbedConfig().envPrefix));
|
|
18986
19127
|
let perTarget = [];
|
|
18987
19128
|
let sigintHandler;
|
|
18988
|
-
let
|
|
19129
|
+
let sigtermHandler;
|
|
18989
19130
|
let sharedNetwork;
|
|
18990
19131
|
let profileCredsFile;
|
|
18991
19132
|
let frontDoorServers = [];
|
|
18992
19133
|
let frontDoorByService = /* @__PURE__ */ new Map();
|
|
18993
19134
|
let frontDoorLambdaRunners = [];
|
|
18994
19135
|
let watcher;
|
|
18995
|
-
let
|
|
19136
|
+
let reloadQueue;
|
|
18996
19137
|
const cleanup = singleFlight(async () => {
|
|
18997
|
-
|
|
18998
|
-
|
|
18999
|
-
|
|
19000
|
-
|
|
19001
|
-
|
|
19002
|
-
|
|
19003
|
-
watcher = void 0;
|
|
19004
|
-
}
|
|
19005
|
-
await reloadChain.catch(() => void 0);
|
|
19138
|
+
await stopWatchReloads({
|
|
19139
|
+
watcher,
|
|
19140
|
+
queue: reloadQueue,
|
|
19141
|
+
onWatcherCloseError: (err) => getLogger().warn(`watcher.close() failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
19142
|
+
});
|
|
19143
|
+
watcher = void 0;
|
|
19006
19144
|
await Promise.allSettled(perTarget.map(async (pt) => {
|
|
19007
19145
|
if (pt.controller) await pt.controller.shutdown();
|
|
19008
19146
|
else {
|
|
@@ -19100,17 +19238,17 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
|
|
|
19100
19238
|
frontDoorByService = built.frontDoorByService;
|
|
19101
19239
|
frontDoorLambdaRunners = built.lambdaRunners;
|
|
19102
19240
|
}
|
|
19103
|
-
|
|
19104
|
-
|
|
19105
|
-
|
|
19106
|
-
|
|
19107
|
-
|
|
19108
|
-
|
|
19109
|
-
|
|
19110
|
-
|
|
19111
|
-
|
|
19241
|
+
const onSignal = createShutdownSignalHandler({
|
|
19242
|
+
cleanup,
|
|
19243
|
+
stoppingMessage: () => "Stopping service(s)...",
|
|
19244
|
+
forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' and 'docker network ls --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
|
|
19245
|
+
info: (m) => logger.info(m),
|
|
19246
|
+
warn: (m) => logger.warn(m)
|
|
19247
|
+
});
|
|
19248
|
+
sigintHandler = () => onSignal("SIGINT", 130);
|
|
19249
|
+
sigtermHandler = () => onSignal("SIGTERM", 130);
|
|
19112
19250
|
process.on("SIGINT", sigintHandler);
|
|
19113
|
-
process.on("SIGTERM",
|
|
19251
|
+
process.on("SIGTERM", sigtermHandler);
|
|
19114
19252
|
const { tags: imageOverrideTags, overrides: imageOverrideMap } = await resolveAndBuildImageOverrides({
|
|
19115
19253
|
perTarget: perTarget.map((pt) => pt.boot.target),
|
|
19116
19254
|
stacks,
|
|
@@ -19144,47 +19282,50 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
|
|
|
19144
19282
|
output: options.output,
|
|
19145
19283
|
watchConfig: resolveWatchConfig()
|
|
19146
19284
|
});
|
|
19285
|
+
reloadQueue = createReloadQueue({
|
|
19286
|
+
run: (changedPaths, signal) => reloadAllServices({
|
|
19287
|
+
perTarget,
|
|
19288
|
+
synthesizer,
|
|
19289
|
+
synthOpts,
|
|
19290
|
+
strategy,
|
|
19291
|
+
resolvedTargets,
|
|
19292
|
+
cloudMapIndexByStack,
|
|
19293
|
+
options,
|
|
19294
|
+
discovery,
|
|
19295
|
+
skipPull,
|
|
19296
|
+
extraStateProviders,
|
|
19297
|
+
profileCredsFile,
|
|
19298
|
+
frontDoorByService,
|
|
19299
|
+
changedPaths,
|
|
19300
|
+
imageOverrideTags,
|
|
19301
|
+
imageOverrideMap,
|
|
19302
|
+
logger,
|
|
19303
|
+
signal
|
|
19304
|
+
}),
|
|
19305
|
+
onError: (err) => logger.error(`reloadAllServices threw: ${err instanceof Error ? err.message : String(err)}`),
|
|
19306
|
+
onCoalesced: (n) => logger.debug(`Reload in progress; ${n} changed path(s) queued for one follow-up reload.`)
|
|
19307
|
+
});
|
|
19308
|
+
const queue = reloadQueue;
|
|
19147
19309
|
watcher = createFileWatcher({
|
|
19148
19310
|
paths: [watchRoot],
|
|
19149
19311
|
ignored,
|
|
19150
19312
|
shouldTrigger,
|
|
19151
19313
|
onChange: (changedPaths) => {
|
|
19152
19314
|
logger.info(`Detected source change (${changedPaths.length} path(s)); reloading service(s)...`);
|
|
19153
|
-
|
|
19154
|
-
perTarget,
|
|
19155
|
-
synthesizer,
|
|
19156
|
-
synthOpts,
|
|
19157
|
-
strategy,
|
|
19158
|
-
resolvedTargets,
|
|
19159
|
-
cloudMapIndexByStack,
|
|
19160
|
-
options,
|
|
19161
|
-
discovery,
|
|
19162
|
-
skipPull,
|
|
19163
|
-
extraStateProviders,
|
|
19164
|
-
profileCredsFile,
|
|
19165
|
-
frontDoorByService,
|
|
19166
|
-
changedPaths,
|
|
19167
|
-
imageOverrideTags,
|
|
19168
|
-
imageOverrideMap,
|
|
19169
|
-
logger
|
|
19170
|
-
})).catch((err) => {
|
|
19171
|
-
logger.error(`reloadAllServices threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
19172
|
-
});
|
|
19315
|
+
queue.schedule(changedPaths);
|
|
19173
19316
|
}
|
|
19174
19317
|
});
|
|
19175
19318
|
logger.info(`Watching ${watchRoot} for source changes (excluding ${excludePatterns.join(", ")}).`);
|
|
19176
19319
|
}
|
|
19177
19320
|
await new Promise(() => {});
|
|
19178
19321
|
} finally {
|
|
19179
|
-
if (sigintHandler) {
|
|
19180
|
-
process.off("SIGINT", sigintHandler);
|
|
19181
|
-
process.off("SIGTERM", sigintHandler);
|
|
19182
|
-
}
|
|
19183
19322
|
await cleanup();
|
|
19323
|
+
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
19324
|
+
if (sigtermHandler) process.off("SIGTERM", sigtermHandler);
|
|
19184
19325
|
}
|
|
19185
19326
|
}
|
|
19186
19327
|
async function reloadAllServices(args) {
|
|
19187
|
-
const { perTarget, synthesizer, synthOpts, strategy, resolvedTargets, cloudMapIndexByStack, options, discovery, skipPull, extraStateProviders, profileCredsFile, frontDoorByService, changedPaths, imageOverrideTags: boottimeImageOverrideTags, imageOverrideMap, logger } = args;
|
|
19328
|
+
const { signal, perTarget, synthesizer, synthOpts, strategy, resolvedTargets, cloudMapIndexByStack, options, discovery, skipPull, extraStateProviders, profileCredsFile, frontDoorByService, changedPaths, imageOverrideTags: boottimeImageOverrideTags, imageOverrideMap, logger } = args;
|
|
19188
19329
|
let stacks;
|
|
19189
19330
|
try {
|
|
19190
19331
|
let checkSelectedStacks;
|
|
@@ -19194,12 +19335,16 @@ async function reloadAllServices(args) {
|
|
|
19194
19335
|
logger.warn(`cdk synth failed during reload; keeping previous version. (${err instanceof Error ? err.message : String(err)})`);
|
|
19195
19336
|
return;
|
|
19196
19337
|
}
|
|
19338
|
+
if (reloadCancelled(signal, logger)) return;
|
|
19197
19339
|
const imageOverrideTags = new Map(boottimeImageOverrideTags);
|
|
19198
|
-
for (const [target, entry] of imageOverrideMap.entries())
|
|
19199
|
-
|
|
19200
|
-
|
|
19201
|
-
|
|
19202
|
-
|
|
19340
|
+
for (const [target, entry] of imageOverrideMap.entries()) {
|
|
19341
|
+
if (reloadCancelled(signal, logger)) return;
|
|
19342
|
+
try {
|
|
19343
|
+
const newTag = (await runImageOverrideBuilds(/* @__PURE__ */ new Map([[target, entry]]))).get(target);
|
|
19344
|
+
if (newTag !== void 0) imageOverrideTags.set(target, newTag);
|
|
19345
|
+
} catch (err) {
|
|
19346
|
+
logger.warn(`Reload of ${displayStackName(target)}: --image-override rebuild failed; keeping the previous local image. (${err instanceof Error ? err.message : String(err)})`);
|
|
19347
|
+
}
|
|
19203
19348
|
}
|
|
19204
19349
|
const { boots: newBoots, warnings } = strategy.resolveBoots(stacks, resolvedTargets);
|
|
19205
19350
|
for (const w of warnings) logger.warn(w);
|
|
@@ -19213,6 +19358,7 @@ async function reloadAllServices(args) {
|
|
|
19213
19358
|
const cdkOutDir = options.output;
|
|
19214
19359
|
const assetLoader = new AssetManifestLoader();
|
|
19215
19360
|
for (const pt of perTarget) {
|
|
19361
|
+
if (reloadCancelled(signal, logger)) return;
|
|
19216
19362
|
const newBoot = newBootByTarget.get(pt.boot.target);
|
|
19217
19363
|
if (!newBoot) {
|
|
19218
19364
|
logger.warn(`Reload: target ${displayStackName(pt.boot.target)} no longer resolves to a service in the synthesized app; keeping the previous replica(s) serving.`);
|
|
@@ -19261,11 +19407,18 @@ async function reloadAllServices(args) {
|
|
|
19261
19407
|
suppressLoadBalancerWarning: strategy.suppressLoadBalancerWarning === true,
|
|
19262
19408
|
verdict,
|
|
19263
19409
|
...imageOverrideTags.get(newBoot.target) !== void 0 && { imageOverrideTag: imageOverrideTags.get(newBoot.target) },
|
|
19264
|
-
logger
|
|
19410
|
+
logger,
|
|
19411
|
+
...signal && { signal }
|
|
19265
19412
|
});
|
|
19266
19413
|
}
|
|
19414
|
+
if (reloadCancelled(signal, logger)) return;
|
|
19267
19415
|
logger.info("Reload complete.");
|
|
19268
19416
|
}
|
|
19417
|
+
function reloadCancelled(signal, logger) {
|
|
19418
|
+
if (!signal?.aborted) return false;
|
|
19419
|
+
logger.info("Reload cancelled: shutting down.");
|
|
19420
|
+
return true;
|
|
19421
|
+
}
|
|
19269
19422
|
async function loadAssetContextForTarget(args) {
|
|
19270
19423
|
const { target, controller, stacks, cdkOutDir, assetLoader, logger } = args;
|
|
19271
19424
|
const parsed = parseEcsTarget(target);
|
|
@@ -19332,7 +19485,7 @@ async function loadAssetContextForTarget(args) {
|
|
|
19332
19485
|
};
|
|
19333
19486
|
}
|
|
19334
19487
|
async function rollOneTarget(args) {
|
|
19335
|
-
const { controller, newBoot, stacks, options, discovery, skipPull, extraStateProviders, profileCredsFile, frontDoorPools, suppressLoadBalancerWarning, verdict, imageOverrideTag, logger } = args;
|
|
19488
|
+
const { signal, controller, newBoot, stacks, options, discovery, skipPull, extraStateProviders, profileCredsFile, frontDoorPools, suppressLoadBalancerWarning, verdict, imageOverrideTag, logger } = args;
|
|
19336
19489
|
const candidate = pickCandidateStack$1(newBoot.target, stacks);
|
|
19337
19490
|
const stateProvider = createLocalStateProvider(options, candidate?.stackName ?? "", await resolveCfnFallbackRegion(options, candidate?.region), extraStateProviders);
|
|
19338
19491
|
try {
|
|
@@ -19357,6 +19510,7 @@ async function rollOneTarget(args) {
|
|
|
19357
19510
|
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).`);
|
|
19358
19511
|
else logger.info(`Reload of ${displayStackName(newBoot.target)}: rolling ${oldReplicas.length} replica(s) one at a time (start new shadow → swap registrations → stop old).`);
|
|
19359
19512
|
for (const oldInstance of oldReplicas) {
|
|
19513
|
+
if (signal?.aborted) return;
|
|
19360
19514
|
const idx = controller.runState.replicas.indexOf(oldInstance);
|
|
19361
19515
|
if (idx === -1) {
|
|
19362
19516
|
logger.warn(`Reload of ${displayStackName(newBoot.target)}: replica r${oldInstance.index} (gen ${oldInstance.generation}) vanished before its roll; skipping.`);
|
|
@@ -20057,7 +20211,7 @@ async function localRunTaskCommand(target, options, extraStateProviders) {
|
|
|
20057
20211
|
if (options.verbose) logger.setLevel("debug");
|
|
20058
20212
|
const state = createEcsRunState();
|
|
20059
20213
|
let sigintHandler;
|
|
20060
|
-
let
|
|
20214
|
+
let sigtermHandler;
|
|
20061
20215
|
let stateProvider;
|
|
20062
20216
|
let profileCredsFile;
|
|
20063
20217
|
let cleanupPromise;
|
|
@@ -20134,17 +20288,17 @@ async function localRunTaskCommand(target, options, extraStateProviders) {
|
|
|
20134
20288
|
}
|
|
20135
20289
|
}
|
|
20136
20290
|
} 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.");
|
|
20137
|
-
|
|
20138
|
-
|
|
20139
|
-
|
|
20140
|
-
|
|
20141
|
-
|
|
20142
|
-
|
|
20143
|
-
|
|
20144
|
-
|
|
20145
|
-
|
|
20291
|
+
const onSignal = createShutdownSignalHandler({
|
|
20292
|
+
cleanup,
|
|
20293
|
+
stoppingMessage: () => "Stopping task...",
|
|
20294
|
+
forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' and 'docker network ls --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
|
|
20295
|
+
info: (m) => logger.info(m),
|
|
20296
|
+
warn: (m) => logger.warn(m)
|
|
20297
|
+
});
|
|
20298
|
+
sigintHandler = () => onSignal("SIGINT", 130);
|
|
20299
|
+
sigtermHandler = () => onSignal("SIGTERM", 130);
|
|
20146
20300
|
process.on("SIGINT", sigintHandler);
|
|
20147
|
-
process.on("SIGTERM",
|
|
20301
|
+
process.on("SIGTERM", sigtermHandler);
|
|
20148
20302
|
const effectiveAssumeRole = resolveEcsAssumeRoleOption(options);
|
|
20149
20303
|
let assumedCredentials;
|
|
20150
20304
|
let resolvedRoleArn;
|
|
@@ -20206,18 +20360,15 @@ async function localRunTaskCommand(target, options, extraStateProviders) {
|
|
|
20206
20360
|
const containers = result.state.startedContainers.filter((c) => joinedNames.has(c.name)).map((c) => c.id.slice(0, 12)).join(", ");
|
|
20207
20361
|
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(", ")}).`);
|
|
20208
20362
|
}
|
|
20209
|
-
sigintCount = 99;
|
|
20210
20363
|
return;
|
|
20211
20364
|
}
|
|
20212
20365
|
if (result.essentialContainerName) logger.info(`Essential container ${displayIdent(result.essentialContainerName)} exited with code ${result.exitCode}.`);
|
|
20213
20366
|
if (result.exitCode !== 0) process.exitCode = result.exitCode;
|
|
20214
20367
|
} finally {
|
|
20215
|
-
if (sigintHandler) {
|
|
20216
|
-
process.off("SIGINT", sigintHandler);
|
|
20217
|
-
process.off("SIGTERM", sigintHandler);
|
|
20218
|
-
}
|
|
20219
20368
|
if (stateProvider) stateProvider.dispose();
|
|
20220
20369
|
if (!options.detach) await cleanup();
|
|
20370
|
+
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
20371
|
+
if (sigtermHandler) process.off("SIGTERM", sigtermHandler);
|
|
20221
20372
|
}
|
|
20222
20373
|
}
|
|
20223
20374
|
var PlaceholderAccountError = class PlaceholderAccountError extends Error {
|
|
@@ -24227,7 +24378,7 @@ async function resolveDeployedS3Origins(distribution, stacks, options, profileCr
|
|
|
24227
24378
|
buckets
|
|
24228
24379
|
};
|
|
24229
24380
|
const synthRegion = stacks.find((s) => s.stackName === distribution.stackName)?.region;
|
|
24230
|
-
const provider = createLocalStateProvider(options, distribution.stackName, synthRegion, extraStateProviders);
|
|
24381
|
+
const provider = createLocalStateProvider(options, distribution.stackName, synthRegion, extraStateProviders, { realAwsOnly: true });
|
|
24231
24382
|
let record;
|
|
24232
24383
|
try {
|
|
24233
24384
|
record = provider ? await provider.load(distribution.stackName, synthRegion) : void 0;
|
|
@@ -24388,7 +24539,7 @@ async function localStartCloudFrontCommand(target, options, extraStateProviders,
|
|
|
24388
24539
|
process.stdout.write(`CloudFront distribution serving on ${server.url} (${displayIdent(initial.distribution.logicalId)})\n`);
|
|
24389
24540
|
process.stdout.write("^C to stop.\n");
|
|
24390
24541
|
let watcher;
|
|
24391
|
-
let
|
|
24542
|
+
let reloadQueue;
|
|
24392
24543
|
if (options.watch) {
|
|
24393
24544
|
const watchRoot = process.cwd();
|
|
24394
24545
|
const { ignored, shouldTrigger, excludePatterns } = createWatchPredicates({
|
|
@@ -24396,37 +24547,37 @@ async function localStartCloudFrontCommand(target, options, extraStateProviders,
|
|
|
24396
24547
|
output: options.output,
|
|
24397
24548
|
watchConfig: resolveWatchConfig()
|
|
24398
24549
|
});
|
|
24550
|
+
const queue = createReloadQueue({ run: async (_changedPaths, signal) => {
|
|
24551
|
+
try {
|
|
24552
|
+
const reloaded = await synthAndResolve();
|
|
24553
|
+
if (signal.aborted) return;
|
|
24554
|
+
annotateDeployedS3Origins(reloaded.distribution, deployedS3.buckets);
|
|
24555
|
+
for (const reader of deployedS3.readers.values()) reader.clearCache();
|
|
24556
|
+
warnUnsupported(reloaded.distribution, extraStateProviders);
|
|
24557
|
+
await attachKvsModules(reloaded.distribution, reloaded.stacks, options, profileCredentials, logger, extraStateProviders);
|
|
24558
|
+
server.update(reloaded.distribution);
|
|
24559
|
+
logger.info("Reload complete.");
|
|
24560
|
+
} catch (err) {
|
|
24561
|
+
logger.warn(`Reload failed; keeping the previous version serving: ${err instanceof Error ? err.message : String(err)}`);
|
|
24562
|
+
}
|
|
24563
|
+
} });
|
|
24564
|
+
reloadQueue = queue;
|
|
24399
24565
|
watcher = createFileWatcher({
|
|
24400
24566
|
paths: [watchRoot],
|
|
24401
24567
|
ignored,
|
|
24402
24568
|
shouldTrigger,
|
|
24403
|
-
onChange: () => {
|
|
24569
|
+
onChange: (changedPaths) => {
|
|
24404
24570
|
logger.info("Detected source change; reloading...");
|
|
24405
|
-
|
|
24406
|
-
try {
|
|
24407
|
-
const reloaded = await synthAndResolve();
|
|
24408
|
-
annotateDeployedS3Origins(reloaded.distribution, deployedS3.buckets);
|
|
24409
|
-
for (const reader of deployedS3.readers.values()) reader.clearCache();
|
|
24410
|
-
warnUnsupported(reloaded.distribution, extraStateProviders);
|
|
24411
|
-
await attachKvsModules(reloaded.distribution, reloaded.stacks, options, profileCredentials, logger, extraStateProviders);
|
|
24412
|
-
server.update(reloaded.distribution);
|
|
24413
|
-
logger.info("Reload complete.");
|
|
24414
|
-
} catch (err) {
|
|
24415
|
-
logger.warn(`Reload failed; keeping the previous version serving: ${err instanceof Error ? err.message : String(err)}`);
|
|
24416
|
-
}
|
|
24417
|
-
}).catch(() => void 0);
|
|
24571
|
+
queue.schedule(changedPaths);
|
|
24418
24572
|
}
|
|
24419
24573
|
});
|
|
24420
24574
|
logger.info(`Watching ${watchRoot} for source changes (excluding ${excludePatterns.join(", ")}).`);
|
|
24421
24575
|
}
|
|
24422
|
-
|
|
24423
|
-
|
|
24424
|
-
|
|
24425
|
-
|
|
24426
|
-
|
|
24427
|
-
if (watcher) try {
|
|
24428
|
-
await watcher.close();
|
|
24429
|
-
} catch {}
|
|
24576
|
+
const teardown = async () => {
|
|
24577
|
+
await stopWatchReloads({
|
|
24578
|
+
watcher,
|
|
24579
|
+
queue: reloadQueue
|
|
24580
|
+
});
|
|
24430
24581
|
try {
|
|
24431
24582
|
await server.close();
|
|
24432
24583
|
} catch {}
|
|
@@ -24436,10 +24587,16 @@ async function localStartCloudFrontCommand(target, options, extraStateProviders,
|
|
|
24436
24587
|
logger.debug(`Web function server teardown failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
24437
24588
|
}))]);
|
|
24438
24589
|
await Promise.all([...deployedS3.readers.values()].map((reader) => reader.close()));
|
|
24439
|
-
process.exit(exitCode);
|
|
24440
24590
|
};
|
|
24441
|
-
|
|
24442
|
-
|
|
24591
|
+
const shutdown = createShutdownSignalHandler({
|
|
24592
|
+
cleanup: () => teardown().catch(() => void 0),
|
|
24593
|
+
stoppingMessage: (signal) => `Received ${signal}, shutting down...`,
|
|
24594
|
+
forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
|
|
24595
|
+
info: (m) => logger.info(m),
|
|
24596
|
+
warn: (m) => logger.warn(m)
|
|
24597
|
+
});
|
|
24598
|
+
process.on("SIGINT", () => shutdown("SIGINT", 130));
|
|
24599
|
+
process.on("SIGTERM", () => shutdown("SIGTERM", 0));
|
|
24443
24600
|
await new Promise(() => void 0);
|
|
24444
24601
|
}
|
|
24445
24602
|
function createLocalStartCloudFrontCommand(opts = {}) {
|
|
@@ -24810,20 +24967,17 @@ async function localStartAgentCoreCommand(target, options, extraStateProviders,
|
|
|
24810
24967
|
let profileCredsFile;
|
|
24811
24968
|
let stateProvider;
|
|
24812
24969
|
let watcher;
|
|
24813
|
-
let
|
|
24970
|
+
let reloadQueue;
|
|
24814
24971
|
let shuttingDown = false;
|
|
24815
24972
|
let tornDown = false;
|
|
24816
24973
|
const teardown = async () => {
|
|
24817
24974
|
if (tornDown) return;
|
|
24818
24975
|
tornDown = true;
|
|
24819
|
-
|
|
24820
|
-
|
|
24821
|
-
|
|
24822
|
-
logger.debug(`watcher close failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
24823
|
-
}
|
|
24824
|
-
try {
|
|
24825
|
-
await reloadChain;
|
|
24826
|
-
} catch {}
|
|
24976
|
+
await stopWatchReloads({
|
|
24977
|
+
watcher,
|
|
24978
|
+
queue: reloadQueue,
|
|
24979
|
+
onWatcherCloseError: (err) => logger.debug(`watcher close failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
24980
|
+
});
|
|
24827
24981
|
if (server) try {
|
|
24828
24982
|
await server.close();
|
|
24829
24983
|
} catch (err) {
|
|
@@ -24908,15 +25062,18 @@ async function localStartAgentCoreCommand(target, options, extraStateProviders,
|
|
|
24908
25062
|
...sensitiveEnvKeys.size > 0 && { sensitiveEnvKeys }
|
|
24909
25063
|
});
|
|
24910
25064
|
stopLogs = streamLogs(containerId);
|
|
24911
|
-
const shutdown =
|
|
24912
|
-
|
|
24913
|
-
|
|
24914
|
-
|
|
24915
|
-
|
|
24916
|
-
|
|
24917
|
-
|
|
24918
|
-
|
|
24919
|
-
|
|
25065
|
+
const shutdown = createShutdownSignalHandler({
|
|
25066
|
+
cleanup: async () => {
|
|
25067
|
+
shuttingDown = true;
|
|
25068
|
+
await teardown().catch(() => void 0);
|
|
25069
|
+
},
|
|
25070
|
+
stoppingMessage: (signal) => `Received ${signal}, shutting down...`,
|
|
25071
|
+
forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
|
|
25072
|
+
info: (m) => logger.info(m),
|
|
25073
|
+
warn: (m) => logger.warn(m)
|
|
25074
|
+
});
|
|
25075
|
+
process.on("SIGINT", () => shutdown("SIGINT", 130));
|
|
25076
|
+
process.on("SIGTERM", () => shutdown("SIGTERM", 0));
|
|
24920
25077
|
try {
|
|
24921
25078
|
if (plan.readyPath === void 0) await waitForAgentCorePing(containerHost, containerHostPort, options.timeout);
|
|
24922
25079
|
else await waitForAgentCoreHttpReady(containerHost, containerHostPort, plan.readyPath, options.timeout);
|
|
@@ -24986,95 +25143,99 @@ async function localStartAgentCoreCommand(target, options, extraStateProviders,
|
|
|
24986
25143
|
watchConfig: resolveWatchConfig()
|
|
24987
25144
|
});
|
|
24988
25145
|
logger.info(`Watching ${watchRoot} for source changes (excluding ${excludePatterns.join(", ")}). The warm container reloads in place; the serve stays up.`);
|
|
25146
|
+
reloadQueue = createReloadQueue({
|
|
25147
|
+
run: async (changedPaths) => {
|
|
25148
|
+
if (tornDown || shuttingDown) return;
|
|
25149
|
+
let freshStacks;
|
|
25150
|
+
let freshResolved;
|
|
25151
|
+
let freshLoaded;
|
|
25152
|
+
let freshImageContext;
|
|
25153
|
+
let verdict;
|
|
25154
|
+
let nextAssetHash = currentAssetHash;
|
|
25155
|
+
try {
|
|
25156
|
+
const synthRes = await synthesizer.synthesize(synthOpts);
|
|
25157
|
+
freshStacks = synthRes.stacks;
|
|
25158
|
+
synthRes.checkSelectedStacks?.([resolved.stack.stackName]);
|
|
25159
|
+
const freshCandidate = pickAgentCoreCandidateStack(resolvedTarget, freshStacks);
|
|
25160
|
+
const ctx = stateProvider && freshCandidate ? await buildAgentCoreImageContext(freshCandidate, stateProvider, options) : {
|
|
25161
|
+
context: void 0,
|
|
25162
|
+
loaded: void 0
|
|
25163
|
+
};
|
|
25164
|
+
freshImageContext = ctx.context;
|
|
25165
|
+
freshLoaded = ctx.loaded;
|
|
25166
|
+
freshResolved = resolveAgentCoreTarget(resolvedTarget, freshStacks, freshImageContext);
|
|
25167
|
+
await resolveFromS3BucketIntrinsic(freshResolved, stateProvider, freshLoaded, freshImageContext);
|
|
25168
|
+
const assetCtx = await loadAgentCoreAssetContext({
|
|
25169
|
+
resolvedTarget,
|
|
25170
|
+
resolved: freshResolved,
|
|
25171
|
+
stacks: freshStacks,
|
|
25172
|
+
cdkOutDir,
|
|
25173
|
+
assetLoader,
|
|
25174
|
+
oldAssetHash: currentAssetHash
|
|
25175
|
+
});
|
|
25176
|
+
if (assetCtx?.newAssetHash !== void 0) nextAssetHash = assetCtx.newAssetHash;
|
|
25177
|
+
verdict = classifySourceChange(changedPaths, assetCtx);
|
|
25178
|
+
logger.info(`Detected source change (${changedPaths.length} path(s)); verdict=${verdict.kind} (${verdict.reason}).`);
|
|
25179
|
+
} catch (err) {
|
|
25180
|
+
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.`);
|
|
25181
|
+
return;
|
|
25182
|
+
}
|
|
25183
|
+
if (tornDown || shuttingDown) return;
|
|
25184
|
+
try {
|
|
25185
|
+
if (verdict.kind === "soft-reload") {
|
|
25186
|
+
if (!containerId) throw new CdkLocalError("Reload: no live container to docker cp / docker restart into.", "LOCAL_START_AGENTCORE_WATCH_NO_CONTAINER");
|
|
25187
|
+
await softReloadAgentContainer(containerId, verdict.newAssetSourceDir);
|
|
25188
|
+
await waitReady(containerHostPort);
|
|
25189
|
+
logger.info("Reload: soft-reloaded the agent container (docker cp + docker restart; container ID + host port preserved).");
|
|
25190
|
+
} else {
|
|
25191
|
+
if (stopLogs) {
|
|
25192
|
+
try {
|
|
25193
|
+
stopLogs();
|
|
25194
|
+
} catch {}
|
|
25195
|
+
stopLogs = void 0;
|
|
25196
|
+
}
|
|
25197
|
+
if (containerId) {
|
|
25198
|
+
await removeContainer(containerId);
|
|
25199
|
+
containerId = void 0;
|
|
25200
|
+
}
|
|
25201
|
+
const newImage = await resolveAgentCoreImage(freshResolved, options, freshLoaded, stateProvider);
|
|
25202
|
+
const { env: newEnv, sensitiveEnvKeys: newSensitive } = await buildContainerEnv(freshResolved, options, profileCredentials, profileCredsFile, stateProvider, freshLoaded, freshImageContext);
|
|
25203
|
+
if (tornDown || shuttingDown) return;
|
|
25204
|
+
const newPort = await pickFreePort();
|
|
25205
|
+
const newName = `${getEmbedConfig().resourceNamePrefix}-agentcore-${process.pid}-${Math.random().toString(36).slice(2, 8)}`;
|
|
25206
|
+
logger.info(`Reload: starting agent container (image=${newImage}, port=${newPort} -> ${plan.containerPortLabel})...`);
|
|
25207
|
+
containerId = await runDetached({
|
|
25208
|
+
image: newImage,
|
|
25209
|
+
mounts: [],
|
|
25210
|
+
env: newEnv,
|
|
25211
|
+
cmd: [],
|
|
25212
|
+
hostPort: newPort,
|
|
25213
|
+
host: containerHost,
|
|
25214
|
+
platform: options.platform,
|
|
25215
|
+
name: newName,
|
|
25216
|
+
...plan.containerPort !== void 0 && { containerPort: plan.containerPort },
|
|
25217
|
+
...newSensitive.size > 0 && { sensitiveEnvKeys: newSensitive }
|
|
25218
|
+
});
|
|
25219
|
+
stopLogs = streamLogs(containerId);
|
|
25220
|
+
containerHostPort = newPort;
|
|
25221
|
+
await waitReady(newPort);
|
|
25222
|
+
server?.setContainerPort(newPort);
|
|
25223
|
+
logger.info(`Reload: rebuilt the agent container; serve re-pointed to port ${newPort}.`);
|
|
25224
|
+
}
|
|
25225
|
+
currentAssetHash = nextAssetHash;
|
|
25226
|
+
logger.info("Reload complete.");
|
|
25227
|
+
} catch (err) {
|
|
25228
|
+
logger.error(`Reload failed: ${err instanceof Error ? err.message : String(err)}. The serve stays up; edit + save again to retry.`);
|
|
25229
|
+
}
|
|
25230
|
+
},
|
|
25231
|
+
onError: (err) => logger.error(`Reload failed: ${err instanceof Error ? err.message : String(err)}.`)
|
|
25232
|
+
});
|
|
25233
|
+
const queue = reloadQueue;
|
|
24989
25234
|
watcher = createFileWatcher({
|
|
24990
25235
|
paths: [watchRoot],
|
|
24991
25236
|
ignored,
|
|
24992
25237
|
shouldTrigger,
|
|
24993
|
-
onChange: (changedPaths) =>
|
|
24994
|
-
reloadChain = reloadChain.then(async () => {
|
|
24995
|
-
if (tornDown || shuttingDown) return;
|
|
24996
|
-
let freshStacks;
|
|
24997
|
-
let freshResolved;
|
|
24998
|
-
let freshLoaded;
|
|
24999
|
-
let freshImageContext;
|
|
25000
|
-
let verdict;
|
|
25001
|
-
let nextAssetHash = currentAssetHash;
|
|
25002
|
-
try {
|
|
25003
|
-
const synthRes = await synthesizer.synthesize(synthOpts);
|
|
25004
|
-
freshStacks = synthRes.stacks;
|
|
25005
|
-
synthRes.checkSelectedStacks?.([resolved.stack.stackName]);
|
|
25006
|
-
const freshCandidate = pickAgentCoreCandidateStack(resolvedTarget, freshStacks);
|
|
25007
|
-
const ctx = stateProvider && freshCandidate ? await buildAgentCoreImageContext(freshCandidate, stateProvider, options) : {
|
|
25008
|
-
context: void 0,
|
|
25009
|
-
loaded: void 0
|
|
25010
|
-
};
|
|
25011
|
-
freshImageContext = ctx.context;
|
|
25012
|
-
freshLoaded = ctx.loaded;
|
|
25013
|
-
freshResolved = resolveAgentCoreTarget(resolvedTarget, freshStacks, freshImageContext);
|
|
25014
|
-
await resolveFromS3BucketIntrinsic(freshResolved, stateProvider, freshLoaded, freshImageContext);
|
|
25015
|
-
const assetCtx = await loadAgentCoreAssetContext({
|
|
25016
|
-
resolvedTarget,
|
|
25017
|
-
resolved: freshResolved,
|
|
25018
|
-
stacks: freshStacks,
|
|
25019
|
-
cdkOutDir,
|
|
25020
|
-
assetLoader,
|
|
25021
|
-
oldAssetHash: currentAssetHash
|
|
25022
|
-
});
|
|
25023
|
-
if (assetCtx?.newAssetHash !== void 0) nextAssetHash = assetCtx.newAssetHash;
|
|
25024
|
-
verdict = classifySourceChange(changedPaths, assetCtx);
|
|
25025
|
-
logger.info(`Detected source change (${changedPaths.length} path(s)); verdict=${verdict.kind} (${verdict.reason}).`);
|
|
25026
|
-
} catch (err) {
|
|
25027
|
-
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.`);
|
|
25028
|
-
return;
|
|
25029
|
-
}
|
|
25030
|
-
if (tornDown || shuttingDown) return;
|
|
25031
|
-
try {
|
|
25032
|
-
if (verdict.kind === "soft-reload") {
|
|
25033
|
-
if (!containerId) throw new CdkLocalError("Reload: no live container to docker cp / docker restart into.", "LOCAL_START_AGENTCORE_WATCH_NO_CONTAINER");
|
|
25034
|
-
await softReloadAgentContainer(containerId, verdict.newAssetSourceDir);
|
|
25035
|
-
await waitReady(containerHostPort);
|
|
25036
|
-
logger.info("Reload: soft-reloaded the agent container (docker cp + docker restart; container ID + host port preserved).");
|
|
25037
|
-
} else {
|
|
25038
|
-
if (stopLogs) {
|
|
25039
|
-
try {
|
|
25040
|
-
stopLogs();
|
|
25041
|
-
} catch {}
|
|
25042
|
-
stopLogs = void 0;
|
|
25043
|
-
}
|
|
25044
|
-
if (containerId) {
|
|
25045
|
-
await removeContainer(containerId);
|
|
25046
|
-
containerId = void 0;
|
|
25047
|
-
}
|
|
25048
|
-
const newImage = await resolveAgentCoreImage(freshResolved, options, freshLoaded, stateProvider);
|
|
25049
|
-
const { env: newEnv, sensitiveEnvKeys: newSensitive } = await buildContainerEnv(freshResolved, options, profileCredentials, profileCredsFile, stateProvider, freshLoaded, freshImageContext);
|
|
25050
|
-
const newPort = await pickFreePort();
|
|
25051
|
-
const newName = `${getEmbedConfig().resourceNamePrefix}-agentcore-${process.pid}-${Math.random().toString(36).slice(2, 8)}`;
|
|
25052
|
-
logger.info(`Reload: starting agent container (image=${newImage}, port=${newPort} -> ${plan.containerPortLabel})...`);
|
|
25053
|
-
containerId = await runDetached({
|
|
25054
|
-
image: newImage,
|
|
25055
|
-
mounts: [],
|
|
25056
|
-
env: newEnv,
|
|
25057
|
-
cmd: [],
|
|
25058
|
-
hostPort: newPort,
|
|
25059
|
-
host: containerHost,
|
|
25060
|
-
platform: options.platform,
|
|
25061
|
-
name: newName,
|
|
25062
|
-
...plan.containerPort !== void 0 && { containerPort: plan.containerPort },
|
|
25063
|
-
...newSensitive.size > 0 && { sensitiveEnvKeys: newSensitive }
|
|
25064
|
-
});
|
|
25065
|
-
stopLogs = streamLogs(containerId);
|
|
25066
|
-
containerHostPort = newPort;
|
|
25067
|
-
await waitReady(newPort);
|
|
25068
|
-
server?.setContainerPort(newPort);
|
|
25069
|
-
logger.info(`Reload: rebuilt the agent container; serve re-pointed to port ${newPort}.`);
|
|
25070
|
-
}
|
|
25071
|
-
currentAssetHash = nextAssetHash;
|
|
25072
|
-
logger.info("Reload complete.");
|
|
25073
|
-
} catch (err) {
|
|
25074
|
-
logger.error(`Reload failed: ${err instanceof Error ? err.message : String(err)}. The serve stays up; edit + save again to retry.`);
|
|
25075
|
-
}
|
|
25076
|
-
});
|
|
25077
|
-
}
|
|
25238
|
+
onChange: (changedPaths) => queue.schedule(changedPaths)
|
|
25078
25239
|
});
|
|
25079
25240
|
}
|
|
25080
25241
|
await new Promise(() => void 0);
|
|
@@ -31747,4 +31908,4 @@ function addStudioSpecificOptions(cmd) {
|
|
|
31747
31908
|
|
|
31748
31909
|
//#endregion
|
|
31749
31910
|
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 };
|
|
31750
|
-
//# sourceMappingURL=local-studio-
|
|
31911
|
+
//# sourceMappingURL=local-studio-CFf6tO1e.js.map
|