@go-to-k/cdkd 0.284.54 → 0.284.56
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/{asg-provider-BaNTIjU4.js → asg-provider-DoiQARH6.js} +2 -2
- package/dist/{asg-provider-BaNTIjU4.js.map → asg-provider-DoiQARH6.js.map} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-B9SrF2-R.js → deploy-engine-CNYFUw4D.js} +39 -12
- package/dist/{deploy-engine-B9SrF2-R.js.map → deploy-engine-CNYFUw4D.js.map} +1 -1
- package/dist/index.js +1 -1
- package/dist/{program-Bpz-tAA5.js → program-BsvNn8Y3.js} +231 -25
- package/dist/{program-Bpz-tAA5.js.map → program-BsvNn8Y3.js.map} +1 -1
- package/dist/{version-DLRgymoe.js → version-oF2rSNET.js} +2 -2
- package/dist/{version-DLRgymoe.js.map → version-oF2rSNET.js.map} +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { An as Synthesizer, Dr as formatError, Er as SynthesisError, Jt as TemplateParser, Or as isCdkdError, Qn as AssemblyReader, Tr as StateError, Ut as DiffCalculator, W as IAMRoleProvider, Yt as LockManager, Zt as S3StateBackend, ar as setAwsClients, br as ProvisioningError, cr as ConfigError, er as clearBucketRegionCache, gr as LockError, ir as resetAwsClients, kr as normalizeAwsError, nr as AwsClients, or as AssetError, q as ProviderRegistry, qt as DagBuilder, r as DeployEngine, rn as AssetPublisher, rr as getAwsClients, rt as CloudControlProvider, sr as CdkdError, tr as resolveBucketRegion, ur as DependencyError } from "./deploy-engine-CNYFUw4D.js";
|
|
2
2
|
import { n as getLogger, r as setLogger, t as ConsoleLogger } from "./logger-zRrlbaQt.js";
|
|
3
3
|
|
|
4
4
|
export { AssemblyReader, AssetError, AssetPublisher, AwsClients, CdkdError, CloudControlProvider, ConfigError, ConsoleLogger, DagBuilder, DependencyError, DeployEngine, DiffCalculator, IAMRoleProvider, LockError, LockManager, ProviderRegistry, ProvisioningError, S3StateBackend, StateError, SynthesisError, Synthesizer, TemplateParser, clearBucketRegionCache, formatError, getAwsClients, getLogger, isCdkdError, normalizeAwsError, resetAwsClients, resolveBucketRegion, setAwsClients, setLogger };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { $ as endCommandInterruptScope, $t as
|
|
1
|
+
import { $ as endCommandInterruptScope, $n as processStackMessages, $t as exportNamesCarriedFrom, A as renderStatefulReason, An as Synthesizer, Ar as withErrorHandling, At as isSingleDynamicReferenceToken, B as exportAliasCollisionScrubWarning, Bn as resolveUseCdkBootstrapAssets, Bt as s3BucketRegionalDomainName, C as isFinalSnapshotError, Cn as formatDockerLoginError, Cr as StackHasActiveImportsError, Ct as requireConfigString, D as extractDeploymentEventError, Dn as runDockerStreaming, Dt as createSecretMasker, E as makeCanonicalizePropertiesFn, En as runDockerForeground, Et as TEMPLATE_SOURCED_RULES, F as green, Fn as resolveAutoAssetStorage, Ft as classifyReplaySecretRegion, G as collectInlinePolicyNamesManagedBySiblings, Gn as MIGRATE_TMP_PREFIX, Gt as describeTypeWithThrottleRetry, H as secretBearingStateKeyWarning, Hn as warnDeprecatedNoPrefixCliFlag, Ht as applyRoleArnIfSet, I as red, In as resolveCaptureObservedState, It as producerRegionsFromState, J as findActionableSilentDrops, Jn as expectedOwnerParam, Jt as TemplateParser, K as clearOnUpdateRemoval, Kn as findLargeInlineResources, Kt as withRetry, L as yellow, Ln as resolveSkipPrefix, Lt as s3BucketArn, M as bold, Mn as getDefaultStateBucketName, Mr as isRetryableTransientError, Mt as maskSecretsInText, N as cyan, Nn as getLegacyStateBucketName, Nr as isThrottlingError, Nt as redactSecretsForState, O as MULTI_REGION_RECREATE_BLOCKED_TYPES, On as AssetManifestLoader, Ot as dynamicReferenceTokens, P as gray, Pn as resolveApp, Pr as markNonRetryable, Pt as scrubResourceRecord, Q as beginCommandInterruptScope, Qn as AssemblyReader, Qt as rebuildClientForBucketRegion, R as collectDeclaredOutputNames, Rn as resolveStateBucketWithDefault, Rt as s3BucketDomainName, S as createPreDeleteFinalSnapshot, Sn as dockerSpawnEnvWithSensitive, Sr as ResourceUpdateNotSupportedError, St as requireConfigObject, T as unsupportedFinalSnapshotError, Tn as partitionSensitiveEnv, Tt as STATE_SOURCED_READBACK_RULES, U as stateKeySecretExposure, Un as CFN_TEMPLATE_BODY_LIMIT, Ut as DiffCalculator, V as isExportAliasCollision, Vn as stateBucketExistenceConfirmed, Vt as s3BucketWebsiteUrl, W as IAMRoleProvider, Wn as CFN_TEMPLATE_URL_LIMIT, Wt as INTRINSIC_KEYS, X as CUSTOM_RESOURCE_RESPONSE_PREFIX, Xn as canonicalizeRegion, Xt as displaySafe, Y as findSilentDropProperties, Yn as PARTITION_TABLE, Yt as LockManager, Z as DEFAULT_STATE_PREFIX, Zn as derivePartitionAndUrlSuffix, Zt as S3StateBackend, _ as computeImplicitDeleteEdges, _n as readBootstrapMarkerBody, _r as MissingCdkCliError, _t as configBooleanRefusal, a as DeploymentEventsStore, an as WorkGraph, ar as setAwsClients, at as disableInstanceApiTermination, b as buildFinalSnapshotIdentifier, bn as buildDenyExternalAccessPolicy, br as ProvisioningError, bt as replayWarn, c as replayFailedOperations, cn as loadPublishableAssetManifest, ct as carriesDynamicReference, d as updatePartialReason, dn as stripControlChars, dr as DeployCancelledError, dt as refStateLookupFromResource, en as importableOutputKeys, et as interruptWatchListenerCount, f as UNSPECIFIED_SKIP_REASON, fn as AssetModeResolver, fr as DynamicReferenceRegionAmbiguousError, ft as WAFv2WebACLProvider, g as IMPLICIT_DELETE_DEPENDENCIES, gn as parseBootstrapMarker, gt as coerceCfnBoolean, h as maskingRetryLogger, hn as getBootstrapMarkerKey, hr as LocalStartServiceError, ht as assertRegionMatch, i as DeploymentEventsReader, in as stringifyValue, ir as resetAwsClients, it as slowCcOperationTimeoutMs, j as formatResourceLine, jn as synthesisStatusMessage, jr as isMarkedNonRetryable, jt as maskSecretsInError, k as isStatefulRecreateTargetSync, kn as getDockerImageBySourceHash, kr as normalizeAwsError, kt as errorCauseChain, l as replayRollback, ln as rewriteTemplateAssetReferences, lr as CrossAccountSecretRefusalError, lt as cfnRefValueFromPhysicalId, m as withResourceDeadline, mn as ensureAssetStorage, mr as LocalMigrateError, mt as resolveExplicitPhysicalId, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as shouldRetainResource, nr as AwsClients, nt as startInterruptWatch, o as planFailedOps, on as buildAssetRedirectMap, ot as isTerminationProtectionPropagationError, p as deleteSkipReason, pn as BOOTSTRAP_MARKER_PREFIX, pr as LocalInvokeBuildError$1, pt as normalizeAwsTagsToCfn, q as ProviderRegistry, qn as uploadCfnTemplate, qt as DagBuilder, r as DeployEngine, rn as AssetPublisher, rr as getAwsClients, rt as CloudControlProvider, s as planRollback, sn as createAssetRedirectResolver, sr as CdkdError, st as IntrinsicFunctionResolver, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as importableOutputs, tr as resolveBucketRegion, tt as isInterruptedWaitError, u as updatePartialMessage, un as escapeRegExp, ut as getAccountInfo, v as ATOMIC_FINAL_SNAPSHOT_TYPES, vn as validateAssetBucketName, vr as NestedStackChildDirectDestroyError, vt as configStringRefusal, w as refusesFinalSnapshot, wn as getDockerCmd, wr as StackTerminationProtectionError, wt as STATE_SOURCED_CROSS_GENERATION_RULES, x as ccRoutedFinalSnapshotError, xn as buildDockerImage, xr as ResourceTimeoutError, xt as requireConfigArray, y as PRE_DELETE_SNAPSHOT_TYPES, yn as validateContainerRepoName, yr as PartialFailureError, yt as readConfigString, z as collectPublishedOutputNames, zn as resolveStateBucketWithDefaultAndSource, zt as s3BucketDualStackDomainName } from "./deploy-engine-CNYFUw4D.js";
|
|
2
2
|
import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, f as getCurrentStackName, h as withStackName, i as runStackBuffered, m as withSkipPrefix, n as getLogger, o as PATTERN_B_NAME_OPTIONS, s as PATTERN_B_NAME_PROPERTIES, u as generateResourceName } from "./logger-zRrlbaQt.js";
|
|
3
|
-
import { t as getCdkdVersion } from "./version-
|
|
4
|
-
import { t as ASGProvider } from "./asg-provider-
|
|
3
|
+
import { t as getCdkdVersion } from "./version-oF2rSNET.js";
|
|
4
|
+
import { t as ASGProvider } from "./asg-provider-DoiQARH6.js";
|
|
5
5
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
6
6
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
7
7
|
import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketEncryptionCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketOwnershipControlsCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketOwnershipControlsCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
@@ -2055,6 +2055,15 @@ function createListCommand() {
|
|
|
2055
2055
|
*/
|
|
2056
2056
|
function forwardSigtermToSigint() {
|
|
2057
2057
|
beginCommandInterruptScope();
|
|
2058
|
+
try {
|
|
2059
|
+
return installSigtermForwarder();
|
|
2060
|
+
} catch (error) {
|
|
2061
|
+
endCommandInterruptScope();
|
|
2062
|
+
throw error;
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
/** The registration half of {@link forwardSigtermToSigint}, after its scope is open. */
|
|
2066
|
+
function installSigtermForwarder() {
|
|
2058
2067
|
const handler = () => {
|
|
2059
2068
|
if (process.listenerCount("SIGINT") === 0) process.exit(143);
|
|
2060
2069
|
process.emit("SIGINT", "SIGINT");
|
|
@@ -2065,6 +2074,117 @@ function forwardSigtermToSigint() {
|
|
|
2065
2074
|
endCommandInterruptScope();
|
|
2066
2075
|
};
|
|
2067
2076
|
}
|
|
2077
|
+
/**
|
|
2078
|
+
* Register a command-scoped SIGINT handler for the destroy commands
|
|
2079
|
+
* (issue #2117).
|
|
2080
|
+
*
|
|
2081
|
+
* `cdkd deploy` has had one of these since issue #1348 (`deploy.ts`'s
|
|
2082
|
+
* `topLevelSigintHandler`). The destroy side had none, so the ONLY channel
|
|
2083
|
+
* carrying "the user interrupted" from `runDestroyForStack` back to the
|
|
2084
|
+
* `--all` loop was `DestroyRunResult.interrupted` — a boolean assigned ONCE,
|
|
2085
|
+
* inside the runner's `try`, after its level loop. Every instant where the
|
|
2086
|
+
* runner's `draining` flag flips AFTER that assignment is an instant where
|
|
2087
|
+
* `cdkd destroy --all` went on to delete the NEXT stack after the user asked
|
|
2088
|
+
* it to stop.
|
|
2089
|
+
*
|
|
2090
|
+
* The runner's outer `finally` re-syncs `result.interrupted ||= draining` to
|
|
2091
|
+
* cover the widest such window (renderer teardown, state flush, lock release),
|
|
2092
|
+
* and that line is marked TACTICAL in its own comment: it narrows the window
|
|
2093
|
+
* rather than removing it. Two gaps survive it, and neither is reachable from
|
|
2094
|
+
* inside the runner at all:
|
|
2095
|
+
*
|
|
2096
|
+
* 1. The runner removes its SIGINT listener in its inner `finally`, BEFORE the
|
|
2097
|
+
* re-sync line and its `return`, so from there on nothing of the runner's is
|
|
2098
|
+
* armed. This watch covers that stretch — by RECORDING once a graceful owner
|
|
2099
|
+
* is gone and the stack is done, and by QUITTING in the mirror-image window
|
|
2100
|
+
* at the START of a stack, where the runner has not armed yet and could not
|
|
2101
|
+
* act on a recorded flag (see `gracefulOwnerArmed` below).
|
|
2102
|
+
* 2. Everything the `--all` loop itself does between two stacks — the
|
|
2103
|
+
* `RUN_FINISHED` event, `eventRecorder.finalize`, `purgeEventsAfterDestroy`
|
|
2104
|
+
* — runs with no runner handler armed at all.
|
|
2105
|
+
*
|
|
2106
|
+
* A handler that lives for the whole command closes both, because it is armed
|
|
2107
|
+
* in every window rather than in the ones the runner happens to span. The two
|
|
2108
|
+
* flags answer different questions and both are kept: `result.interrupted` is
|
|
2109
|
+
* the PER-STACK outcome (it decides that stack's state preservation, its
|
|
2110
|
+
* summary line and its `--purge-events` skip), while this one is the
|
|
2111
|
+
* COMMAND-level "stop" the loop wants.
|
|
2112
|
+
*
|
|
2113
|
+
* Note on the counterpart contract: `deploy-engine.ts` removes its own SIGINT
|
|
2114
|
+
* handler before releasing its lock, which is safe only because `deploy.ts`'s
|
|
2115
|
+
* top-level handler outlives it. The destroy side now has the same property
|
|
2116
|
+
* for the same reason — `destroy-runner.ts`'s `process.removeListener('SIGINT',
|
|
2117
|
+
* sigintHandler)` is no longer the last handler standing, because this one is
|
|
2118
|
+
* disposed only in the command's outermost `finally`.
|
|
2119
|
+
*
|
|
2120
|
+
* @param opts.command the user-facing command name used in the force-quit
|
|
2121
|
+
* notice (`cdkd destroy` / `cdkd state destroy`).
|
|
2122
|
+
*/
|
|
2123
|
+
function watchCommandInterrupt(opts) {
|
|
2124
|
+
let interrupted = false;
|
|
2125
|
+
let stacksInFlight = 0;
|
|
2126
|
+
/**
|
|
2127
|
+
* Is some OTHER listener going to handle this signal gracefully?
|
|
2128
|
+
*
|
|
2129
|
+
* Being inside `runStack` is NOT the same question, and assuming it was is a
|
|
2130
|
+
* regression this fix already shipped once: `runDestroyForStack` registers
|
|
2131
|
+
* its own handler about two hundred lines in, AFTER the strong-reference
|
|
2132
|
+
* pre-flight scan (an S3 LIST plus a GET per stack) and the per-stack
|
|
2133
|
+
* confirm prompt. Staying silent across that window swallowed the signal
|
|
2134
|
+
* outright — no notice, no exit, no escalation on a repeat — and because
|
|
2135
|
+
* this watch IS a listener, `interrupt-watch.ts`'s last-listener force-quit
|
|
2136
|
+
* could no longer fire there either. The runner then began with `draining`
|
|
2137
|
+
* false and destroyed the whole stack the user had just asked to stop, which
|
|
2138
|
+
* is issue #2117's own defect one window further in.
|
|
2139
|
+
*
|
|
2140
|
+
* Counting listeners answers the real question, and the two exclusions are
|
|
2141
|
+
* what make the count mean "graceful owner":
|
|
2142
|
+
*
|
|
2143
|
+
* - our own handler, which is not an answer to itself;
|
|
2144
|
+
* - `interrupt-watch.ts`'s shared handler, which is a LATCH rather than a
|
|
2145
|
+
* graceful owner — deferring to it is exactly the swallow above.
|
|
2146
|
+
*
|
|
2147
|
+
* A provider's transient wait listener (CustomResource / ACM / CloudFront /
|
|
2148
|
+
* Route53) does count, and that is correct rather than a false positive:
|
|
2149
|
+
* those exist only DURING a provider wait, which is strictly inside the
|
|
2150
|
+
* runner handler's own lifetime, so one cannot be present while the runner's
|
|
2151
|
+
* is absent.
|
|
2152
|
+
*/
|
|
2153
|
+
function gracefulOwnerArmed() {
|
|
2154
|
+
return process.listeners("SIGINT").filter((l) => l !== handler).length - interruptWatchListenerCount() > 0;
|
|
2155
|
+
}
|
|
2156
|
+
const handler = () => {
|
|
2157
|
+
if (stacksInFlight > 0 && gracefulOwnerArmed()) {
|
|
2158
|
+
interrupted = true;
|
|
2159
|
+
return;
|
|
2160
|
+
}
|
|
2161
|
+
if (interrupted) {
|
|
2162
|
+
process.stderr.write("\nForce-quit.\n");
|
|
2163
|
+
process.exit(130);
|
|
2164
|
+
}
|
|
2165
|
+
interrupted = true;
|
|
2166
|
+
if (stacksInFlight > 0) {
|
|
2167
|
+
process.stderr.write(`\nInterrupted before ${opts.command} armed its per-stack teardown — quitting now. Nothing was deleted and no stack lock is held.\n`);
|
|
2168
|
+
process.exit(130);
|
|
2169
|
+
}
|
|
2170
|
+
process.stderr.write(`\nInterrupted — ${opts.command} will stop before starting another stack (press Ctrl-C again to force-quit)...\n`);
|
|
2171
|
+
};
|
|
2172
|
+
process.on("SIGINT", handler);
|
|
2173
|
+
return {
|
|
2174
|
+
interrupted: () => interrupted,
|
|
2175
|
+
async runStack(fn) {
|
|
2176
|
+
stacksInFlight += 1;
|
|
2177
|
+
try {
|
|
2178
|
+
return await fn();
|
|
2179
|
+
} finally {
|
|
2180
|
+
stacksInFlight -= 1;
|
|
2181
|
+
}
|
|
2182
|
+
},
|
|
2183
|
+
dispose: () => {
|
|
2184
|
+
process.removeListener("SIGINT", handler);
|
|
2185
|
+
}
|
|
2186
|
+
};
|
|
2187
|
+
}
|
|
2068
2188
|
|
|
2069
2189
|
//#endregion
|
|
2070
2190
|
//#region src/deployment/recreate-targets.ts
|
|
@@ -15927,17 +16047,60 @@ var ProtectionFlipRegistry = class {
|
|
|
15927
16047
|
/**
|
|
15928
16048
|
* The record for `key`, creating it on first use and REUSING it on re-entry.
|
|
15929
16049
|
*
|
|
15930
|
-
* `reuseWithinMs` bounds how long an entry may
|
|
15931
|
-
*
|
|
15932
|
-
*
|
|
15933
|
-
*
|
|
15934
|
-
*
|
|
15935
|
-
*
|
|
16050
|
+
* `reuseWithinMs` bounds how long an entry may sit UNUSED, and the window
|
|
16051
|
+
* SLIDES: every reuse restarts the stopwatch, so what is bounded is the idle
|
|
16052
|
+
* time since the last `acquire` rather than the entry's total lifetime. It is
|
|
16053
|
+
* passed the same `DELETE_BUDGET_REUSE_WINDOW_MS` the allowance uses, and it
|
|
16054
|
+
* is still needed for the reason it was introduced: entries are RETAINED on a
|
|
16055
|
+
* throw, so without any bound a retained record would let a much LATER
|
|
16056
|
+
* destroy of the same table re-enable a guard it never touched — the inverse
|
|
16057
|
+
* hazard of the one this record exists for.
|
|
16058
|
+
*
|
|
16059
|
+
* Measuring from FIRST acquisition instead is what issue #2211 reported, and
|
|
16060
|
+
* it re-creates issue #1978's residue through this very mechanism. The retry
|
|
16061
|
+
* sequence is unbounded while the window is a wall clock, so a
|
|
16062
|
+
* `--resource-timeout` overshoot past `DELETE_BUDGET_REUSE_WINDOW_MS` lets a
|
|
16063
|
+
* LIVE sequence age out MID-flight: `acquire` drops the entry and hands the
|
|
16064
|
+
* next attempt a fresh `{ flippedOffByThisRun: false }`, whose pre-flip
|
|
16065
|
+
* `DescribeTable` then observes the guard already OFF — because attempt 1
|
|
16066
|
+
* turned it off — so the latch stays `false` and a terminal failure
|
|
16067
|
+
* compensates nothing.
|
|
16068
|
+
*
|
|
16069
|
+
* KNOWN BOUND, stated because the obvious reading overclaims it. `acquire` is
|
|
16070
|
+
* called ONCE per `delete()`, at the top, and nothing touches the entry's
|
|
16071
|
+
* idle STOPWATCH again (the record's fields are mutated throughout, and
|
|
16072
|
+
* `release` drops it) — so the interval this measures is not a gap BETWEEN
|
|
16073
|
+
* operations, it is the previous ATTEMPT's own duration plus the outer loop's
|
|
16074
|
+
* backoff.
|
|
16075
|
+
*
|
|
16076
|
+
* That is normally comfortable, and the arithmetic is worth having right.
|
|
16077
|
+
* `DELETE_BUDGET_REUSE_WINDOW_MS` is `DYNAMODB_DELETE_BUDGET_MS` (26 min)
|
|
16078
|
+
* plus `DYNAMODB_DELETE_DEADLINE_MARGIN_MS` (4 min). The 26 minutes is the
|
|
16079
|
+
* allowance for the WHOLE retry sequence, not for one attempt —
|
|
16080
|
+
* `ElapsedBudgetRegistry.acquire` hands back the SAME budget on re-entry — so
|
|
16081
|
+
* a budget-conforming attempt plus one backoff is at most ~26m20s against a
|
|
16082
|
+
* 30-minute window, and the margin exists precisely to price that backoff.
|
|
16083
|
+
*
|
|
16084
|
+
* What can still age out a successor is therefore an attempt that OVERRUNS
|
|
16085
|
+
* the allowance rather than one that merely spends it: `attemptsWithin` keeps
|
|
16086
|
+
* a `minAttempts` floor poll even at zero remaining, and the auto-scaling
|
|
16087
|
+
* teardown is unpriced (see `src/utils/elapsed-budget.ts`). The slide removes
|
|
16088
|
+
* the ACCUMULATION case — many attempts summing past the window, the common
|
|
16089
|
+
* shape and the one issue #2211 reported — not the overrun one.
|
|
16090
|
+
*
|
|
16091
|
+
* Closing the remainder means sliding at attempt END too (a `touch(key)` in
|
|
16092
|
+
* `delete()`'s catch, making the measured gap the loop backoff rather than
|
|
16093
|
+
* the attempt), or sizing this window independently of the delete budget.
|
|
16094
|
+
* Both are behaviour changes to the delete path and belong in their own
|
|
16095
|
+
* change rather than riding this one.
|
|
15936
16096
|
*/
|
|
15937
16097
|
acquire(key, reuseWithinMs, clock = monotonicNowMs) {
|
|
15938
16098
|
const existing = this.records.get(key);
|
|
15939
16099
|
if (existing) {
|
|
15940
|
-
if (existing.
|
|
16100
|
+
if (existing.idle.elapsedMs() <= reuseWithinMs) {
|
|
16101
|
+
existing.idle = new ElapsedBudget(reuseWithinMs, clock);
|
|
16102
|
+
return existing.record;
|
|
16103
|
+
}
|
|
15941
16104
|
this.records.delete(key);
|
|
15942
16105
|
}
|
|
15943
16106
|
const created = {
|
|
@@ -15945,7 +16108,7 @@ var ProtectionFlipRegistry = class {
|
|
|
15945
16108
|
flippedOffByThisRun: false,
|
|
15946
16109
|
deleteAccepted: false
|
|
15947
16110
|
},
|
|
15948
|
-
|
|
16111
|
+
idle: new ElapsedBudget(reuseWithinMs, clock)
|
|
15949
16112
|
};
|
|
15950
16113
|
this.records.set(key, created);
|
|
15951
16114
|
return created.record;
|
|
@@ -16044,9 +16207,30 @@ async function compensateRemovedDeletionProtection(opts) {
|
|
|
16044
16207
|
await opts.reEnable();
|
|
16045
16208
|
opts.logger.warn(`DynamoDB ${opts.typeLabel} ${opts.logicalId}: the delete failed after --remove-protection had turned DeletionProtectionEnabled off, so it was re-enabled on ${opts.physicalId}. The delete failure below is the outcome.`);
|
|
16046
16209
|
} catch (reEnableError) {
|
|
16047
|
-
|
|
16210
|
+
const detail = reEnableError instanceof Error ? reEnableError.message : String(reEnableError);
|
|
16211
|
+
if (isResourceNotFoundError(reEnableError)) {
|
|
16212
|
+
const regionArg = opts.region ? ` --region ${opts.region}` : "";
|
|
16213
|
+
opts.logger.warn(`DynamoDB ${opts.typeLabel} ${opts.logicalId}: could not re-enable DeletionProtectionEnabled on ${opts.physicalId} after the delete failed — DynamoDB answered ResourceNotFound. That most commonly means the table is gone or its status is not ACTIVE, and it can also mean the table is not in this region or account. If it still exists, its deletion protection is OFF. Check with: aws dynamodb describe-table --table-name ${opts.physicalId}${regionArg} and if it is there, restore it with: aws dynamodb update-table --table-name ${opts.physicalId}${regionArg} --deletion-protection-enabled. (${detail})`);
|
|
16214
|
+
return;
|
|
16215
|
+
}
|
|
16216
|
+
opts.logger.error(`DynamoDB ${opts.typeLabel} ${opts.logicalId}: could NOT re-enable DeletionProtectionEnabled on ${opts.physicalId} after the delete failed — that table is LIVE with its deletion protection still off. Restore it with: aws dynamodb update-table --table-name ${opts.physicalId} --deletion-protection-enabled. (${detail})`);
|
|
16048
16217
|
}
|
|
16049
16218
|
}
|
|
16219
|
+
/**
|
|
16220
|
+
* Whether `error` is DynamoDB's `ResourceNotFoundException`.
|
|
16221
|
+
*
|
|
16222
|
+
* Keyed on the SDK's `name` rather than on `instanceof`, so this module keeps
|
|
16223
|
+
* its (deliberate) freedom from an `@aws-sdk/client-dynamodb` import and so a
|
|
16224
|
+
* second client instance of the class still matches.
|
|
16225
|
+
*
|
|
16226
|
+
* Deliberately NOT a `cause`-chain walk: every `reEnable` callback handed to
|
|
16227
|
+
* {@link compensateRemovedDeletionProtection} is a bare `UpdateTable` send, so
|
|
16228
|
+
* the SDK error arrives unwrapped. If one ever wraps its call, this answers
|
|
16229
|
+
* `false` and the compensation keeps the LOUD error line — the safe direction.
|
|
16230
|
+
*/
|
|
16231
|
+
function isResourceNotFoundError(error) {
|
|
16232
|
+
return typeof error === "object" && error !== null && error.name === "ResourceNotFoundException";
|
|
16233
|
+
}
|
|
16050
16234
|
|
|
16051
16235
|
//#endregion
|
|
16052
16236
|
//#region src/provisioning/providers/dynamodb-table-provider.ts
|
|
@@ -17007,6 +17191,7 @@ var DynamoDBTableProvider = class {
|
|
|
17007
17191
|
physicalId,
|
|
17008
17192
|
typeLabel: "table",
|
|
17009
17193
|
logger: this.logger,
|
|
17194
|
+
...context?.expectedRegion ? { region: context.expectedRegion } : {},
|
|
17010
17195
|
reEnable: async () => {
|
|
17011
17196
|
await this.dynamoDBClient.send(new UpdateTableCommand({
|
|
17012
17197
|
TableName: physicalId,
|
|
@@ -19573,6 +19758,7 @@ var DynamoDBGlobalTableProvider = class {
|
|
|
19573
19758
|
physicalId,
|
|
19574
19759
|
typeLabel: "GlobalTable",
|
|
19575
19760
|
logger: this.logger,
|
|
19761
|
+
...context?.expectedRegion ? { region: context.expectedRegion } : {},
|
|
19576
19762
|
reEnable: async () => {
|
|
19577
19763
|
await this.dynamoDBClient.send(new UpdateTableCommand({
|
|
19578
19764
|
TableName: physicalId,
|
|
@@ -68211,7 +68397,14 @@ async function destroyCommand(stackArgs, options) {
|
|
|
68211
68397
|
...options.profile && { profile: options.profile }
|
|
68212
68398
|
});
|
|
68213
68399
|
setAwsClients(awsClients);
|
|
68214
|
-
const
|
|
68400
|
+
const interruptWatch = watchCommandInterrupt({ command: "cdkd destroy" });
|
|
68401
|
+
let unforwardSigterm;
|
|
68402
|
+
try {
|
|
68403
|
+
unforwardSigterm = forwardSigtermToSigint();
|
|
68404
|
+
} catch (error) {
|
|
68405
|
+
interruptWatch.dispose();
|
|
68406
|
+
throw error;
|
|
68407
|
+
}
|
|
68215
68408
|
try {
|
|
68216
68409
|
const stateConfig = {
|
|
68217
68410
|
bucket: stateBucket,
|
|
@@ -68271,6 +68464,7 @@ async function destroyCommand(stackArgs, options) {
|
|
|
68271
68464
|
let totalErrors = 0;
|
|
68272
68465
|
let totalSkipped = 0;
|
|
68273
68466
|
let interrupted = false;
|
|
68467
|
+
const runInterrupted = () => interrupted || interruptWatch.interrupted();
|
|
68274
68468
|
let stackNames;
|
|
68275
68469
|
if (options.all) stackNames = candidateStacks.map((s) => s.stackName);
|
|
68276
68470
|
else if (stackPatterns.length > 0) stackNames = matchStacks(candidateStacks, stackPatterns).map((s) => s.stackName);
|
|
@@ -68347,6 +68541,7 @@ async function destroyCommand(stackArgs, options) {
|
|
|
68347
68541
|
totalErrors++;
|
|
68348
68542
|
continue;
|
|
68349
68543
|
}
|
|
68544
|
+
if (runInterrupted()) break;
|
|
68350
68545
|
const eventRecorder = startRunRecorder({
|
|
68351
68546
|
backend: stateBackend,
|
|
68352
68547
|
stackName,
|
|
@@ -68355,7 +68550,7 @@ async function destroyCommand(stackArgs, options) {
|
|
|
68355
68550
|
});
|
|
68356
68551
|
let destroyRunResult = "SUCCEEDED";
|
|
68357
68552
|
try {
|
|
68358
|
-
const result = await withNestedStackContext({
|
|
68553
|
+
const result = await interruptWatch.runStack(() => withNestedStackContext({
|
|
68359
68554
|
stateBackend,
|
|
68360
68555
|
lockManager,
|
|
68361
68556
|
providerRegistry,
|
|
@@ -68394,7 +68589,7 @@ async function destroyCommand(stackArgs, options) {
|
|
|
68394
68589
|
...options.resourceWarnAfter?.perTypeMs && { resourceWarnAfterByType: options.resourceWarnAfter.perTypeMs },
|
|
68395
68590
|
...options.resourceTimeout?.perTypeMs && { resourceTimeoutByType: options.resourceTimeout.perTypeMs },
|
|
68396
68591
|
eventRecorder
|
|
68397
|
-
}));
|
|
68592
|
+
})));
|
|
68398
68593
|
totalErrors += result.errorCount;
|
|
68399
68594
|
totalSkipped += result.skippedCount;
|
|
68400
68595
|
if (result.interrupted) interrupted = true;
|
|
@@ -68421,15 +68616,16 @@ async function destroyCommand(stackArgs, options) {
|
|
|
68421
68616
|
await purgeEventsAfterDestroy(new DeploymentEventsReader(stateBackend), stackName, stackTargetRegion, {
|
|
68422
68617
|
purgeEvents: options.purgeEvents,
|
|
68423
68618
|
runResult: destroyRunResult,
|
|
68424
|
-
interrupted
|
|
68619
|
+
interrupted: runInterrupted()
|
|
68425
68620
|
}, logger);
|
|
68426
|
-
if (
|
|
68621
|
+
if (runInterrupted()) break;
|
|
68427
68622
|
}
|
|
68428
68623
|
if (totalErrors > 0) throw new PartialFailureError(`Destroy completed with ${totalErrors} resource error(s). State preserved — inspect 'cdkd state show <stack>' and re-run 'cdkd destroy' to retry. If the same resource keeps failing, 'cdkd state orphan <stack>' removes the state record without deleting AWS resources.`);
|
|
68429
|
-
if (
|
|
68624
|
+
if (runInterrupted()) throw new PartialFailureError(`Destroy interrupted by Ctrl-C. State preserved — re-run 'cdkd destroy' to finish.`);
|
|
68430
68625
|
if (totalSkipped > 0) throw new PartialFailureError(`Destroy skipped ${totalSkipped} entr${totalSkipped === 1 ? "y" : "ies"} cdkd could not address, so the underlying resources may still exist in AWS. A skipped nested stack counts as ONE entry and may cover several of its own resources — the per-stack summaries above give the exact breakdown. State preserved (the records are kept). Repair the physicalId in state.json and re-run 'cdkd destroy', or delete the resources by hand and drop the records with 'cdkd state orphan <stack>'.`);
|
|
68431
68626
|
} finally {
|
|
68432
68627
|
unforwardSigterm();
|
|
68628
|
+
interruptWatch.dispose();
|
|
68433
68629
|
awsClients.destroy();
|
|
68434
68630
|
}
|
|
68435
68631
|
}
|
|
@@ -72997,7 +73193,14 @@ async function stateDestroyCommand(stackArgs, options) {
|
|
|
72997
73193
|
registerAllProviders(providerRegistry);
|
|
72998
73194
|
providerRegistry.setCustomResourceResponseBucket(setup.bucket);
|
|
72999
73195
|
if (options.allowUnsupportedTypes?.length) providerRegistry.allowUnsupportedTypes(options.allowUnsupportedTypes);
|
|
73000
|
-
const
|
|
73196
|
+
const interruptWatch = watchCommandInterrupt({ command: "cdkd state destroy" });
|
|
73197
|
+
let unforwardSigterm;
|
|
73198
|
+
try {
|
|
73199
|
+
unforwardSigterm = forwardSigtermToSigint();
|
|
73200
|
+
} catch (error) {
|
|
73201
|
+
interruptWatch.dispose();
|
|
73202
|
+
throw error;
|
|
73203
|
+
}
|
|
73001
73204
|
try {
|
|
73002
73205
|
const stateRefs = await setup.stateBackend.listStacks();
|
|
73003
73206
|
const knownStackNames = new Set(stateRefs.map((r) => r.stackName));
|
|
@@ -73033,6 +73236,7 @@ async function stateDestroyCommand(stackArgs, options) {
|
|
|
73033
73236
|
let totalErrors = 0;
|
|
73034
73237
|
let totalSkipped = 0;
|
|
73035
73238
|
let interrupted = false;
|
|
73239
|
+
const runInterrupted = () => interrupted || interruptWatch.interrupted();
|
|
73036
73240
|
for (const stackName of stackNames) {
|
|
73037
73241
|
const refs = stateRefs.filter((r) => r.stackName === stackName);
|
|
73038
73242
|
let targets;
|
|
@@ -73054,7 +73258,8 @@ async function stateDestroyCommand(stackArgs, options) {
|
|
|
73054
73258
|
logger.warn(`No state found for stack ${stackName}${ref.region ? ` in ${ref.region}` : ""}, skipping`);
|
|
73055
73259
|
continue;
|
|
73056
73260
|
}
|
|
73057
|
-
|
|
73261
|
+
if (runInterrupted()) break;
|
|
73262
|
+
const result = await interruptWatch.runStack(() => withNestedStackContext({
|
|
73058
73263
|
stateBackend: setup.stateBackend,
|
|
73059
73264
|
lockManager: setup.lockManager,
|
|
73060
73265
|
providerRegistry,
|
|
@@ -73092,19 +73297,20 @@ async function stateDestroyCommand(stackArgs, options) {
|
|
|
73092
73297
|
...options.resourceTimeout?.globalMs !== void 0 && { resourceTimeoutMs: options.resourceTimeout.globalMs },
|
|
73093
73298
|
...options.resourceWarnAfter?.perTypeMs && { resourceWarnAfterByType: options.resourceWarnAfter.perTypeMs },
|
|
73094
73299
|
...options.resourceTimeout?.perTypeMs && { resourceTimeoutByType: options.resourceTimeout.perTypeMs }
|
|
73095
|
-
}));
|
|
73300
|
+
})));
|
|
73096
73301
|
totalErrors += result.errorCount;
|
|
73097
73302
|
totalSkipped += result.skippedCount;
|
|
73098
73303
|
if (result.interrupted) interrupted = true;
|
|
73099
|
-
if (
|
|
73304
|
+
if (runInterrupted()) break;
|
|
73100
73305
|
}
|
|
73101
|
-
if (
|
|
73306
|
+
if (runInterrupted()) break;
|
|
73102
73307
|
}
|
|
73103
73308
|
if (totalErrors > 0) throw new PartialFailureError(`Destroy completed with ${totalErrors} resource error(s). State preserved — inspect 'cdkd state show <stack>' and re-run 'cdkd state destroy' to retry. If the same resource keeps failing, 'cdkd state orphan <stack>' removes the state record without deleting AWS resources.`);
|
|
73104
|
-
if (
|
|
73309
|
+
if (runInterrupted()) throw new PartialFailureError(`Destroy interrupted by Ctrl-C. State preserved — re-run 'cdkd state destroy' to finish.`);
|
|
73105
73310
|
if (totalSkipped > 0) throw new PartialFailureError(`Destroy skipped ${totalSkipped} entr${totalSkipped === 1 ? "y" : "ies"} cdkd could not address, so the underlying resources may still exist in AWS. A skipped nested stack counts as ONE entry and may cover several of its own resources — the per-stack summaries above give the exact breakdown. State preserved (the records are kept). Repair the physicalId in state.json and re-run 'cdkd state destroy', or delete the resources by hand and drop the records with 'cdkd state orphan <stack>'.`);
|
|
73106
73311
|
} finally {
|
|
73107
73312
|
unforwardSigterm();
|
|
73313
|
+
interruptWatch.dispose();
|
|
73108
73314
|
setup.dispose();
|
|
73109
73315
|
}
|
|
73110
73316
|
}
|
|
@@ -87364,4 +87570,4 @@ function buildProgram() {
|
|
|
87364
87570
|
|
|
87365
87571
|
//#endregion
|
|
87366
87572
|
export { buildProgram };
|
|
87367
|
-
//# sourceMappingURL=program-
|
|
87573
|
+
//# sourceMappingURL=program-BsvNn8Y3.js.map
|