@firestartr/cli 2.11.0-snapshot-import-filter-fix → 2.11.0-snapshot-importer-filter-fix-3
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/build/index.js +710 -242
- package/build/packages/cdk8s_renderer/src/refresolver/index.d.ts +1 -0
- package/build/packages/cdk8s_renderer/src/renderer/import-renderer.d.ts +5 -0
- package/build/packages/github/index.d.ts +1 -1
- package/build/packages/github/src/check_run.d.ts +12 -0
- package/build/packages/github/src/with_profile.d.ts +2 -1
- package/build/packages/operator/src/user-feedback-ops/user-feedback-ops.d.ts +24 -0
- package/build/packages/terraform_provisioner/src/debug.d.ts +3 -0
- package/build/packages/terraform_provisioner/src/project_tf.d.ts +2 -2
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -134117,6 +134117,7 @@ class GithubCheckRun {
|
|
|
134117
134117
|
this.pullNumber = params.pullNumber;
|
|
134118
134118
|
this.includeCheckRunComment = Boolean(params.includeCheckRunComment);
|
|
134119
134119
|
this.checkRunComment = params.checkRunComment;
|
|
134120
|
+
this.stickyCommentBaseKind = params.stickyCommentBaseKind;
|
|
134120
134121
|
this.buffer = new CheckRunBuffer('', (data) => this.__updateCheckRun(data).catch(() => { }), { intervalSec: FLUSH_TIMEOUT });
|
|
134121
134122
|
}
|
|
134122
134123
|
/**
|
|
@@ -134188,7 +134189,13 @@ class GithubCheckRun {
|
|
|
134188
134189
|
text,
|
|
134189
134190
|
},
|
|
134190
134191
|
});
|
|
134191
|
-
|
|
134192
|
+
// With a shared sticky base kind, the result publisher targeting the
|
|
134193
|
+
// same base kind is always the last word: close() performs no sticky
|
|
134194
|
+
// rewrite (it could otherwise land after the result publish on error
|
|
134195
|
+
// paths and clobber it with a stale progress comment).
|
|
134196
|
+
if (this.includeCheckRunComment &&
|
|
134197
|
+
this.pullNumber !== undefined &&
|
|
134198
|
+
!this.stickyCommentBaseKind) {
|
|
134192
134199
|
try {
|
|
134193
134200
|
await this.__ensureAndUpdateStickyComment(this.__buildCheckRunUrl());
|
|
134194
134201
|
this.hasCommented = true;
|
|
@@ -134253,7 +134260,14 @@ class GithubCheckRun {
|
|
|
134253
134260
|
text,
|
|
134254
134261
|
},
|
|
134255
134262
|
});
|
|
134256
|
-
|
|
134263
|
+
// After the awaits above, close() may have begun. With a shared sticky
|
|
134264
|
+
// base kind the result publisher must be the last word, so an in-flight
|
|
134265
|
+
// progress upsert must not land after it. Legacy flows (no shared base
|
|
134266
|
+
// kind) keep their current behavior.
|
|
134267
|
+
const closedMidFlight = this.stickyCommentBaseKind && (this.closed || this.closing);
|
|
134268
|
+
if (this.includeCheckRunComment &&
|
|
134269
|
+
this.pullNumber !== undefined &&
|
|
134270
|
+
!closedMidFlight) {
|
|
134257
134271
|
try {
|
|
134258
134272
|
await this.__ensureAndUpdateStickyComment(this.__buildCheckRunUrl());
|
|
134259
134273
|
}
|
|
@@ -134300,7 +134314,7 @@ class GithubCheckRun {
|
|
|
134300
134314
|
owner: this.owner,
|
|
134301
134315
|
repo: this.repo,
|
|
134302
134316
|
pullNumber: this.pullNumber,
|
|
134303
|
-
baseKind: `check-run:${this.name}`,
|
|
134317
|
+
baseKind: this.stickyCommentBaseKind ?? `check-run:${this.name}`,
|
|
134304
134318
|
bodies: [linkLine],
|
|
134305
134319
|
});
|
|
134306
134320
|
}
|
|
@@ -134338,6 +134352,7 @@ async function createCheckRunForOrg(org, owner, repo, name, opts) {
|
|
|
134338
134352
|
pullNumber: opts?.pullNumber,
|
|
134339
134353
|
includeCheckRunComment: Boolean(opts?.includeCheckRunComment),
|
|
134340
134354
|
checkRunComment: opts?.checkRunComment,
|
|
134355
|
+
stickyCommentBaseKind: opts?.stickyCommentBaseKind,
|
|
134341
134356
|
});
|
|
134342
134357
|
}
|
|
134343
134358
|
async function createCheckRun(owner, repo, name, opts) {
|
|
@@ -134790,6 +134805,7 @@ function createFacade(profileName) {
|
|
|
134790
134805
|
pullNumber: opts?.pullNumber,
|
|
134791
134806
|
includeCheckRunComment: Boolean(opts?.includeCheckRunComment),
|
|
134792
134807
|
checkRunComment: opts?.checkRunComment,
|
|
134808
|
+
stickyCommentBaseKind: opts?.stickyCommentBaseKind,
|
|
134793
134809
|
});
|
|
134794
134810
|
},
|
|
134795
134811
|
CheckRun: CheckRun,
|
|
@@ -134943,6 +134959,100 @@ async function checkIfInstalledForOrg(org = 'default') {
|
|
|
134943
134959
|
}
|
|
134944
134960
|
|
|
134945
134961
|
|
|
134962
|
+
/***/ }),
|
|
134963
|
+
|
|
134964
|
+
/***/ 16907:
|
|
134965
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __nccwpck_require__) => {
|
|
134966
|
+
|
|
134967
|
+
__nccwpck_require__.r(__webpack_exports__);
|
|
134968
|
+
/* harmony export */ __nccwpck_require__.d(__webpack_exports__, {
|
|
134969
|
+
/* harmony export */ "initTfDebug": () => (/* binding */ initTfDebug),
|
|
134970
|
+
/* harmony export */ "writeConfig": () => (/* binding */ writeConfig),
|
|
134971
|
+
/* harmony export */ "writeTfOutput": () => (/* binding */ writeTfOutput)
|
|
134972
|
+
/* harmony export */ });
|
|
134973
|
+
/* harmony import */ var catalog_common__WEBPACK_IMPORTED_MODULE_0__ = __nccwpck_require__(78542);
|
|
134974
|
+
/* harmony import */ var fs_promises__WEBPACK_IMPORTED_MODULE_1__ = __nccwpck_require__(73292);
|
|
134975
|
+
/* harmony import */ var fs_promises__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__nccwpck_require__.n(fs_promises__WEBPACK_IMPORTED_MODULE_1__);
|
|
134976
|
+
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __nccwpck_require__(71017);
|
|
134977
|
+
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__nccwpck_require__.n(path__WEBPACK_IMPORTED_MODULE_2__);
|
|
134978
|
+
/* harmony import */ var _logger__WEBPACK_IMPORTED_MODULE_3__ = __nccwpck_require__(31986);
|
|
134979
|
+
|
|
134980
|
+
|
|
134981
|
+
|
|
134982
|
+
|
|
134983
|
+
const DEBUG_PREFIX = '/tmp/tf-debug/';
|
|
134984
|
+
async function initTfDebug(ctx) {
|
|
134985
|
+
try {
|
|
134986
|
+
const projectPath = ctx?.projectPath;
|
|
134987
|
+
if (!projectPath || !projectPath.startsWith(DEBUG_PREFIX))
|
|
134988
|
+
return;
|
|
134989
|
+
// Normalize projectPath by stripping a trailing UUID-like suffix from the
|
|
134990
|
+
// final path segment. This makes the debug folder deterministic even if
|
|
134991
|
+
// callers still supply a name with an embedded tfStateKey or uuid suffix.
|
|
134992
|
+
const dir = path__WEBPACK_IMPORTED_MODULE_2__.dirname(projectPath);
|
|
134993
|
+
const name = path__WEBPACK_IMPORTED_MODULE_2__.basename(projectPath);
|
|
134994
|
+
const baseName = name.replace(/-[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/, '');
|
|
134995
|
+
const normalizedProjectPath = path__WEBPACK_IMPORTED_MODULE_2__.join(dir, baseName);
|
|
134996
|
+
// Ensure the session project dir and a dedicated subdir for
|
|
134997
|
+
// terraform_provisioner exist. Do NOT remove an existing deterministic
|
|
134998
|
+
// debug folder here — removing it during build() breaks the reuse
|
|
134999
|
+
// validation when build() is invoked a second time for output().
|
|
135000
|
+
await fs_promises__WEBPACK_IMPORTED_MODULE_1__.mkdir(normalizedProjectPath, { recursive: true });
|
|
135001
|
+
const debugArtifactsDir = path__WEBPACK_IMPORTED_MODULE_2__.join(normalizedProjectPath, 'tf_provisioner_debug');
|
|
135002
|
+
await fs_promises__WEBPACK_IMPORTED_MODULE_1__.mkdir(debugArtifactsDir, { recursive: true });
|
|
135003
|
+
// Write cr.yaml and deps.yaml if provided on context
|
|
135004
|
+
if (ctx.rawCr) {
|
|
135005
|
+
await fs_promises__WEBPACK_IMPORTED_MODULE_1__.writeFile(path__WEBPACK_IMPORTED_MODULE_2__.join(debugArtifactsDir, 'cr.yaml'), catalog_common__WEBPACK_IMPORTED_MODULE_0__/* ["default"].io.toYaml */ .Z.io.toYaml(ctx.rawCr));
|
|
135006
|
+
}
|
|
135007
|
+
if (ctx.deps) {
|
|
135008
|
+
await fs_promises__WEBPACK_IMPORTED_MODULE_1__.writeFile(path__WEBPACK_IMPORTED_MODULE_2__.join(debugArtifactsDir, 'deps.yaml'), catalog_common__WEBPACK_IMPORTED_MODULE_0__/* ["default"].io.toYaml */ .Z.io.toYaml(ctx.deps));
|
|
135009
|
+
}
|
|
135010
|
+
// Enable file logging for debug runs
|
|
135011
|
+
_logger__WEBPACK_IMPORTED_MODULE_3__/* ["default"].enableFileLogging */ .Z.enableFileLogging(path__WEBPACK_IMPORTED_MODULE_2__.join(debugArtifactsDir, 'debug.log'));
|
|
135012
|
+
}
|
|
135013
|
+
catch (e) {
|
|
135014
|
+
_logger__WEBPACK_IMPORTED_MODULE_3__/* ["default"].warn */ .Z.warn(`[terraform-provisioner]: failed to init tf debug artifacts: ${e}`);
|
|
135015
|
+
}
|
|
135016
|
+
}
|
|
135017
|
+
async function writeTfOutput(projectPath, output) {
|
|
135018
|
+
try {
|
|
135019
|
+
if (!projectPath || !projectPath.startsWith(DEBUG_PREFIX))
|
|
135020
|
+
return;
|
|
135021
|
+
const debugArtifactsDir = path__WEBPACK_IMPORTED_MODULE_2__.join(projectPath, 'tf_provisioner_debug');
|
|
135022
|
+
await fs_promises__WEBPACK_IMPORTED_MODULE_1__.mkdir(debugArtifactsDir, { recursive: true });
|
|
135023
|
+
await fs_promises__WEBPACK_IMPORTED_MODULE_1__.writeFile(path__WEBPACK_IMPORTED_MODULE_2__.join(debugArtifactsDir, 'terraform-output.txt'), output);
|
|
135024
|
+
}
|
|
135025
|
+
catch (e) {
|
|
135026
|
+
_logger__WEBPACK_IMPORTED_MODULE_3__/* ["default"].warn */ .Z.warn(`[terraform-provisioner]: failed to write terraform output: ${e}`);
|
|
135027
|
+
}
|
|
135028
|
+
}
|
|
135029
|
+
async function writeConfig(projectPath, config) {
|
|
135030
|
+
try {
|
|
135031
|
+
if (!projectPath || !projectPath.startsWith(DEBUG_PREFIX))
|
|
135032
|
+
return;
|
|
135033
|
+
const debugArtifactsDir = path__WEBPACK_IMPORTED_MODULE_2__.join(projectPath, 'tf_provisioner_debug');
|
|
135034
|
+
await fs_promises__WEBPACK_IMPORTED_MODULE_1__.mkdir(debugArtifactsDir, { recursive: true });
|
|
135035
|
+
await fs_promises__WEBPACK_IMPORTED_MODULE_1__.writeFile(path__WEBPACK_IMPORTED_MODULE_2__.join(debugArtifactsDir, 'config.json'), JSON.stringify(config, null, 2));
|
|
135036
|
+
}
|
|
135037
|
+
catch (e) {
|
|
135038
|
+
_logger__WEBPACK_IMPORTED_MODULE_3__/* ["default"].warn */ .Z.warn(`[terraform-provisioner]: failed to write config.json: ${e}`);
|
|
135039
|
+
}
|
|
135040
|
+
}
|
|
135041
|
+
|
|
135042
|
+
|
|
135043
|
+
/***/ }),
|
|
135044
|
+
|
|
135045
|
+
/***/ 31986:
|
|
135046
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __nccwpck_require__) => {
|
|
135047
|
+
|
|
135048
|
+
/* harmony export */ __nccwpck_require__.d(__webpack_exports__, {
|
|
135049
|
+
/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
135050
|
+
/* harmony export */ });
|
|
135051
|
+
/* harmony import */ var catalog_common__WEBPACK_IMPORTED_MODULE_0__ = __nccwpck_require__(78542);
|
|
135052
|
+
|
|
135053
|
+
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (catalog_common__WEBPACK_IMPORTED_MODULE_0__/* ["default"].logger */ .Z.logger);
|
|
135054
|
+
|
|
135055
|
+
|
|
134946
135056
|
/***/ }),
|
|
134947
135057
|
|
|
134948
135058
|
/***/ 71421:
|
|
@@ -160443,6 +160553,13 @@ InitializerClaimRef.applicableKinds = [
|
|
|
160443
160553
|
* and the value is the rendered CR
|
|
160444
160554
|
*/
|
|
160445
160555
|
let renderedClaims = {};
|
|
160556
|
+
/**
|
|
160557
|
+
* previousClaimsSymbols holds previously rendered claims (from prior import
|
|
160558
|
+
* runs, e.g. the CRs already present on disk) keyed by claim kind and name.
|
|
160559
|
+
* It is only consulted as a fallback when a claim reference is not part of the
|
|
160560
|
+
* current render run but still exists as a previous CR.
|
|
160561
|
+
*/
|
|
160562
|
+
let previousClaimsSymbols = {};
|
|
160446
160563
|
|
|
160447
160564
|
function setRenderedClaim(claim, cr) {
|
|
160448
160565
|
const claimKey = `${claim.kind}-${claim.name}`;
|
|
@@ -160452,8 +160569,12 @@ function setRenderedClaim(claim, cr) {
|
|
|
160452
160569
|
}
|
|
160453
160570
|
renderedClaims[claimKey] = cr;
|
|
160454
160571
|
}
|
|
160572
|
+
function setPreviousClaimsSymbols(symbols) {
|
|
160573
|
+
previousClaimsSymbols = symbols ?? {};
|
|
160574
|
+
}
|
|
160455
160575
|
function emptyRenderedClaims() {
|
|
160456
160576
|
renderedClaims = {};
|
|
160577
|
+
previousClaimsSymbols = {};
|
|
160457
160578
|
}
|
|
160458
160579
|
/**
|
|
160459
160580
|
* Resolves a claim reference
|
|
@@ -160466,9 +160587,13 @@ function resolveClaimRef(kind, name, symbolsTable = renderedClaims) {
|
|
|
160466
160587
|
if (symbolsTable[`${kind}-${name}`]) {
|
|
160467
160588
|
return symbolsTable[`${kind}-${name}`];
|
|
160468
160589
|
}
|
|
160469
|
-
|
|
160470
|
-
|
|
160590
|
+
if (symbolsTable === renderedClaims) {
|
|
160591
|
+
const previousCr = previousClaimsSymbols[`${kind}-${name}`];
|
|
160592
|
+
if (previousCr) {
|
|
160593
|
+
return previousCr;
|
|
160594
|
+
}
|
|
160471
160595
|
}
|
|
160596
|
+
throw new Error(`Claim ${kind}-${name} not found`);
|
|
160472
160597
|
}
|
|
160473
160598
|
|
|
160474
160599
|
;// CONCATENATED MODULE: ../cdk8s_renderer/src/utils/repositoryClaimUtils.ts
|
|
@@ -171316,19 +171441,18 @@ const ORG_ROLE_ANNOTATION = 'firestartr.backstage.dev/org-role';
|
|
|
171316
171441
|
class CatalogUserChart extends BaseCatalogChart {
|
|
171317
171442
|
template() {
|
|
171318
171443
|
const claim = this.get('claim');
|
|
171319
|
-
const explicitOrgRole = claim.annotations?.[ORG_ROLE_ANNOTATION];
|
|
171320
171444
|
const inferredOrgRole = claim.providers &&
|
|
171321
171445
|
typeof claim.providers === 'object' &&
|
|
171322
171446
|
'github' in claim.providers &&
|
|
171323
171447
|
claim.providers.github?.role === 'admin'
|
|
171324
171448
|
? 'owner'
|
|
171325
171449
|
: undefined;
|
|
171326
|
-
const
|
|
171450
|
+
const { [ORG_ROLE_ANNOTATION]: _, ...claimAnnotations } = claim.annotations || {};
|
|
171327
171451
|
const annotations = {
|
|
171328
|
-
...
|
|
171452
|
+
...claimAnnotations,
|
|
171329
171453
|
};
|
|
171330
|
-
if (
|
|
171331
|
-
annotations[ORG_ROLE_ANNOTATION] =
|
|
171454
|
+
if (inferredOrgRole) {
|
|
171455
|
+
annotations[ORG_ROLE_ANNOTATION] = inferredOrgRole;
|
|
171332
171456
|
}
|
|
171333
171457
|
return {
|
|
171334
171458
|
apiVersion: 'backstage.io/v1alpha1',
|
|
@@ -172826,6 +172950,8 @@ function walkArray(arr, symbolsToResolve, renderClaim) {
|
|
|
172826
172950
|
|
|
172827
172951
|
|
|
172828
172952
|
|
|
172953
|
+
|
|
172954
|
+
|
|
172829
172955
|
/*
|
|
172830
172956
|
* Function called when rendering from the importer class.
|
|
172831
172957
|
*
|
|
@@ -172849,8 +172975,9 @@ async function renderFromImports(rClaims, crs = {}, catalogOutputDir = '/tmp/.ca
|
|
|
172849
172975
|
}
|
|
172850
172976
|
// type: is the kind of the claim
|
|
172851
172977
|
// value: is the imported-ref (the name in Github, can be with special characters, spaces, etc)
|
|
172978
|
+
const previousClaimsIndex = buildPreviousClaimsIndex(crs);
|
|
172852
172979
|
const fSolver = (type, value) => {
|
|
172853
|
-
return solver(type, value, rClaims);
|
|
172980
|
+
return solver(type, value, rClaims, previousClaimsIndex);
|
|
172854
172981
|
};
|
|
172855
172982
|
try {
|
|
172856
172983
|
// we need to expand the imported-refs
|
|
@@ -172880,6 +173007,9 @@ async function renderFromImports(rClaims, crs = {}, catalogOutputDir = '/tmp/.ca
|
|
|
172880
173007
|
outputFileExtension: '.yaml',
|
|
172881
173008
|
yamlOutputType: lib.YamlOutputType.FILE_PER_RESOURCE,
|
|
172882
173009
|
});
|
|
173010
|
+
// Claims skipped from this run (e.g. by fCheckCRExistsOnDisk) but still
|
|
173011
|
+
// present as previous CRs must be resolvable by charts that reference them.
|
|
173012
|
+
setPreviousClaimsSymbols(buildPreviousClaimsSymbols(crs));
|
|
172883
173013
|
const result = await renderClaims(catalogScope, firestartrScope, { renderClaims: rClaims, crs, renames: [] });
|
|
172884
173014
|
firestartrScope.synth();
|
|
172885
173015
|
if (crOutputDir) {
|
|
@@ -172887,8 +173017,58 @@ async function renderFromImports(rClaims, crs = {}, catalogOutputDir = '/tmp/.ca
|
|
|
172887
173017
|
}
|
|
172888
173018
|
return result;
|
|
172889
173019
|
}
|
|
172890
|
-
|
|
172891
|
-
|
|
173020
|
+
function buildPreviousClaimsIndex(crs) {
|
|
173021
|
+
const index = {
|
|
173022
|
+
user: new Map(),
|
|
173023
|
+
group: new Map(),
|
|
173024
|
+
};
|
|
173025
|
+
for (const cr of Object.values(crs ?? {})) {
|
|
173026
|
+
const anyCr = cr;
|
|
173027
|
+
const kind = anyCr?.kind;
|
|
173028
|
+
const externalName = anyCr?.metadata?.annotations?.[catalog_common/* default.generic.getFirestartrAnnotation */.Z.generic.getFirestartrAnnotation('external-name')];
|
|
173029
|
+
const claimRef = anyCr?.metadata?.annotations?.[catalog_common/* default.generic.getFirestartrAnnotation */.Z.generic.getFirestartrAnnotation('claim-ref')];
|
|
173030
|
+
if (!kind || !externalName || !claimRef) {
|
|
173031
|
+
continue;
|
|
173032
|
+
}
|
|
173033
|
+
const claimName = claimRef.split('/')[1];
|
|
173034
|
+
if (!claimName) {
|
|
173035
|
+
continue;
|
|
173036
|
+
}
|
|
173037
|
+
if (kind === 'FirestartrGithubMembership') {
|
|
173038
|
+
index.user.set(externalName, claimName);
|
|
173039
|
+
}
|
|
173040
|
+
else if (kind === 'FirestartrGithubGroup') {
|
|
173041
|
+
index.group.set(externalName, claimName);
|
|
173042
|
+
}
|
|
173043
|
+
}
|
|
173044
|
+
return index;
|
|
173045
|
+
}
|
|
173046
|
+
function buildPreviousClaimsSymbols(crs) {
|
|
173047
|
+
const symbols = {};
|
|
173048
|
+
for (const cr of Object.values(crs ?? {})) {
|
|
173049
|
+
const anyCr = cr;
|
|
173050
|
+
const kind = anyCr?.kind;
|
|
173051
|
+
const claimRef = anyCr?.metadata?.annotations?.[catalog_common/* default.generic.getFirestartrAnnotation */.Z.generic.getFirestartrAnnotation('claim-ref')];
|
|
173052
|
+
if (!kind || !claimRef) {
|
|
173053
|
+
continue;
|
|
173054
|
+
}
|
|
173055
|
+
const claimName = claimRef.split('/')[1];
|
|
173056
|
+
if (!claimName) {
|
|
173057
|
+
continue;
|
|
173058
|
+
}
|
|
173059
|
+
const claimKind = kind === 'FirestartrGithubMembership'
|
|
173060
|
+
? 'UserClaim'
|
|
173061
|
+
: kind === 'FirestartrGithubGroup'
|
|
173062
|
+
? 'GroupClaim'
|
|
173063
|
+
: undefined;
|
|
173064
|
+
if (!claimKind) {
|
|
173065
|
+
continue;
|
|
173066
|
+
}
|
|
173067
|
+
symbols[`${claimKind}-${claimName}`] = anyCr;
|
|
173068
|
+
}
|
|
173069
|
+
return symbols;
|
|
173070
|
+
}
|
|
173071
|
+
async function solver(type, value, rClaims, previousClaimsIndex) {
|
|
172892
173072
|
const claimKind = type === 'user' ? 'UserClaim' : 'GroupClaim';
|
|
172893
173073
|
for (const key in rClaims) {
|
|
172894
173074
|
if (key.startsWith(claimKind)) {
|
|
@@ -172898,6 +173078,12 @@ async function solver(type, value, rClaims) {
|
|
|
172898
173078
|
}
|
|
172899
173079
|
}
|
|
172900
173080
|
}
|
|
173081
|
+
const previousClaimName = type === 'user'
|
|
173082
|
+
? previousClaimsIndex.user.get(value)
|
|
173083
|
+
: previousClaimsIndex.group.get(value);
|
|
173084
|
+
if (previousClaimName) {
|
|
173085
|
+
return `${type}:${previousClaimName}`;
|
|
173086
|
+
}
|
|
172901
173087
|
throw new Error(`Could not resolve imported-ref of type ${type} with value ${value}`);
|
|
172902
173088
|
}
|
|
172903
173089
|
|
|
@@ -360977,10 +361163,8 @@ class TFPlanItemVersion extends TFPlanItem {
|
|
|
360977
361163
|
}
|
|
360978
361164
|
}
|
|
360979
361165
|
|
|
360980
|
-
|
|
360981
|
-
|
|
360982
|
-
/* harmony default export */ const terraform_provisioner_src_logger = (catalog_common/* default.logger */.Z.logger);
|
|
360983
|
-
|
|
361166
|
+
// EXTERNAL MODULE: ../terraform_provisioner/src/logger.ts
|
|
361167
|
+
var terraform_provisioner_src_logger = __nccwpck_require__(31986);
|
|
360984
361168
|
;// CONCATENATED MODULE: ../terraform_provisioner/src/process_handler.ts
|
|
360985
361169
|
|
|
360986
361170
|
const GRACE_PERIOD = 60 * 2; // 2 min
|
|
@@ -360998,7 +361182,7 @@ function processHandler(processToHandle, ctl, onTimedOut) {
|
|
|
360998
361182
|
}
|
|
360999
361183
|
}
|
|
361000
361184
|
catch (error) {
|
|
361001
|
-
terraform_provisioner_src_logger.error(`FATAL: timeout signal ${signal} could not be delivered to the process: ${error}`);
|
|
361185
|
+
terraform_provisioner_src_logger/* default.error */.Z.error(`FATAL: timeout signal ${signal} could not be delivered to the process: ${error}`);
|
|
361002
361186
|
if (!callerNotified) {
|
|
361003
361187
|
ctl.processKilled(false);
|
|
361004
361188
|
callerNotified = true;
|
|
@@ -361010,15 +361194,15 @@ function processHandler(processToHandle, ctl, onTimedOut) {
|
|
|
361010
361194
|
onTimedOut();
|
|
361011
361195
|
timedOut = true;
|
|
361012
361196
|
// send sigInt
|
|
361013
|
-
terraform_provisioner_src_logger.error(`Terraform process has not exited after initial timeout of ${ctl.hardTimeout} seconds, sending SIGINT...`);
|
|
361197
|
+
terraform_provisioner_src_logger/* default.error */.Z.error(`Terraform process has not exited after initial timeout of ${ctl.hardTimeout} seconds, sending SIGINT...`);
|
|
361014
361198
|
safeKill('SIGINT');
|
|
361015
361199
|
// grace period
|
|
361016
361200
|
gracefulResetId = setTimeout(() => {
|
|
361017
|
-
terraform_provisioner_src_logger.error(`Terraform process has not exited after SIGINT grace period of ${GRACE_PERIOD} seconds (total elapsed ~${ctl.hardTimeout + GRACE_PERIOD} seconds), sending SIGTERM...`);
|
|
361201
|
+
terraform_provisioner_src_logger/* default.error */.Z.error(`Terraform process has not exited after SIGINT grace period of ${GRACE_PERIOD} seconds (total elapsed ~${ctl.hardTimeout + GRACE_PERIOD} seconds), sending SIGTERM...`);
|
|
361018
361202
|
safeKill('SIGTERM');
|
|
361019
361203
|
// hard reset period
|
|
361020
361204
|
hardResetId = setTimeout(() => {
|
|
361021
|
-
terraform_provisioner_src_logger.error(`Terraform process has not exited after SIGTERM hard reset period of ${HARD_RESET_PERIOD} seconds (total elapsed ~${ctl.hardTimeout + GRACE_PERIOD + HARD_RESET_PERIOD} seconds), sending SIGKILL...`);
|
|
361205
|
+
terraform_provisioner_src_logger/* default.error */.Z.error(`Terraform process has not exited after SIGTERM hard reset period of ${HARD_RESET_PERIOD} seconds (total elapsed ~${ctl.hardTimeout + GRACE_PERIOD + HARD_RESET_PERIOD} seconds), sending SIGKILL...`);
|
|
361022
361206
|
safeKill('SIGKILL');
|
|
361023
361207
|
setTimeout(() => {
|
|
361024
361208
|
// we send if the process was killed or not to the caller
|
|
@@ -361381,7 +361565,7 @@ async function initFromModule(path, source, secrets, stream, ctl) {
|
|
|
361381
361565
|
return tfExec(path, ['init', `-from-module=${source}`], secrets, [], stream, ctl);
|
|
361382
361566
|
}
|
|
361383
361567
|
async function plan(path, secrets, format, args = ['plan'], stream, ctl) {
|
|
361384
|
-
terraform_provisioner_src_logger.info(`Running terraform plan with ${format} in path ${path}`);
|
|
361568
|
+
terraform_provisioner_src_logger/* default.info */.Z.info(`Running terraform plan with ${format} in path ${path}`);
|
|
361385
361569
|
const plan = await tfExec(path, args.concat(format === 'json' ? ['-json'] : []), secrets, ['-input=false'], stream, ctl);
|
|
361386
361570
|
if (format === 'json') {
|
|
361387
361571
|
const tfPlan = planGet(plan);
|
|
@@ -361390,7 +361574,7 @@ async function plan(path, secrets, format, args = ['plan'], stream, ctl) {
|
|
|
361390
361574
|
return plan;
|
|
361391
361575
|
}
|
|
361392
361576
|
async function apply(path, secrets, stream, ctl) {
|
|
361393
|
-
terraform_provisioner_src_logger.debug(`Running terraform apply in path ${path}`);
|
|
361577
|
+
terraform_provisioner_src_logger/* default.debug */.Z.debug(`Running terraform apply in path ${path}`);
|
|
361394
361578
|
let lastError;
|
|
361395
361579
|
for (let attempt = 1; attempt <= MAX_APPLY_ATTEMPTS; attempt++) {
|
|
361396
361580
|
try {
|
|
@@ -361400,11 +361584,11 @@ async function apply(path, secrets, stream, ctl) {
|
|
|
361400
361584
|
lastError = error;
|
|
361401
361585
|
if (isGitHubInconsistentApplyError(lastError)) {
|
|
361402
361586
|
if (attempt < MAX_APPLY_ATTEMPTS) {
|
|
361403
|
-
terraform_provisioner_src_logger.warn(`Transient GitHub provider apply error detected (attempt ${attempt} of ${MAX_APPLY_ATTEMPTS}); retrying after ${TRANSIENT_APPLY_RETRY_DELAY_MS}ms: ${GITHUB_INCONSISTENT_APPLY_SIGNATURE.join(', ')}`);
|
|
361587
|
+
terraform_provisioner_src_logger/* default.warn */.Z.warn(`Transient GitHub provider apply error detected (attempt ${attempt} of ${MAX_APPLY_ATTEMPTS}); retrying after ${TRANSIENT_APPLY_RETRY_DELAY_MS}ms: ${GITHUB_INCONSISTENT_APPLY_SIGNATURE.join(', ')}`);
|
|
361404
361588
|
await catalog_common/* default.generic.sleep */.Z.generic.sleep(TRANSIENT_APPLY_RETRY_DELAY_MS);
|
|
361405
361589
|
continue;
|
|
361406
361590
|
}
|
|
361407
|
-
terraform_provisioner_src_logger.warn(`Transient GitHub provider apply error persisted after ${MAX_APPLY_ATTEMPTS} attempts; giving up.`);
|
|
361591
|
+
terraform_provisioner_src_logger/* default.warn */.Z.warn(`Transient GitHub provider apply error persisted after ${MAX_APPLY_ATTEMPTS} attempts; giving up.`);
|
|
361408
361592
|
}
|
|
361409
361593
|
throw lastError;
|
|
361410
361594
|
}
|
|
@@ -361412,15 +361596,15 @@ async function apply(path, secrets, stream, ctl) {
|
|
|
361412
361596
|
throw lastError;
|
|
361413
361597
|
}
|
|
361414
361598
|
async function customCommand(path, secrets, args, stream) {
|
|
361415
|
-
terraform_provisioner_src_logger.debug(`Running terraform customCommand in path ${path} ${args.join(',')}`);
|
|
361599
|
+
terraform_provisioner_src_logger/* default.debug */.Z.debug(`Running terraform customCommand in path ${path} ${args.join(',')}`);
|
|
361416
361600
|
return await tfExec(path, args, secrets, [], stream);
|
|
361417
361601
|
}
|
|
361418
361602
|
async function destroy(path, secrets, stream, ctl) {
|
|
361419
|
-
terraform_provisioner_src_logger.debug(`Running terraform destroy in path ${path}`);
|
|
361603
|
+
terraform_provisioner_src_logger/* default.debug */.Z.debug(`Running terraform destroy in path ${path}`);
|
|
361420
361604
|
return await tfExec(path, ['destroy', '-auto-approve', TOFU_LOCK_TIMEOUT], secrets, ['-input=false'], stream, ctl);
|
|
361421
361605
|
}
|
|
361422
361606
|
async function output(path, secrets) {
|
|
361423
|
-
terraform_provisioner_src_logger.debug(`Running terraform output in path ${path}`);
|
|
361607
|
+
terraform_provisioner_src_logger/* default.debug */.Z.debug(`Running terraform output in path ${path}`);
|
|
361424
361608
|
return await tfExec(path, ['output', '-json'], secrets, []);
|
|
361425
361609
|
}
|
|
361426
361610
|
async function tfExec(path, args, secrets, extraArgs = ['-input=false'], stream, ctl) {
|
|
@@ -361478,7 +361662,7 @@ async function tfExec(path, args, secrets, extraArgs = ['-input=false'], stream,
|
|
|
361478
361662
|
// this process has been killed/terminated
|
|
361479
361663
|
// by timeout (not in our control)
|
|
361480
361664
|
if (processTimeout) {
|
|
361481
|
-
terraform_provisioner_src_logger.error(`Terraform output ${path}: ${[output, outputErrors].join('')}`);
|
|
361665
|
+
terraform_provisioner_src_logger/* default.error */.Z.error(`Terraform output ${path}: ${[output, outputErrors].join('')}`);
|
|
361482
361666
|
ko(catalog_common/* default.generic.buildCommandExecutionError */.Z.generic.buildCommandExecutionError([output, outputErrors, '\n<PROCESS TIMEOUT>'].join(''), catalog_common/* default.generic.normalizeExitCode */.Z.generic.normalizeExitCode(code), args.concat(extraArgs), {
|
|
361483
361667
|
errorName: 'TerraformCommandError',
|
|
361484
361668
|
label: 'Terraform command',
|
|
@@ -361486,14 +361670,14 @@ async function tfExec(path, args, secrets, extraArgs = ['-input=false'], stream,
|
|
|
361486
361670
|
return;
|
|
361487
361671
|
}
|
|
361488
361672
|
if (code !== 0) {
|
|
361489
|
-
terraform_provisioner_src_logger.error(`Terraform output ${path}: ${[output, outputErrors].join('')}`);
|
|
361673
|
+
terraform_provisioner_src_logger/* default.error */.Z.error(`Terraform output ${path}: ${[output, outputErrors].join('')}`);
|
|
361490
361674
|
ko(catalog_common/* default.generic.buildCommandExecutionError */.Z.generic.buildCommandExecutionError([output, outputErrors].join(''), catalog_common/* default.generic.normalizeExitCode */.Z.generic.normalizeExitCode(code), args.concat(extraArgs), {
|
|
361491
361675
|
errorName: 'TerraformCommandError',
|
|
361492
361676
|
label: 'Terraform command',
|
|
361493
361677
|
}));
|
|
361494
361678
|
}
|
|
361495
361679
|
else {
|
|
361496
|
-
terraform_provisioner_src_logger.info(`Terraform output ${path}: ${output}`);
|
|
361680
|
+
terraform_provisioner_src_logger/* default.info */.Z.info(`Terraform output ${path}: ${output}`);
|
|
361497
361681
|
ok(output);
|
|
361498
361682
|
}
|
|
361499
361683
|
});
|
|
@@ -361631,6 +361815,62 @@ async function configGit() {
|
|
|
361631
361815
|
external_fs_.writeFileSync(gitconfigPath, `[url "https://firestartr:${ghToken}@github.com"]\ninsteadOf = https://github.com\n`);
|
|
361632
361816
|
}
|
|
361633
361817
|
|
|
361818
|
+
;// CONCATENATED MODULE: ../terraform_provisioner/src/writer_additional_files.ts
|
|
361819
|
+
|
|
361820
|
+
|
|
361821
|
+
|
|
361822
|
+
class WriterAdditionalFiles extends writer {
|
|
361823
|
+
constructor(files) {
|
|
361824
|
+
super();
|
|
361825
|
+
this.files = files;
|
|
361826
|
+
}
|
|
361827
|
+
// This writer complies with the abstract Writer class but does not render content in the traditional sense.
|
|
361828
|
+
async _render() {
|
|
361829
|
+
return '';
|
|
361830
|
+
}
|
|
361831
|
+
async writeToTerraformProject(projectPath) {
|
|
361832
|
+
for (const file of this.files) {
|
|
361833
|
+
try {
|
|
361834
|
+
const targetPath = external_path_.resolve(projectPath, file.path);
|
|
361835
|
+
const absProjectPath = external_path_.resolve(projectPath);
|
|
361836
|
+
if (!targetPath.startsWith(absProjectPath + external_path_.sep)) {
|
|
361837
|
+
throw new Error(`Path traversal detected: ${file.path}`);
|
|
361838
|
+
}
|
|
361839
|
+
await promises_.mkdir(external_path_.dirname(targetPath), { recursive: true });
|
|
361840
|
+
await promises_.writeFile(targetPath, Buffer.from(file.content, 'base64').toString('utf8'));
|
|
361841
|
+
}
|
|
361842
|
+
catch (err) {
|
|
361843
|
+
throw new Error(`Error writing additional file: ${file.path}: ${err}`);
|
|
361844
|
+
}
|
|
361845
|
+
}
|
|
361846
|
+
}
|
|
361847
|
+
}
|
|
361848
|
+
|
|
361849
|
+
;// CONCATENATED MODULE: ../terraform_provisioner/src/writer_imports.ts
|
|
361850
|
+
|
|
361851
|
+
class WriterImports extends writer {
|
|
361852
|
+
constructor(config) {
|
|
361853
|
+
super();
|
|
361854
|
+
this.config = config;
|
|
361855
|
+
}
|
|
361856
|
+
async _render() {
|
|
361857
|
+
let importBlocks = '';
|
|
361858
|
+
for (const importBlock of this.config.imports) {
|
|
361859
|
+
importBlocks += `
|
|
361860
|
+
|
|
361861
|
+
import {
|
|
361862
|
+
|
|
361863
|
+
to = ${importBlock.to}
|
|
361864
|
+
|
|
361865
|
+
id = "${importBlock.id}"
|
|
361866
|
+
}
|
|
361867
|
+
|
|
361868
|
+
`;
|
|
361869
|
+
}
|
|
361870
|
+
this.output = importBlocks;
|
|
361871
|
+
}
|
|
361872
|
+
}
|
|
361873
|
+
|
|
361634
361874
|
;// CONCATENATED MODULE: ../terraform_provisioner/src/writer_main_tf.ts
|
|
361635
361875
|
|
|
361636
361876
|
|
|
@@ -361653,6 +361893,31 @@ ${this.mainBlock}
|
|
|
361653
361893
|
}
|
|
361654
361894
|
}
|
|
361655
361895
|
|
|
361896
|
+
;// CONCATENATED MODULE: ../terraform_provisioner/src/writer_provider_tf_json.ts
|
|
361897
|
+
|
|
361898
|
+
|
|
361899
|
+
|
|
361900
|
+
class WriterProviderJson extends writer {
|
|
361901
|
+
constructor(mainBlock, providers, backend, tfStateKey) {
|
|
361902
|
+
super();
|
|
361903
|
+
this.mainBlock = mainBlock;
|
|
361904
|
+
this.providers = providers;
|
|
361905
|
+
this.backend = backend;
|
|
361906
|
+
this.tfStateKey = tfStateKey;
|
|
361907
|
+
}
|
|
361908
|
+
async _render() {
|
|
361909
|
+
this.output = await new WriterTerraform(this.providers, this.backend, this.tfStateKey, false).render('json');
|
|
361910
|
+
}
|
|
361911
|
+
writeToTerraformProject(mainTfPath) {
|
|
361912
|
+
if (this.output.trim() === '') {
|
|
361913
|
+
terraform_provisioner_src_logger/* default.info */.Z.info(`Skipping writing ${mainTfPath} as there is no provider to write.`);
|
|
361914
|
+
}
|
|
361915
|
+
else {
|
|
361916
|
+
super.writeToTerraformProject(mainTfPath);
|
|
361917
|
+
}
|
|
361918
|
+
}
|
|
361919
|
+
}
|
|
361920
|
+
|
|
361656
361921
|
;// CONCATENATED MODULE: ../terraform_provisioner/src/resolutor/resolver.ts
|
|
361657
361922
|
|
|
361658
361923
|
const REG_IS_CLAIM_SECRET_REF = new RegExp(/^secret-ref-\d+$/);
|
|
@@ -361712,7 +361977,7 @@ function getRefNameFromKey(key) {
|
|
|
361712
361977
|
function resolveClaimSecret(value, refs) {
|
|
361713
361978
|
if (typeof value === 'string' && REG_IS_CLAIM_SECRET_REF.test(value)) {
|
|
361714
361979
|
if (!Object.prototype.hasOwnProperty.call(refs, value)) {
|
|
361715
|
-
terraform_provisioner_src_logger.error(`SecretsClaim ref ${value} is not present on references`);
|
|
361980
|
+
terraform_provisioner_src_logger/* default.error */.Z.error(`SecretsClaim ref ${value} is not present on references`);
|
|
361716
361981
|
throw new Error(`SecretsClaim ref ${value} is not present on references`);
|
|
361717
361982
|
}
|
|
361718
361983
|
return refs[value];
|
|
@@ -361808,87 +362073,6 @@ function fCheckString(keys, refs) {
|
|
|
361808
362073
|
return true;
|
|
361809
362074
|
}
|
|
361810
362075
|
|
|
361811
|
-
;// CONCATENATED MODULE: ../terraform_provisioner/src/writer_provider_tf_json.ts
|
|
361812
|
-
|
|
361813
|
-
|
|
361814
|
-
|
|
361815
|
-
class WriterProviderJson extends writer {
|
|
361816
|
-
constructor(mainBlock, providers, backend, tfStateKey) {
|
|
361817
|
-
super();
|
|
361818
|
-
this.mainBlock = mainBlock;
|
|
361819
|
-
this.providers = providers;
|
|
361820
|
-
this.backend = backend;
|
|
361821
|
-
this.tfStateKey = tfStateKey;
|
|
361822
|
-
}
|
|
361823
|
-
async _render() {
|
|
361824
|
-
this.output = await new WriterTerraform(this.providers, this.backend, this.tfStateKey, false).render('json');
|
|
361825
|
-
}
|
|
361826
|
-
writeToTerraformProject(mainTfPath) {
|
|
361827
|
-
if (this.output.trim() === '') {
|
|
361828
|
-
terraform_provisioner_src_logger.info(`Skipping writing ${mainTfPath} as there is no provider to write.`);
|
|
361829
|
-
}
|
|
361830
|
-
else {
|
|
361831
|
-
super.writeToTerraformProject(mainTfPath);
|
|
361832
|
-
}
|
|
361833
|
-
}
|
|
361834
|
-
}
|
|
361835
|
-
|
|
361836
|
-
;// CONCATENATED MODULE: ../terraform_provisioner/src/writer_additional_files.ts
|
|
361837
|
-
|
|
361838
|
-
|
|
361839
|
-
|
|
361840
|
-
class WriterAdditionalFiles extends writer {
|
|
361841
|
-
constructor(files) {
|
|
361842
|
-
super();
|
|
361843
|
-
this.files = files;
|
|
361844
|
-
}
|
|
361845
|
-
// This writer complies with the abstract Writer class but does not render content in the traditional sense.
|
|
361846
|
-
async _render() {
|
|
361847
|
-
return '';
|
|
361848
|
-
}
|
|
361849
|
-
async writeToTerraformProject(projectPath) {
|
|
361850
|
-
for (const file of this.files) {
|
|
361851
|
-
try {
|
|
361852
|
-
const targetPath = external_path_.resolve(projectPath, file.path);
|
|
361853
|
-
const absProjectPath = external_path_.resolve(projectPath);
|
|
361854
|
-
if (!targetPath.startsWith(absProjectPath + external_path_.sep)) {
|
|
361855
|
-
throw new Error(`Path traversal detected: ${file.path}`);
|
|
361856
|
-
}
|
|
361857
|
-
await promises_.mkdir(external_path_.dirname(targetPath), { recursive: true });
|
|
361858
|
-
await promises_.writeFile(targetPath, Buffer.from(file.content, 'base64').toString('utf8'));
|
|
361859
|
-
}
|
|
361860
|
-
catch (err) {
|
|
361861
|
-
throw new Error(`Error writing additional file: ${file.path}: ${err}`);
|
|
361862
|
-
}
|
|
361863
|
-
}
|
|
361864
|
-
}
|
|
361865
|
-
}
|
|
361866
|
-
|
|
361867
|
-
;// CONCATENATED MODULE: ../terraform_provisioner/src/writer_imports.ts
|
|
361868
|
-
|
|
361869
|
-
class WriterImports extends writer {
|
|
361870
|
-
constructor(config) {
|
|
361871
|
-
super();
|
|
361872
|
-
this.config = config;
|
|
361873
|
-
}
|
|
361874
|
-
async _render() {
|
|
361875
|
-
let importBlocks = '';
|
|
361876
|
-
for (const importBlock of this.config.imports) {
|
|
361877
|
-
importBlocks += `
|
|
361878
|
-
|
|
361879
|
-
import {
|
|
361880
|
-
|
|
361881
|
-
to = ${importBlock.to}
|
|
361882
|
-
|
|
361883
|
-
id = "${importBlock.id}"
|
|
361884
|
-
}
|
|
361885
|
-
|
|
361886
|
-
`;
|
|
361887
|
-
}
|
|
361888
|
-
this.output = importBlocks;
|
|
361889
|
-
}
|
|
361890
|
-
}
|
|
361891
|
-
|
|
361892
362076
|
// EXTERNAL MODULE: external "stream"
|
|
361893
362077
|
var external_stream_ = __nccwpck_require__(12781);
|
|
361894
362078
|
;// CONCATENATED MODULE: ../terraform_provisioner/src/project_tf.ts
|
|
@@ -361909,10 +362093,14 @@ class project_tf_TFProjectManager {
|
|
|
361909
362093
|
? external_path_.resolve(this.projectPath)
|
|
361910
362094
|
: '';
|
|
361911
362095
|
// Remove the entire workspace directory
|
|
362096
|
+
// Never delete debug workspaces. Support both gh-debug (existing) and
|
|
362097
|
+
// the new tf-debug workspace prefix.
|
|
361912
362098
|
if (resolvedProjectPath &&
|
|
361913
|
-
resolvedProjectPath.startsWith('/tmp/gh-debug/')
|
|
362099
|
+
(resolvedProjectPath.startsWith('/tmp/gh-debug/') ||
|
|
362100
|
+
resolvedProjectPath.startsWith('/tmp/tf-debug/') ||
|
|
362101
|
+
process.env.FIRESTARTR_DEBUG === 'true')) {
|
|
361914
362102
|
// Never delete debug workspaces, per spec.
|
|
361915
|
-
terraform_provisioner_src_logger.info(`[terraform-provisioner]: SKIP teardown for debug workspace at ${this.projectPath}`);
|
|
362103
|
+
terraform_provisioner_src_logger/* default.info */.Z.info(`[terraform-provisioner]: SKIP teardown for debug workspace at ${this.projectPath}`);
|
|
361916
362104
|
return;
|
|
361917
362105
|
}
|
|
361918
362106
|
if (resolvedProjectPath &&
|
|
@@ -361923,7 +362111,7 @@ class project_tf_TFProjectManager {
|
|
|
361923
362111
|
recursive: true,
|
|
361924
362112
|
force: true,
|
|
361925
362113
|
});
|
|
361926
|
-
terraform_provisioner_src_logger.info(`[terraform-provisioner]: Workspace at ${resolvedProjectPath} torn up successfully`);
|
|
362114
|
+
terraform_provisioner_src_logger/* default.info */.Z.info(`[terraform-provisioner]: Workspace at ${resolvedProjectPath} torn up successfully`);
|
|
361927
362115
|
}
|
|
361928
362116
|
catch (e) {
|
|
361929
362117
|
throw new Error(`[terraform-provisioner]: Failed to tear up local project at ${this.projectPath}: ${e}`);
|
|
@@ -361939,7 +362127,81 @@ class project_tf_TFProjectManager {
|
|
|
361939
362127
|
this.onImport = false;
|
|
361940
362128
|
this.onImport = !!ctx.importMode;
|
|
361941
362129
|
this.ctx = ctx;
|
|
361942
|
-
|
|
362130
|
+
// Normalize incoming debug project paths so the provisioner tolerates both
|
|
362131
|
+
// old (suffixed) and new (stripped) naming. If ctx.projectPath points to a
|
|
362132
|
+
// /tmp/tf-debug path, strip a trailing UUID-like suffix from the final
|
|
362133
|
+
// segment so reuse checks look at the deterministic folder.
|
|
362134
|
+
const incomingPath = ctx.projectPath;
|
|
362135
|
+
if (typeof incomingPath === 'string' &&
|
|
362136
|
+
incomingPath.startsWith('/tmp/tf-debug/')) {
|
|
362137
|
+
const dir = external_path_.dirname(incomingPath);
|
|
362138
|
+
const name = external_path_.basename(incomingPath);
|
|
362139
|
+
// If the incoming debug folder includes a tfStateKey suffix, preserve
|
|
362140
|
+
// it when normalizing. We expect the operator to set projectPath to
|
|
362141
|
+
// `/tmp/tf-debug/<kind>-<baseName>-<tfStateKey>` when tfStateKey is
|
|
362142
|
+
// available. Strip only a trailing UUID-like suffix if present.
|
|
362143
|
+
const baseName = name.replace(/-[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/, '');
|
|
362144
|
+
const normalized = external_path_.join(dir, baseName);
|
|
362145
|
+
// If the deterministic folder exists, use it. If not, but there is an
|
|
362146
|
+
// existing legacy suffixed folder, fall back to that so we remain
|
|
362147
|
+
// tolerant of older operators that still write suffixed debug folders.
|
|
362148
|
+
if (external_fs_.existsSync(normalized)) {
|
|
362149
|
+
this.projectPath = normalized;
|
|
362150
|
+
}
|
|
362151
|
+
else {
|
|
362152
|
+
try {
|
|
362153
|
+
const entries = external_fs_.readdirSync(dir, { withFileTypes: true });
|
|
362154
|
+
const escapedBaseName = baseName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
362155
|
+
const legacyDirRegex = new RegExp(`^${escapedBaseName}-[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$`);
|
|
362156
|
+
const candidate = entries
|
|
362157
|
+
.filter((e) => e.isDirectory())
|
|
362158
|
+
.map((e) => e.name)
|
|
362159
|
+
.find((n) => legacyDirRegex.test(n));
|
|
362160
|
+
if (candidate) {
|
|
362161
|
+
// Prefer using the deterministic normalized path even if a
|
|
362162
|
+
// legacy suffixed candidate exists. Try to atomically rename the
|
|
362163
|
+
// legacy folder to the normalized name so subsequent runs use
|
|
362164
|
+
// a single, stable location. If rename fails, fall back to the
|
|
362165
|
+
// legacy candidate to avoid breaking execution.
|
|
362166
|
+
const candidatePath = external_path_.join(dir, candidate);
|
|
362167
|
+
try {
|
|
362168
|
+
external_fs_.renameSync(candidatePath, normalized);
|
|
362169
|
+
this.projectPath = normalized;
|
|
362170
|
+
}
|
|
362171
|
+
catch (renameErr) {
|
|
362172
|
+
// Renaming may fail (permissions, cross-fs). Fall back to
|
|
362173
|
+
// legacy candidate to preserve behavior.
|
|
362174
|
+
terraform_provisioner_src_logger/* default.warn */.Z.warn(`[terraform-provisioner]: failed to rename legacy debug folder ${candidatePath} -> ${normalized}: ${renameErr}`);
|
|
362175
|
+
this.projectPath = candidatePath;
|
|
362176
|
+
}
|
|
362177
|
+
}
|
|
362178
|
+
else {
|
|
362179
|
+
this.projectPath = normalized;
|
|
362180
|
+
}
|
|
362181
|
+
}
|
|
362182
|
+
catch (e) {
|
|
362183
|
+
// If reading the directory fails for any reason, fall back to the
|
|
362184
|
+
// normalized path — this keeps behavior deterministic and avoids
|
|
362185
|
+
// throwing from the constructor.
|
|
362186
|
+
this.projectPath = normalized;
|
|
362187
|
+
}
|
|
362188
|
+
}
|
|
362189
|
+
}
|
|
362190
|
+
else {
|
|
362191
|
+
this.projectPath = ctx.projectPath;
|
|
362192
|
+
}
|
|
362193
|
+
// Ensure ctx.projectPath matches the resolved projectPath so subsequent
|
|
362194
|
+
// debug initialization (which reads ctx.projectPath) operates on the
|
|
362195
|
+
// same directory the project managers will write to. This prevents a
|
|
362196
|
+
// timing mismatch where debug.init creates the deterministic folder but
|
|
362197
|
+
// the project manager writes into a different (suffixed) folder.
|
|
362198
|
+
try {
|
|
362199
|
+
if (this.ctx && typeof this.ctx === 'object')
|
|
362200
|
+
this.ctx.projectPath = this.projectPath;
|
|
362201
|
+
}
|
|
362202
|
+
catch (e) {
|
|
362203
|
+
// Non-fatal: keep behavior deterministic even if we cannot mutate ctx
|
|
362204
|
+
}
|
|
361943
362205
|
this.mainTfWriter = new WriterMainTf(ctx.inline, ctx.requiredProviders, ctx.backend, ctx.tfStateKey);
|
|
361944
362206
|
this.providerJsonWriter = new WriterProviderJson(ctx.inline, ctx.requiredProviders, ctx.backend, ctx.tfStateKey);
|
|
361945
362207
|
this.tfVarsJsonWriter = new WriterTfVarsJson(ctx.values, ctx.references);
|
|
@@ -361967,14 +362229,41 @@ class project_tf_TFProjectManager {
|
|
|
361967
362229
|
this.stream.on('end', fnEnd);
|
|
361968
362230
|
}
|
|
361969
362231
|
async build() {
|
|
362232
|
+
// If this context indicates a debug workspace, initialize debug artifacts
|
|
362233
|
+
// early so files like cr.yaml/deps.yaml are present before build steps.
|
|
362234
|
+
try {
|
|
362235
|
+
terraform_provisioner_src_logger/* default.debug */.Z.debug(`[terraform-provisioner]: build() start - ctx.projectPath=${this.ctx?.projectPath} projectPath=${this.projectPath}`);
|
|
362236
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
362237
|
+
const debug = __nccwpck_require__(16907);
|
|
362238
|
+
await debug.initTfDebug(this.ctx);
|
|
362239
|
+
terraform_provisioner_src_logger/* default.debug */.Z.debug(`[terraform-provisioner]: build() after initTfDebug - ctx.projectPath=${this.ctx?.projectPath} projectPath=${this.projectPath}`);
|
|
362240
|
+
}
|
|
362241
|
+
catch (e) {
|
|
362242
|
+
// Best-effort; failures here should not block normal execution but
|
|
362243
|
+
// emit a warning so operators know why debug artifacts may be absent.
|
|
362244
|
+
terraform_provisioner_src_logger/* default.warn */.Z.warn(`[terraform-provisioner]: failed to init tf debug artifacts: ${e?.message ?? e}`);
|
|
362245
|
+
}
|
|
361970
362246
|
if (this.ctx?.reuseExistingProject) {
|
|
361971
362247
|
if (!external_fs_.existsSync(this.projectPath)) {
|
|
361972
362248
|
throw new Error(`[terraform-provisioner]: Workspace reuse requested but projectPath does not exist: ${this.projectPath}. Cannot continue.`);
|
|
361973
362249
|
}
|
|
362250
|
+
try {
|
|
362251
|
+
const entries = external_fs_.readdirSync(this.projectPath);
|
|
362252
|
+
// Directory listing may contain user-supplied filenames; keep at debug level
|
|
362253
|
+
// to avoid leaking sensitive names in normal info logs.
|
|
362254
|
+
terraform_provisioner_src_logger/* default.debug */.Z.debug(`[terraform-provisioner]: reuse check - projectPath contents: ${JSON.stringify(entries)}`);
|
|
362255
|
+
}
|
|
362256
|
+
catch (e) {
|
|
362257
|
+
terraform_provisioner_src_logger/* default.warn */.Z.warn(`[terraform-provisioner]: failed to read projectPath ${this.projectPath}: ${e}`);
|
|
362258
|
+
}
|
|
361974
362259
|
const expectedFiles = await computeInlineWorkspaceFiles(this.ctx);
|
|
362260
|
+
// expectedFiles may include user-supplied paths; log at debug level only.
|
|
362261
|
+
terraform_provisioner_src_logger/* default.debug */.Z.debug(`[terraform-provisioner]: reuse check - expected files: ${JSON.stringify(expectedFiles)}`);
|
|
361975
362262
|
const missing = validateWorkspaceStructure(this.projectPath, expectedFiles);
|
|
362263
|
+
// Missing files may reveal internal filenames; keep at debug level.
|
|
362264
|
+
terraform_provisioner_src_logger/* default.debug */.Z.debug(`[terraform-provisioner]: reuse check - missing files: ${JSON.stringify(missing)}`);
|
|
361976
362265
|
if (missing.length === 0) {
|
|
361977
|
-
terraform_provisioner_src_logger.info(`[terraform-provisioner]: Reusing existing Inline workspace at ${this.projectPath}`);
|
|
362266
|
+
terraform_provisioner_src_logger/* default.info */.Z.info(`[terraform-provisioner]: Reusing existing Inline workspace at ${this.projectPath}`);
|
|
361978
362267
|
// imports.tf is command-scoped: always (re)generate it for import commands after reuse validation.
|
|
361979
362268
|
if (this.onImport) {
|
|
361980
362269
|
const writerImports = new WriterImports(this.customArgs);
|
|
@@ -361987,7 +362276,7 @@ class project_tf_TFProjectManager {
|
|
|
361987
362276
|
}
|
|
361988
362277
|
throw new Error(`[terraform-provisioner]: Workspace reuse requested but missing required files: ${missing.join(', ')}. Cannot continue.`);
|
|
361989
362278
|
}
|
|
361990
|
-
terraform_provisioner_src_logger.info(`[terraform-provisioner]: Creating new Inline workspace at ${this.projectPath}`);
|
|
362279
|
+
terraform_provisioner_src_logger/* default.info */.Z.info(`[terraform-provisioner]: Creating new Inline workspace at ${this.projectPath}`);
|
|
361991
362280
|
await this.mainTfWriter.render();
|
|
361992
362281
|
this.mainTfWriter.writeToTerraformProject(external_path_.join(this.projectPath, 'firestartr-main.tf'));
|
|
361993
362282
|
await this.providerJsonWriter.render();
|
|
@@ -362058,13 +362347,13 @@ class project_tf_TFProjectManager {
|
|
|
362058
362347
|
const addressesList = (await customCommand(this.projectPath, this.secrets, ['state', 'list'], this.stream))
|
|
362059
362348
|
.split(/\n/)
|
|
362060
362349
|
.filter((line) => line.replace(/\n|\s/g, ''));
|
|
362061
|
-
terraform_provisioner_src_logger.info(`[terraform-provisioner]: destroyStateOnly: Obtained the addresses of the resources ${addressesList.join(',')}`);
|
|
362350
|
+
terraform_provisioner_src_logger/* default.info */.Z.info(`[terraform-provisioner]: destroyStateOnly: Obtained the addresses of the resources ${addressesList.join(',')}`);
|
|
362062
362351
|
if (addressesList.length > 0) {
|
|
362063
362352
|
await customCommand(this.projectPath, this.secrets, ['state', 'rm'].concat(addressesList), this.stream);
|
|
362064
|
-
terraform_provisioner_src_logger.info(`[terraform-provisioner]: destroyStateOnly: deleted from the state the following addresses ${addressesList.join(',')}`);
|
|
362353
|
+
terraform_provisioner_src_logger/* default.info */.Z.info(`[terraform-provisioner]: destroyStateOnly: deleted from the state the following addresses ${addressesList.join(',')}`);
|
|
362065
362354
|
}
|
|
362066
362355
|
else {
|
|
362067
|
-
terraform_provisioner_src_logger.info('[terraform-provisioner]: destroyStateOnly: warning the state is already empty, no destroy has taken place');
|
|
362356
|
+
terraform_provisioner_src_logger/* default.info */.Z.info('[terraform-provisioner]: destroyStateOnly: warning the state is already empty, no destroy has taken place');
|
|
362068
362357
|
}
|
|
362069
362358
|
if (this.stream)
|
|
362070
362359
|
this.stream.end();
|
|
@@ -362114,7 +362403,7 @@ async function initializeMirrors(repos = [...DEFAULT_MIRROR_WARMUP_LIST]) {
|
|
|
362114
362403
|
await onError(err);
|
|
362115
362404
|
}
|
|
362116
362405
|
else {
|
|
362117
|
-
terraform_provisioner_src_logger.error('[mirror] Refresher beforeRefresh error:', err);
|
|
362406
|
+
terraform_provisioner_src_logger/* default.error */.Z.error('[mirror] Refresher beforeRefresh error:', err);
|
|
362118
362407
|
}
|
|
362119
362408
|
return; // skip this tick if beforeRefresh fails
|
|
362120
362409
|
}
|
|
@@ -362133,7 +362422,7 @@ async function initializeMirrors(repos = [...DEFAULT_MIRROR_WARMUP_LIST]) {
|
|
|
362133
362422
|
await onError(err);
|
|
362134
362423
|
}
|
|
362135
362424
|
else {
|
|
362136
|
-
terraform_provisioner_src_logger.error('[mirror] Refresher error:', err);
|
|
362425
|
+
terraform_provisioner_src_logger/* default.error */.Z.error('[mirror] Refresher error:', err);
|
|
362137
362426
|
}
|
|
362138
362427
|
}
|
|
362139
362428
|
}
|
|
@@ -362337,7 +362626,7 @@ async function installMirrorForRepo(remoteUrl) {
|
|
|
362337
362626
|
const headPath = external_path_default().join(mirrorPath, 'HEAD');
|
|
362338
362627
|
await external_fs_promises_default().access(configPath);
|
|
362339
362628
|
await external_fs_promises_default().access(headPath);
|
|
362340
|
-
terraform_provisioner_src_logger.info(`[mirror] Mirror exists at ${mirrorPath}, refreshing...`);
|
|
362629
|
+
terraform_provisioner_src_logger/* default.info */.Z.info(`[mirror] Mirror exists at ${mirrorPath}, refreshing...`);
|
|
362341
362630
|
await refreshMirror(mirrorPath);
|
|
362342
362631
|
}
|
|
362343
362632
|
catch (e) {
|
|
@@ -362347,7 +362636,7 @@ async function installMirrorForRepo(remoteUrl) {
|
|
|
362347
362636
|
else if (stat === null) {
|
|
362348
362637
|
try {
|
|
362349
362638
|
await external_fs_promises_default().mkdir(external_path_default().posix.dirname(mirrorPath), { recursive: true });
|
|
362350
|
-
terraform_provisioner_src_logger.info(`[mirror] Cloning bare mirror from ${repoUrl} to ${mirrorPath}`);
|
|
362639
|
+
terraform_provisioner_src_logger/* default.info */.Z.info(`[mirror] Cloning bare mirror from ${repoUrl} to ${mirrorPath}`);
|
|
362351
362640
|
await gitCloneMirror(repoUrl, mirrorPath);
|
|
362352
362641
|
}
|
|
362353
362642
|
catch (e) {
|
|
@@ -362433,7 +362722,7 @@ async function refreshMirror(mirrorPath) {
|
|
|
362433
362722
|
}
|
|
362434
362723
|
// Run the actual refresher, which throws on failure
|
|
362435
362724
|
await gitFetchPrune(mirrorPath);
|
|
362436
|
-
terraform_provisioner_src_logger.debug(`[mirror] Mirror at ${mirrorPath} was successfully refreshed`);
|
|
362725
|
+
terraform_provisioner_src_logger/* default.debug */.Z.debug(`[mirror] Mirror at ${mirrorPath} was successfully refreshed`);
|
|
362437
362726
|
}
|
|
362438
362727
|
// --- Spec 002-mirror-tfm-usage: Warmup support ---
|
|
362439
362728
|
|
|
@@ -362488,7 +362777,7 @@ async function resolveMirroredModuleSource(source) {
|
|
|
362488
362777
|
return translateModuleSource(source);
|
|
362489
362778
|
}
|
|
362490
362779
|
catch (e) {
|
|
362491
|
-
terraform_provisioner_src_logger.warn(`[mirror] Could not mirror ${repoUrl}; failing provisioning. Reason: ${e.message}`);
|
|
362780
|
+
terraform_provisioner_src_logger/* default.warn */.Z.warn(`[mirror] Could not mirror ${repoUrl}; failing provisioning. Reason: ${e.message}`);
|
|
362492
362781
|
throw e;
|
|
362493
362782
|
}
|
|
362494
362783
|
}
|
|
@@ -362604,10 +362893,14 @@ class TFProjectManagerRemote {
|
|
|
362604
362893
|
? external_path_.resolve(this.projectPath)
|
|
362605
362894
|
: '';
|
|
362606
362895
|
// Remove the entire workspace directory
|
|
362896
|
+
// Never delete debug workspaces. Support both gh-debug (existing) and
|
|
362897
|
+
// the new tf-debug workspace prefix.
|
|
362607
362898
|
if (resolvedProjectPath &&
|
|
362608
|
-
resolvedProjectPath.startsWith('/tmp/gh-debug/')
|
|
362899
|
+
(resolvedProjectPath.startsWith('/tmp/gh-debug/') ||
|
|
362900
|
+
resolvedProjectPath.startsWith('/tmp/tf-debug/') ||
|
|
362901
|
+
process.env.FIRESTARTR_DEBUG === 'true')) {
|
|
362609
362902
|
// Never delete debug workspaces, per spec.
|
|
362610
|
-
terraform_provisioner_src_logger.info(`[terraform-provisioner]: SKIP teardown for debug workspace at ${this.projectPath}`);
|
|
362903
|
+
terraform_provisioner_src_logger/* default.info */.Z.info(`[terraform-provisioner]: SKIP teardown for debug workspace at ${this.projectPath}`);
|
|
362611
362904
|
return;
|
|
362612
362905
|
}
|
|
362613
362906
|
if (resolvedProjectPath &&
|
|
@@ -362618,7 +362911,7 @@ class TFProjectManagerRemote {
|
|
|
362618
362911
|
recursive: true,
|
|
362619
362912
|
force: true,
|
|
362620
362913
|
});
|
|
362621
|
-
terraform_provisioner_src_logger.info(`[terraform-provisioner]: Workspace at ${resolvedProjectPath} torn up successfully`);
|
|
362914
|
+
terraform_provisioner_src_logger/* default.info */.Z.info(`[terraform-provisioner]: Workspace at ${resolvedProjectPath} torn up successfully`);
|
|
362622
362915
|
}
|
|
362623
362916
|
catch (e) {
|
|
362624
362917
|
throw new Error(`[terraform-provisioner]: Failed to tear up local project at ${this.projectPath}: ${e}`);
|
|
@@ -362665,6 +362958,18 @@ class TFProjectManagerRemote {
|
|
|
362665
362958
|
this.stream.on('end', fnEnd);
|
|
362666
362959
|
}
|
|
362667
362960
|
async build() {
|
|
362961
|
+
// If this context indicates a debug workspace, initialize debug artifacts
|
|
362962
|
+
// early so files like cr.yaml/deps.yaml are present before build steps.
|
|
362963
|
+
try {
|
|
362964
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
362965
|
+
const debug = __nccwpck_require__(16907);
|
|
362966
|
+
await debug.initTfDebug(this.ctx);
|
|
362967
|
+
}
|
|
362968
|
+
catch (e) {
|
|
362969
|
+
// Best-effort; failures here should not block normal execution but
|
|
362970
|
+
// emit a warning so operators know why debug artifacts may be absent.
|
|
362971
|
+
terraform_provisioner_src_logger/* default.warn */.Z.warn(`[terraform-provisioner]: failed to init tf debug artifacts: ${e?.message ?? e}`);
|
|
362972
|
+
}
|
|
362668
362973
|
// Workspace reuse block for remote
|
|
362669
362974
|
if (this.ctx?.reuseExistingProject) {
|
|
362670
362975
|
if (!external_fs_.existsSync(this.projectPath)) {
|
|
@@ -362673,7 +362978,7 @@ class TFProjectManagerRemote {
|
|
|
362673
362978
|
const expectedFiles = await computeRemoteWorkspaceFiles(this.ctx);
|
|
362674
362979
|
const missing = validateWorkspaceStructure(this.projectPath, expectedFiles);
|
|
362675
362980
|
if (missing.length === 0) {
|
|
362676
|
-
terraform_provisioner_src_logger.info(`[terraform-provisioner]: Reusing existing Remote workspace at ${this.projectPath}`);
|
|
362981
|
+
terraform_provisioner_src_logger/* default.info */.Z.info(`[terraform-provisioner]: Reusing existing Remote workspace at ${this.projectPath}`);
|
|
362677
362982
|
// imports.tf is command-scoped: always (re)generate it for import commands after reuse validation.
|
|
362678
362983
|
if (this.onImport) {
|
|
362679
362984
|
const writerImports = new WriterImports(this.customArgs);
|
|
@@ -362686,7 +362991,7 @@ class TFProjectManagerRemote {
|
|
|
362686
362991
|
}
|
|
362687
362992
|
throw new Error(`[terraform-provisioner]: Workspace reuse requested but missing required files: ${missing.join(', ')}. Cannot continue.`);
|
|
362688
362993
|
}
|
|
362689
|
-
terraform_provisioner_src_logger.info(`[terraform-provisioner]: Creating new Remote workspace at ${this.projectPath}`);
|
|
362994
|
+
terraform_provisioner_src_logger/* default.info */.Z.info(`[terraform-provisioner]: Creating new Remote workspace at ${this.projectPath}`);
|
|
362690
362995
|
external_fs_.rmSync(this.projectPath, { recursive: true, force: true });
|
|
362691
362996
|
await configGit();
|
|
362692
362997
|
await this.__initFromModule();
|
|
@@ -362763,13 +363068,13 @@ class TFProjectManagerRemote {
|
|
|
362763
363068
|
const addressesList = (await customCommand(this.projectPath, this.secrets, ['state', 'list'], this.stream))
|
|
362764
363069
|
.split(/\n/)
|
|
362765
363070
|
.filter((line) => line.replace(/\n|\s/g, ''));
|
|
362766
|
-
terraform_provisioner_src_logger.info(`[terraform-provisioner]: destroyStateOnly: Obtained the addresses of the resources ${addressesList.join(',')}`);
|
|
363071
|
+
terraform_provisioner_src_logger/* default.info */.Z.info(`[terraform-provisioner]: destroyStateOnly: Obtained the addresses of the resources ${addressesList.join(',')}`);
|
|
362767
363072
|
if (addressesList.length > 0) {
|
|
362768
363073
|
await customCommand(this.projectPath, this.secrets, ['state', 'rm'].concat(addressesList), this.stream);
|
|
362769
|
-
terraform_provisioner_src_logger.info(`[terraform-provisioner]: destroyStateOnly: deleted from the state the following addresses ${addressesList.join(',')}`);
|
|
363074
|
+
terraform_provisioner_src_logger/* default.info */.Z.info(`[terraform-provisioner]: destroyStateOnly: deleted from the state the following addresses ${addressesList.join(',')}`);
|
|
362770
363075
|
}
|
|
362771
363076
|
else {
|
|
362772
|
-
terraform_provisioner_src_logger.info('[terraform-provisioner]: destroyStateOnly: warning the state is already empty, no destroy has taken place');
|
|
363077
|
+
terraform_provisioner_src_logger/* default.info */.Z.info('[terraform-provisioner]: destroyStateOnly: warning the state is already empty, no destroy has taken place');
|
|
362773
363078
|
}
|
|
362774
363079
|
if (this.stream)
|
|
362775
363080
|
this.stream.end();
|
|
@@ -362842,7 +363147,7 @@ async function run() {
|
|
|
362842
363147
|
}
|
|
362843
363148
|
// Programatic API
|
|
362844
363149
|
async function runTerraformProvisioner(context, command = 'init', streaming, customArgs, ctl) {
|
|
362845
|
-
terraform_provisioner_src_logger.info(`Running command ${command} on a ${context.type} project`);
|
|
363150
|
+
terraform_provisioner_src_logger/* default.info */.Z.info(`Running command ${command} on a ${context.type} project`);
|
|
362846
363151
|
validateContext(context);
|
|
362847
363152
|
let tfProject = {};
|
|
362848
363153
|
if (context.type === 'Inline') {
|
|
@@ -362868,7 +363173,7 @@ async function runTerraformProvisioner(context, command = 'init', streaming, cus
|
|
|
362868
363173
|
tfProject.context.importMode = true;
|
|
362869
363174
|
}
|
|
362870
363175
|
if (command === 'destroy-state-only') {
|
|
362871
|
-
terraform_provisioner_src_logger.info('[gh-provisioner] WARNING! is a destroy-state-only');
|
|
363176
|
+
terraform_provisioner_src_logger/* default.info */.Z.info('[gh-provisioner] WARNING! is a destroy-state-only');
|
|
362872
363177
|
}
|
|
362873
363178
|
if (ctl) {
|
|
362874
363179
|
tfProject.ctl = ctl;
|
|
@@ -362877,7 +363182,7 @@ async function runTerraformProvisioner(context, command = 'init', streaming, cus
|
|
|
362877
363182
|
return output;
|
|
362878
363183
|
}
|
|
362879
363184
|
async function execCommand(command, tfProject) {
|
|
362880
|
-
terraform_provisioner_src_logger.info(`Executing command ${command} on ${tfProject.projectPath}`);
|
|
363185
|
+
terraform_provisioner_src_logger/* default.info */.Z.info(`Executing command ${command} on ${tfProject.projectPath}`);
|
|
362881
363186
|
// Handle no-build commands FIRST
|
|
362882
363187
|
if (command === 'tear-up-project') {
|
|
362883
363188
|
if (tfProject.tearUpProject) {
|
|
@@ -362939,6 +363244,28 @@ function operatorProfile() {
|
|
|
362939
363244
|
return github["default"].withProfile('operator');
|
|
362940
363245
|
}
|
|
362941
363246
|
|
|
363247
|
+
function resolveProgressCommentResource(item) {
|
|
363248
|
+
return { kind: item.kind, name: item.metadata?.name ?? 'unknown' };
|
|
363249
|
+
}
|
|
363250
|
+
/**
|
|
363251
|
+
* Single builder of the sticky base kind shared by the apply progress
|
|
363252
|
+
* comment (upserted by the check run while the operation runs) and the
|
|
363253
|
+
* final result publisher (which updates that same comment in place).
|
|
363254
|
+
* Keyed per resource so claims of the same kind never overwrite each
|
|
363255
|
+
* other's feedback.
|
|
363256
|
+
*/
|
|
363257
|
+
function progressCommentBaseKind(cmd, item) {
|
|
363258
|
+
const { kind, name } = resolveProgressCommentResource(item);
|
|
363259
|
+
return `${cmd}:${kind}:${name}`;
|
|
363260
|
+
}
|
|
363261
|
+
/**
|
|
363262
|
+
* Body of the apply progress comment. The check-run module appends the
|
|
363263
|
+
* `[here](<check-run-url>)` link to it.
|
|
363264
|
+
*/
|
|
363265
|
+
function progressCommentText(cmd, item) {
|
|
363266
|
+
const { kind, name } = resolveProgressCommentResource(item);
|
|
363267
|
+
return `The ${kind} '${name}' is being processed (cmd=${cmd}). Details: `;
|
|
363268
|
+
}
|
|
362942
363269
|
async function tryPublishApply(item, planOutput, isSuccess = true, exitCode) {
|
|
362943
363270
|
const kind = item.kind;
|
|
362944
363271
|
const metadataName = item.metadata?.name ?? 'unknown';
|
|
@@ -362992,7 +363319,7 @@ ${commentContent}
|
|
|
362992
363319
|
owner: org,
|
|
362993
363320
|
repo,
|
|
362994
363321
|
pullNumber: prNumber,
|
|
362995
|
-
baseKind:
|
|
363322
|
+
baseKind: progressCommentBaseKind('destroy', item),
|
|
362996
363323
|
bodies: commentBodies,
|
|
362997
363324
|
});
|
|
362998
363325
|
operator_src_logger.debug(`The user feedback for the '${item.kind}/${item.metadata.name}' destroy operation has been published as a comment on pull request '${prNumber}'.`);
|
|
@@ -363029,7 +363356,7 @@ ${commentContent}
|
|
|
363029
363356
|
owner: org,
|
|
363030
363357
|
repo,
|
|
363031
363358
|
pullNumber: prNumber,
|
|
363032
|
-
baseKind:
|
|
363359
|
+
baseKind: progressCommentBaseKind('apply', item),
|
|
363033
363360
|
bodies: commentBodies,
|
|
363034
363361
|
});
|
|
363035
363362
|
}
|
|
@@ -363130,93 +363457,6 @@ ${commentContent}
|
|
|
363130
363457
|
}
|
|
363131
363458
|
}
|
|
363132
363459
|
|
|
363133
|
-
;// CONCATENATED MODULE: ../operator/src/tfworkspaces/policies.ts
|
|
363134
|
-
|
|
363135
|
-
|
|
363136
|
-
|
|
363137
|
-
function policyAllowsOp(policy, op, item) {
|
|
363138
|
-
let msg = '';
|
|
363139
|
-
const foundPolicy = catalog_common/* default.policies.getPolicyByName */.Z.policies.getPolicyByName(policy);
|
|
363140
|
-
if (op === OperationType.RETRY.toString() &&
|
|
363141
|
-
foundPolicy?.allowedOps.includes(op)) {
|
|
363142
|
-
if ('deletionTimestamp' in item.metadata && 'full-control' !== policy) {
|
|
363143
|
-
msg = `A RETRY operation is not allowed on a resource with a deletionTimestamp. It means
|
|
363144
|
-
that the resource is being deleted and it is not possible to retry the operation with policy: ${policy}.
|
|
363145
|
-
|
|
363146
|
-
To fix this issue, you must first delete the "firestartr.dev/finalizer" from finalizers array in the resource manifest,
|
|
363147
|
-
it will be automatically deleted by Kubernetes. Terraform will not execute any operation on the resource.
|
|
363148
|
-
`;
|
|
363149
|
-
return { allowed: false, msg };
|
|
363150
|
-
}
|
|
363151
|
-
else {
|
|
363152
|
-
return { allowed: true, msg };
|
|
363153
|
-
}
|
|
363154
|
-
}
|
|
363155
|
-
if (op === OperationType.RETRY_SYNC.toString() &&
|
|
363156
|
-
foundPolicy?.allowedOps.includes(OperationType.SYNC.toString())) {
|
|
363157
|
-
if ('deletionTimestamp' in item.metadata && 'full-control' !== policy) {
|
|
363158
|
-
msg = `A RETRY_SYNC operation is not allowed on a resource with a deletionTimestamp. It means
|
|
363159
|
-
that the resource is being deleted and it is not possible to retry the operation with policy: ${policy}.
|
|
363160
|
-
|
|
363161
|
-
To fix this issue, you must first delete the "firestartr.dev/finalizer" from finalizers array in the resource manifest,
|
|
363162
|
-
it will be automatically deleted by Kubernetes. Terraform will not execute any operation on the resource.
|
|
363163
|
-
`;
|
|
363164
|
-
return { allowed: false, msg };
|
|
363165
|
-
}
|
|
363166
|
-
return { allowed: true, msg };
|
|
363167
|
-
}
|
|
363168
|
-
if (!foundPolicy) {
|
|
363169
|
-
msg = `Policy ${policy} not found`;
|
|
363170
|
-
return { allowed: false, msg };
|
|
363171
|
-
}
|
|
363172
|
-
const allowed = foundPolicy.allowedOps.includes(op);
|
|
363173
|
-
if (!allowed) {
|
|
363174
|
-
msg = searchAllowedPolicies(op, policy);
|
|
363175
|
-
}
|
|
363176
|
-
return { allowed, msg };
|
|
363177
|
-
}
|
|
363178
|
-
function searchAllowedPolicies(op, policy) {
|
|
363179
|
-
const allowedPolicies = [];
|
|
363180
|
-
for (const policy of catalog_common/* default.policies.FIRESTARTR_POLICIES */.Z.policies.FIRESTARTR_POLICIES) {
|
|
363181
|
-
if (policy.allowedOps.includes(op)) {
|
|
363182
|
-
allowedPolicies.push(policy.name);
|
|
363183
|
-
}
|
|
363184
|
-
}
|
|
363185
|
-
let policies = '';
|
|
363186
|
-
if (allowedPolicies.length > 0) {
|
|
363187
|
-
policies = allowedPolicies.join(', ');
|
|
363188
|
-
}
|
|
363189
|
-
return `
|
|
363190
|
-
|
|
363191
|
-
Operation ${op} not allowed by policy \`${policy}\`, to allow this operation,
|
|
363192
|
-
|
|
363193
|
-
switch to one of the following policies: \`${policies}\`
|
|
363194
|
-
|
|
363195
|
-
`;
|
|
363196
|
-
}
|
|
363197
|
-
async function* errorPolicyCompatibility(syncPolicy, generalPolicy, item, op) {
|
|
363198
|
-
const message = `Conflict: 'sync-policy': ${syncPolicy} and 'policy': ${generalPolicy} are not compatible`;
|
|
363199
|
-
for (const typeStatus of [
|
|
363200
|
-
['ERROR', 'True'],
|
|
363201
|
-
['PROVISIONED', 'False'],
|
|
363202
|
-
['PROVISIONING', 'False'],
|
|
363203
|
-
['OUT_OF_SYNC', 'False'],
|
|
363204
|
-
['DELETED', 'False'],
|
|
363205
|
-
['PLANNING', 'False'],
|
|
363206
|
-
['DELETING', 'False'],
|
|
363207
|
-
]) {
|
|
363208
|
-
const [type, status] = typeStatus;
|
|
363209
|
-
yield {
|
|
363210
|
-
item,
|
|
363211
|
-
reason: op,
|
|
363212
|
-
type,
|
|
363213
|
-
status,
|
|
363214
|
-
message,
|
|
363215
|
-
};
|
|
363216
|
-
}
|
|
363217
|
-
await tryPublishError(item, op, message);
|
|
363218
|
-
}
|
|
363219
|
-
|
|
363220
363460
|
;// CONCATENATED MODULE: ../operator/src/user-feedback-ops/tf-checkrun.ts
|
|
363221
363461
|
|
|
363222
363462
|
|
|
@@ -363229,7 +363469,12 @@ async function TFCheckRun(cmd, item) {
|
|
|
363229
363469
|
const prInfo = extractPrInfo(item);
|
|
363230
363470
|
const checkRun = await tf_checkrun_operatorProfile().feedback.createCheckRun(prInfo.org, prInfo.repo, helperCreateCheckRunName(cmd, item), {
|
|
363231
363471
|
pullNumber: Number(prInfo.prNumber),
|
|
363232
|
-
//
|
|
363472
|
+
// Apply progress comment: the result publisher updates this same
|
|
363473
|
+
// comment in place when the operation ends (shared sticky base
|
|
363474
|
+
// kind keyed per resource).
|
|
363475
|
+
includeCheckRunComment: true,
|
|
363476
|
+
checkRunComment: progressCommentText(cmd, item),
|
|
363477
|
+
stickyCommentBaseKind: progressCommentBaseKind(cmd, item),
|
|
363233
363478
|
});
|
|
363234
363479
|
checkRun.mdOptionsDetails({
|
|
363235
363480
|
quotes: 'terraform',
|
|
@@ -363327,6 +363572,93 @@ function extractErrorDetails(error) {
|
|
|
363327
363572
|
return { output: String(error), exitCode };
|
|
363328
363573
|
}
|
|
363329
363574
|
|
|
363575
|
+
;// CONCATENATED MODULE: ../operator/src/tfworkspaces/policies.ts
|
|
363576
|
+
|
|
363577
|
+
|
|
363578
|
+
|
|
363579
|
+
function policyAllowsOp(policy, op, item) {
|
|
363580
|
+
let msg = '';
|
|
363581
|
+
const foundPolicy = catalog_common/* default.policies.getPolicyByName */.Z.policies.getPolicyByName(policy);
|
|
363582
|
+
if (op === OperationType.RETRY.toString() &&
|
|
363583
|
+
foundPolicy?.allowedOps.includes(op)) {
|
|
363584
|
+
if ('deletionTimestamp' in item.metadata && 'full-control' !== policy) {
|
|
363585
|
+
msg = `A RETRY operation is not allowed on a resource with a deletionTimestamp. It means
|
|
363586
|
+
that the resource is being deleted and it is not possible to retry the operation with policy: ${policy}.
|
|
363587
|
+
|
|
363588
|
+
To fix this issue, you must first delete the "firestartr.dev/finalizer" from finalizers array in the resource manifest,
|
|
363589
|
+
it will be automatically deleted by Kubernetes. Terraform will not execute any operation on the resource.
|
|
363590
|
+
`;
|
|
363591
|
+
return { allowed: false, msg };
|
|
363592
|
+
}
|
|
363593
|
+
else {
|
|
363594
|
+
return { allowed: true, msg };
|
|
363595
|
+
}
|
|
363596
|
+
}
|
|
363597
|
+
if (op === OperationType.RETRY_SYNC.toString() &&
|
|
363598
|
+
foundPolicy?.allowedOps.includes(OperationType.SYNC.toString())) {
|
|
363599
|
+
if ('deletionTimestamp' in item.metadata && 'full-control' !== policy) {
|
|
363600
|
+
msg = `A RETRY_SYNC operation is not allowed on a resource with a deletionTimestamp. It means
|
|
363601
|
+
that the resource is being deleted and it is not possible to retry the operation with policy: ${policy}.
|
|
363602
|
+
|
|
363603
|
+
To fix this issue, you must first delete the "firestartr.dev/finalizer" from finalizers array in the resource manifest,
|
|
363604
|
+
it will be automatically deleted by Kubernetes. Terraform will not execute any operation on the resource.
|
|
363605
|
+
`;
|
|
363606
|
+
return { allowed: false, msg };
|
|
363607
|
+
}
|
|
363608
|
+
return { allowed: true, msg };
|
|
363609
|
+
}
|
|
363610
|
+
if (!foundPolicy) {
|
|
363611
|
+
msg = `Policy ${policy} not found`;
|
|
363612
|
+
return { allowed: false, msg };
|
|
363613
|
+
}
|
|
363614
|
+
const allowed = foundPolicy.allowedOps.includes(op);
|
|
363615
|
+
if (!allowed) {
|
|
363616
|
+
msg = searchAllowedPolicies(op, policy);
|
|
363617
|
+
}
|
|
363618
|
+
return { allowed, msg };
|
|
363619
|
+
}
|
|
363620
|
+
function searchAllowedPolicies(op, policy) {
|
|
363621
|
+
const allowedPolicies = [];
|
|
363622
|
+
for (const policy of catalog_common/* default.policies.FIRESTARTR_POLICIES */.Z.policies.FIRESTARTR_POLICIES) {
|
|
363623
|
+
if (policy.allowedOps.includes(op)) {
|
|
363624
|
+
allowedPolicies.push(policy.name);
|
|
363625
|
+
}
|
|
363626
|
+
}
|
|
363627
|
+
let policies = '';
|
|
363628
|
+
if (allowedPolicies.length > 0) {
|
|
363629
|
+
policies = allowedPolicies.join(', ');
|
|
363630
|
+
}
|
|
363631
|
+
return `
|
|
363632
|
+
|
|
363633
|
+
Operation ${op} not allowed by policy \`${policy}\`, to allow this operation,
|
|
363634
|
+
|
|
363635
|
+
switch to one of the following policies: \`${policies}\`
|
|
363636
|
+
|
|
363637
|
+
`;
|
|
363638
|
+
}
|
|
363639
|
+
async function* errorPolicyCompatibility(syncPolicy, generalPolicy, item, op) {
|
|
363640
|
+
const message = `Conflict: 'sync-policy': ${syncPolicy} and 'policy': ${generalPolicy} are not compatible`;
|
|
363641
|
+
for (const typeStatus of [
|
|
363642
|
+
['ERROR', 'True'],
|
|
363643
|
+
['PROVISIONED', 'False'],
|
|
363644
|
+
['PROVISIONING', 'False'],
|
|
363645
|
+
['OUT_OF_SYNC', 'False'],
|
|
363646
|
+
['DELETED', 'False'],
|
|
363647
|
+
['PLANNING', 'False'],
|
|
363648
|
+
['DELETING', 'False'],
|
|
363649
|
+
]) {
|
|
363650
|
+
const [type, status] = typeStatus;
|
|
363651
|
+
yield {
|
|
363652
|
+
item,
|
|
363653
|
+
reason: op,
|
|
363654
|
+
type,
|
|
363655
|
+
status,
|
|
363656
|
+
message,
|
|
363657
|
+
};
|
|
363658
|
+
}
|
|
363659
|
+
await tryPublishError(item, op, message);
|
|
363660
|
+
}
|
|
363661
|
+
|
|
363330
363662
|
;// CONCATENATED MODULE: ../operator/src/tfworkspaces/process-operation.ts
|
|
363331
363663
|
|
|
363332
363664
|
|
|
@@ -363339,11 +363671,36 @@ function extractErrorDetails(error) {
|
|
|
363339
363671
|
|
|
363340
363672
|
|
|
363341
363673
|
|
|
363674
|
+
|
|
363342
363675
|
const TF_PROJECTS_PATH = '/tmp/tfworkspaces';
|
|
363343
363676
|
const TF_CACHES_PATH = '/tmp/tfcaches';
|
|
363344
363677
|
function generateSessionId() {
|
|
363345
363678
|
return Math.random().toString(36).substring(2, 6).padEnd(4, '0');
|
|
363346
363679
|
}
|
|
363680
|
+
// Recursively copy session workspace to debugPath (best-effort)
|
|
363681
|
+
async function copyDir(src, dest) {
|
|
363682
|
+
await promises_.mkdir(dest, { recursive: true });
|
|
363683
|
+
const entries = await promises_.readdir(src, { withFileTypes: true });
|
|
363684
|
+
for (const e of entries) {
|
|
363685
|
+
const s = external_path_.join(src, e.name);
|
|
363686
|
+
const d = external_path_.join(dest, e.name);
|
|
363687
|
+
if (e.isDirectory()) {
|
|
363688
|
+
await copyDir(s, d);
|
|
363689
|
+
}
|
|
363690
|
+
else if (e.isSymbolicLink()) {
|
|
363691
|
+
try {
|
|
363692
|
+
const link = await promises_.readlink(s);
|
|
363693
|
+
await promises_.symlink(link, d);
|
|
363694
|
+
}
|
|
363695
|
+
catch (err) {
|
|
363696
|
+
// ignore symlink copy failures
|
|
363697
|
+
}
|
|
363698
|
+
}
|
|
363699
|
+
else {
|
|
363700
|
+
await promises_.copyFile(s, d);
|
|
363701
|
+
}
|
|
363702
|
+
}
|
|
363703
|
+
}
|
|
363347
363704
|
async function tearUpSessionWorkspace(item, deps, sessionId, failureContext) {
|
|
363348
363705
|
try {
|
|
363349
363706
|
const context = buildProvisionerContext(item, deps, sessionId);
|
|
@@ -363735,6 +364092,9 @@ async function* process_operation_sync(item, op, handler, syncPolicy, generalPol
|
|
|
363735
364092
|
}
|
|
363736
364093
|
}
|
|
363737
364094
|
async function* process_operation_markedToDeletion(item, op, handler) {
|
|
364095
|
+
// Apply progress comment: announces the destroy on the wet-repo PR and
|
|
364096
|
+
// streams its output; the result publisher updates it in place at the end.
|
|
364097
|
+
const checkRunCtl = await TFCheckRun('destroy', item);
|
|
363738
364098
|
let error = false;
|
|
363739
364099
|
let deps;
|
|
363740
364100
|
let terraformExecutionStarted = false;
|
|
@@ -363799,7 +364159,7 @@ async function* process_operation_markedToDeletion(item, op, handler) {
|
|
|
363799
364159
|
deps = await handler.resolveReferences();
|
|
363800
364160
|
const context = buildProvisionerContext(item, deps, sessionId);
|
|
363801
364161
|
terraformExecutionStarted = true;
|
|
363802
|
-
const destroyOutput = await runTerraformProvisioner(context, 'destroy',
|
|
364162
|
+
const destroyOutput = await runTerraformProvisioner(context, 'destroy', checkRunCtl, undefined, {
|
|
363803
364163
|
tfCacheDir: external_path_.join(TF_CACHES_PATH, `slot_${handler.getSlotInfo().slotId}`),
|
|
363804
364164
|
hardTimeout: handler.recommendedTimeout(),
|
|
363805
364165
|
processKilled: (killed) => {
|
|
@@ -363836,6 +364196,7 @@ async function* process_operation_markedToDeletion(item, op, handler) {
|
|
|
363836
364196
|
catch (e) {
|
|
363837
364197
|
error = true;
|
|
363838
364198
|
const { output: errorMsg } = extractErrorDetails(e);
|
|
364199
|
+
checkRunCtl.fnOnError(errorMsg);
|
|
363839
364200
|
await tryPublishDestroy(item, errorMsg, false);
|
|
363840
364201
|
await handler.writeTerraformOutputInTfResult(item, errorMsg, 1);
|
|
363841
364202
|
if (item.metadata.annotations['firestartr.dev/last-state-pr'] || false) {
|
|
@@ -363945,6 +364306,7 @@ async function* doApply(item, op, handler) {
|
|
|
363945
364306
|
operator_src_logger.info(`The Terraform processor is applying and assessing dependencies for item '${item.kind}/${item.metadata.name}' with dependencies: '${deps}'.`);
|
|
363946
364307
|
const context = buildProvisionerContext(item, deps, sessionId);
|
|
363947
364308
|
terraformExecutionStarted = true;
|
|
364309
|
+
operator_src_logger.info(`[operator]: runTerraformProvisioner apply - projectPath=${context.projectPath} reuseExistingProject=${context.reuseExistingProject}`);
|
|
363948
364310
|
const applyOutput = await runTerraformProvisioner(context, 'apply', checkRunCtl, undefined, {
|
|
363949
364311
|
tfCacheDir: external_path_.join(TF_CACHES_PATH, `slot_${handler.getSlotInfo().slotId}`),
|
|
363950
364312
|
hardTimeout: handler.recommendedTimeout(),
|
|
@@ -363957,7 +364319,70 @@ async function* doApply(item, op, handler) {
|
|
|
363957
364319
|
}
|
|
363958
364320
|
},
|
|
363959
364321
|
});
|
|
364322
|
+
// If tf-debug annotation is present, create a snapshot copy of the
|
|
364323
|
+
// session-scoped workspace into the deterministic debug folder. We do
|
|
364324
|
+
// this as a best-effort, non-fatal operation so debug artifacts are
|
|
364325
|
+
// available for inspection without interfering with the reuse flow.
|
|
364326
|
+
try {
|
|
364327
|
+
const tfDebug = item && item.metadata && item.metadata.annotations
|
|
364328
|
+
? item.metadata.annotations['firestartr.dev/tf-debug']
|
|
364329
|
+
: undefined;
|
|
364330
|
+
if (sessionId && tfDebug === '1' && context.projectPath) {
|
|
364331
|
+
const rawName = item.metadata.name;
|
|
364332
|
+
const baseName = rawName.replace(/-[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/, // strip uuid
|
|
364333
|
+
'');
|
|
364334
|
+
const tfStateKey = context.tfStateKey ||
|
|
364335
|
+
item?.spec?.firestartr?.tfStateKey;
|
|
364336
|
+
const safeKey = tfStateKey
|
|
364337
|
+
? String(tfStateKey).replace(/\//g, '-')
|
|
364338
|
+
: '';
|
|
364339
|
+
const debugPath = external_path_.join('/tmp/tf-debug', `${item.kind.toLowerCase()}-${baseName}${safeKey ? `-${safeKey}` : ''}`);
|
|
364340
|
+
// If the session workspace is already the deterministic debugPath,
|
|
364341
|
+
// do not remove or copy it (that would delete the freshly-created
|
|
364342
|
+
// workspace). Instead, just ensure the debug artifacts folder exists
|
|
364343
|
+
// and write the metadata files there. When the source and target are
|
|
364344
|
+
// different, perform a best-effort copy as before.
|
|
364345
|
+
const srcPath = context.projectPath;
|
|
364346
|
+
try {
|
|
364347
|
+
if (srcPath && external_path_.resolve(srcPath) === external_path_.resolve(debugPath)) {
|
|
364348
|
+
const debugArtifactsDir = external_path_.join(debugPath, 'tf_provisioner_debug');
|
|
364349
|
+
await promises_.mkdir(debugArtifactsDir, { recursive: true });
|
|
364350
|
+
await promises_.writeFile(external_path_.join(debugArtifactsDir, 'cr.yaml'), catalog_common/* default.io.toYaml */.Z.io.toYaml(item));
|
|
364351
|
+
await promises_.writeFile(external_path_.join(debugArtifactsDir, 'deps.yaml'), catalog_common/* default.io.toYaml */.Z.io.toYaml(deps));
|
|
364352
|
+
operator_src_logger.info(`[operator]: debug snapshot preserved at ${debugPath}`);
|
|
364353
|
+
}
|
|
364354
|
+
else {
|
|
364355
|
+
// Remove any previous debug snapshot; ignore failures
|
|
364356
|
+
try {
|
|
364357
|
+
await promises_.rm(debugPath, { recursive: true, force: true });
|
|
364358
|
+
}
|
|
364359
|
+
catch (e) {
|
|
364360
|
+
operator_src_logger.warn(`Failed to remove existing debug path ${debugPath}: ${e}`);
|
|
364361
|
+
}
|
|
364362
|
+
try {
|
|
364363
|
+
if (srcPath)
|
|
364364
|
+
await copyDir(srcPath, debugPath);
|
|
364365
|
+
const debugArtifactsDir = external_path_.join(debugPath, 'tf_provisioner_debug');
|
|
364366
|
+
await promises_.mkdir(debugArtifactsDir, { recursive: true });
|
|
364367
|
+
await promises_.writeFile(external_path_.join(debugArtifactsDir, 'cr.yaml'), catalog_common/* default.io.toYaml */.Z.io.toYaml(item));
|
|
364368
|
+
await promises_.writeFile(external_path_.join(debugArtifactsDir, 'deps.yaml'), catalog_common/* default.io.toYaml */.Z.io.toYaml(deps));
|
|
364369
|
+
operator_src_logger.info(`[operator]: debug snapshot created at ${debugPath}`);
|
|
364370
|
+
}
|
|
364371
|
+
catch (e) {
|
|
364372
|
+
operator_src_logger.warn(`[operator]: failed to snapshot debug workspace: ${e}`);
|
|
364373
|
+
}
|
|
364374
|
+
}
|
|
364375
|
+
}
|
|
364376
|
+
catch (e) {
|
|
364377
|
+
operator_src_logger.warn(`[operator]: debug snapshot flow failed: ${e}`);
|
|
364378
|
+
}
|
|
364379
|
+
}
|
|
364380
|
+
}
|
|
364381
|
+
catch (e) {
|
|
364382
|
+
operator_src_logger.warn(`[operator]: debug snapshot flow failed: ${e}`);
|
|
364383
|
+
}
|
|
363960
364384
|
context.reuseExistingProject = true;
|
|
364385
|
+
operator_src_logger.info(`[operator]: runTerraformProvisioner output - projectPath=${context.projectPath} reuseExistingProject=${context.reuseExistingProject}`);
|
|
363961
364386
|
const terraformOutputJson = await runTerraformProvisioner(context, 'output');
|
|
363962
364387
|
if (!terraformOutputJson) {
|
|
363963
364388
|
throw new Error(`Terraform output is empty for ${item.kind}/${item.metadata.name}`);
|
|
@@ -364113,6 +364538,16 @@ function buildProvisionerContext(item, deps, sessionId) {
|
|
|
364113
364538
|
if (typeof tfStateKey !== 'string' || tfStateKey.trim() === '') {
|
|
364114
364539
|
throw new Error(`Invalid terraform state key: ${tfStateKey}`);
|
|
364115
364540
|
}
|
|
364541
|
+
// Preserve the raw CR and resolved dependencies on the context so provisioners
|
|
364542
|
+
// can emit debug artifacts when requested. This is intentionally additive
|
|
364543
|
+
// and does not change the public runTerraformProvisioner API shape.
|
|
364544
|
+
context['rawCr'] = item;
|
|
364545
|
+
context['deps'] = deps;
|
|
364546
|
+
// Always use a session-scoped projectPath for apply/plan/etc when a
|
|
364547
|
+
// sessionId is provided. Do not hand the deterministic debug path to the
|
|
364548
|
+
// provisioner; instead, the operator will perform a copy to /tmp/tf-debug
|
|
364549
|
+
// after apply if the tf-debug annotation is present. This avoids races and
|
|
364550
|
+
// accidental deletion of debug folders during the provisioner lifecycle.
|
|
364116
364551
|
if (sessionId) {
|
|
364117
364552
|
context['projectPath'] = external_path_.join(TF_PROJECTS_PATH, `${item.kind.toLowerCase()}-${item.metadata.name}-${sessionId}`);
|
|
364118
364553
|
}
|
|
@@ -366513,13 +366948,17 @@ function providers_replaceInlineSecrets(inline, secrets) {
|
|
|
366513
366948
|
const DEBUG_DIR = external_path_default().join(external_os_default().tmpdir(), 'gh-debug');
|
|
366514
366949
|
// Returns the project path to use for debug artifacts (always SessionProjectPath for consistency)
|
|
366515
366950
|
function getDebugProjectPath(entity) {
|
|
366516
|
-
// Use the sessionProjectPath
|
|
366951
|
+
// Use the sessionProjectPath if present. sessionProjectPath will include
|
|
366952
|
+
// the tfStateKey suffix when in debug mode, as set by runGhProvisioner.
|
|
366517
366953
|
return (entity.sessionProjectPath ||
|
|
366518
366954
|
external_path_default().join(DEBUG_DIR, entity.k8sId.replace(/\//, '-') + '-id_missing'));
|
|
366519
366955
|
}
|
|
366520
366956
|
async function initDebug(entity, deps) {
|
|
366521
|
-
//
|
|
366522
|
-
//
|
|
366957
|
+
// If a previous deterministic debug folder exists for this resource, wipe it
|
|
366958
|
+
// We intentionally remove only the per-claim debug folder (the whole folder)
|
|
366959
|
+
// to ensure a fresh debug run and avoid accumulating files between runs.
|
|
366960
|
+
await (0,promises_namespaceObject.rm)(getDebugProjectPath(entity), { recursive: true, force: true });
|
|
366961
|
+
// Create the (fresh) project path and debug artifacts dir
|
|
366523
366962
|
await (0,promises_namespaceObject.mkdir)(getDebugProjectPath(entity), { recursive: true });
|
|
366524
366963
|
const debugArtifactsDir = external_path_default().join(getDebugProjectPath(entity), 'gh_provisioner_debug');
|
|
366525
366964
|
await (0,promises_namespaceObject.mkdir)(debugArtifactsDir, { recursive: true });
|
|
@@ -367442,9 +367881,21 @@ async function runGhProvisioner(data, opts) {
|
|
|
367442
367881
|
try {
|
|
367443
367882
|
entity = await initSystem(data.mainCr, data.deps);
|
|
367444
367883
|
// Generate per-execution sessionId and session projectPath
|
|
367884
|
+
// For debug mode we want a deterministic per-resource folder (no random suffix)
|
|
367885
|
+
// Use the resource's tfStateKey when present for stability, otherwise fall
|
|
367886
|
+
// back to metadata UID-like deterministic id stored on the CR name/fields.
|
|
367445
367887
|
sessionId = generateSessionId();
|
|
367446
367888
|
if (entity.inDebugMode) {
|
|
367447
|
-
|
|
367889
|
+
// Use deterministic per-resource folder under /tmp/gh-debug. Include
|
|
367890
|
+
// the tfStateKey as a suffix when available to avoid collisions for
|
|
367891
|
+
// resources (like features) that share a human-friendly name.
|
|
367892
|
+
const rawName = entity.cr.name;
|
|
367893
|
+
const baseName = rawName.replace(/-[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/, '');
|
|
367894
|
+
const tfStateKey = entity.cr?.spec?.firestartr?.tfStateKey;
|
|
367895
|
+
const safeKey = typeof tfStateKey === 'string' && tfStateKey.trim() !== ''
|
|
367896
|
+
? tfStateKey
|
|
367897
|
+
: null;
|
|
367898
|
+
sessionProjectPath = `/tmp/gh-debug/${entity.cr.kind.toLowerCase()}-${baseName}${safeKey ? `-${safeKey}` : ''}`;
|
|
367448
367899
|
}
|
|
367449
367900
|
else {
|
|
367450
367901
|
sessionProjectPath = `/tmp/gh-workspaces/${entity.cr.kind.toLowerCase()}-${entity.cr.name}-${sessionId}`;
|
|
@@ -368442,6 +368893,11 @@ async function* gh_process_operation_markedToDeletion(item, op, handler) {
|
|
|
368442
368893
|
// we close it with an error
|
|
368443
368894
|
if (checkRunCtl)
|
|
368444
368895
|
checkRunCtl.fnOnError(errorMsg);
|
|
368896
|
+
// also close the Terraform check run: its periodic flush would
|
|
368897
|
+
// otherwise keep rewriting the apply progress comment after the
|
|
368898
|
+
// final destroy result is published
|
|
368899
|
+
if (checkRunTFCtl)
|
|
368900
|
+
checkRunTFCtl.fnOnError(errorMsg);
|
|
368445
368901
|
await tryPublishDestroy(item, errorMsg, false);
|
|
368446
368902
|
await handler.writeTerraformOutputInTfResult(item, errorMsg, errCode ?? 1);
|
|
368447
368903
|
void handler.error();
|
|
@@ -368696,10 +369152,18 @@ async function tfPlanner(claimFilePath, claim, namespace, debug, jobTtl = 300, c
|
|
|
368696
369152
|
job.spec.ttlSecondsAfterFinished = jobTtl;
|
|
368697
369153
|
job.spec.template = controllerDeploy.spec.template;
|
|
368698
369154
|
job.spec.template.spec.containers[0].image = withToolImageTag(job.spec.template.spec.containers[0].image, toolImageTag);
|
|
368699
|
-
|
|
368700
|
-
|
|
368701
|
-
|
|
369155
|
+
if (!debug) {
|
|
369156
|
+
// set activeDeadlineSeconds to force terminate jobs that exceed this time
|
|
369157
|
+
// see https://kubernetes.io/docs/concepts/workloads/controllers/job/#job-termination-and-cleanup
|
|
369158
|
+
job.spec.activeDeadlineSeconds = 3600;
|
|
369159
|
+
}
|
|
368702
369160
|
job.spec.template.spec.containers[0].env = [{ name: 'CI', value: 'True' }];
|
|
369161
|
+
if (debug) {
|
|
369162
|
+
job.spec.template.spec.containers[0].env.push({
|
|
369163
|
+
name: 'FIRESTARTR_DEBUG',
|
|
369164
|
+
value: 'true',
|
|
369165
|
+
});
|
|
369166
|
+
}
|
|
368703
369167
|
job.spec.template.spec.containers[0].command = [
|
|
368704
369168
|
'sh',
|
|
368705
369169
|
'-c',
|
|
@@ -368707,7 +369171,7 @@ async function tfPlanner(claimFilePath, claim, namespace, debug, jobTtl = 300, c
|
|
|
368707
369171
|
];
|
|
368708
369172
|
if (debug) {
|
|
368709
369173
|
job.spec.template.spec.containers[0].command[2] =
|
|
368710
|
-
job.spec.template.spec.containers[0].command[2].concat('
|
|
369174
|
+
job.spec.template.spec.containers[0].command[2].concat(' ; tail -f /dev/null');
|
|
368711
369175
|
}
|
|
368712
369176
|
job.spec.template.spec.restartPolicy = 'Never';
|
|
368713
369177
|
job.metadata = metadata;
|
|
@@ -368722,7 +369186,7 @@ async function tfPlanner(claimFilePath, claim, namespace, debug, jobTtl = 300, c
|
|
|
368722
369186
|
ctlCleanUp: () => cleanUp(namespace, metadata.name),
|
|
368723
369187
|
});
|
|
368724
369188
|
await batchV1Api.createNamespacedJob({ namespace, body: job });
|
|
368725
|
-
await copyClaimAndGetLogs(namespace, job.metadata.name, claimFilePath);
|
|
369189
|
+
await copyClaimAndGetLogs(namespace, job.metadata.name, claimFilePath, debug);
|
|
368726
369190
|
}
|
|
368727
369191
|
async function cleanUp(namespace, jobName) {
|
|
368728
369192
|
try {
|
|
@@ -368733,7 +369197,7 @@ async function cleanUp(namespace, jobName) {
|
|
|
368733
369197
|
await batchV1Api.deleteNamespacedJob({
|
|
368734
369198
|
name: jobName,
|
|
368735
369199
|
namespace,
|
|
368736
|
-
gracePeriodSeconds:
|
|
369200
|
+
gracePeriodSeconds: 0,
|
|
368737
369201
|
propagationPolicy: 'Foreground',
|
|
368738
369202
|
});
|
|
368739
369203
|
}
|
|
@@ -368746,7 +369210,7 @@ async function cleanUp(namespace, jobName) {
|
|
|
368746
369210
|
console.error(cleanError);
|
|
368747
369211
|
}
|
|
368748
369212
|
}
|
|
368749
|
-
async function copyClaimAndGetLogs(namespace, jobName, sourcePath) {
|
|
369213
|
+
async function copyClaimAndGetLogs(namespace, jobName, sourcePath, skipLogs = false) {
|
|
368750
369214
|
const { kc } = await getConnection();
|
|
368751
369215
|
const k8sApi = kc.makeApiClient(client.CoreV1Api);
|
|
368752
369216
|
const logStream = new stream.PassThrough();
|
|
@@ -368788,6 +369252,10 @@ async function copyClaimAndGetLogs(namespace, jobName, sourcePath) {
|
|
|
368788
369252
|
console.log('Copying claim to pod');
|
|
368789
369253
|
await kubectlCp(sourcePath, namespace, pod.metadata.name);
|
|
368790
369254
|
console.log('Claim copied to pod');
|
|
369255
|
+
if (skipLogs) {
|
|
369256
|
+
console.log('Debug mode: skipping log streaming');
|
|
369257
|
+
return;
|
|
369258
|
+
}
|
|
368791
369259
|
try {
|
|
368792
369260
|
const logClient = new client.Log(kc);
|
|
368793
369261
|
await new Promise((resolve, reject) => {
|
|
@@ -713425,7 +713893,7 @@ const crsStatusSubcommand = {
|
|
|
713425
713893
|
};
|
|
713426
713894
|
|
|
713427
713895
|
;// CONCATENATED MODULE: ./package.json
|
|
713428
|
-
const package_namespaceObject = JSON.parse('{"i8":"2.11.0-snapshot-
|
|
713896
|
+
const package_namespaceObject = JSON.parse('{"i8":"2.11.0-snapshot-importer-filter-fix-3"}');
|
|
713429
713897
|
;// CONCATENATED MODULE: ../../package.json
|
|
713430
713898
|
const package_namespaceObject_1 = {"i8":"2.10.0"};
|
|
713431
713899
|
// EXTERNAL MODULE: ../../node_modules/semver/index.js
|