@firestartr/cli 2.8.0-snapshot-variant-cloning-test-1 → 2.8.0-snapshot-variant-cloning-2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.js +355 -66
- package/build/packages/cdk8s_renderer/src/claims/base/schemas/index.d.ts +1 -4
- package/build/packages/cdk8s_renderer/src/claims/tfworkspaces/index.d.ts +1 -4
- package/build/packages/cdk8s_renderer/src/claims/tfworkspaces/terraform.schema.d.ts +1 -4
- package/build/packages/operator/src/definitions.d.ts +4 -1
- package/build/packages/operator/src/gh/process-operation.d.ts +14 -0
- package/build/packages/operator/src/retry.d.ts +1 -2
- package/build/packages/operator/src/retry.debug.d.ts +11 -0
- package/build/packages/operator/src/syncer.d.ts +3 -0
- package/build/packages/operator/src/tfworkspaces/process-operation.d.ts +21 -0
- package/build/packages/terraform_provisioner/src/utils.d.ts +5 -1
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -317375,10 +317375,12 @@ class InitializerClaimRef extends InitializerPatches {
|
|
|
317375
317375
|
apply(cr) {
|
|
317376
317376
|
cr.metadata = cr.metadata ?? {};
|
|
317377
317377
|
cr.metadata.labels = cr.metadata.labels ?? {};
|
|
317378
|
-
|
|
317378
|
+
const claimName = claim._parentClaimName || claim.name;
|
|
317379
|
+
cr.metadata.labels['claim-ref'] =
|
|
317380
|
+
catalog_common/* default.generic.normalizeLabel */.Z.generic.normalizeLabel(claimName);
|
|
317379
317381
|
cr.metadata.annotations = {
|
|
317380
317382
|
...(cr.metadata.annotations || {}),
|
|
317381
|
-
[catalog_common/* default.generic.getFirestartrAnnotation */.Z.generic.getFirestartrAnnotation('claim-ref')]: `${claim.kind}/${
|
|
317383
|
+
[catalog_common/* default.generic.getFirestartrAnnotation */.Z.generic.getFirestartrAnnotation('claim-ref')]: `${claim.kind}/${claimName}`,
|
|
317382
317384
|
};
|
|
317383
317385
|
return cr;
|
|
317384
317386
|
},
|
|
@@ -320729,10 +320731,6 @@ const GithubSchemas = [
|
|
|
320729
320731
|
description: 'Override fields for a variant of a TFWorkspaceClaim',
|
|
320730
320732
|
type: 'object',
|
|
320731
320733
|
properties: {
|
|
320732
|
-
name: {
|
|
320733
|
-
type: 'string',
|
|
320734
|
-
description: 'override the terraform provider name',
|
|
320735
|
-
},
|
|
320736
320734
|
values: {
|
|
320737
320735
|
type: 'object',
|
|
320738
320736
|
additionalProperties: true,
|
|
@@ -320799,7 +320797,8 @@ const GithubSchemas = [
|
|
|
320799
320797
|
properties: {
|
|
320800
320798
|
name: {
|
|
320801
320799
|
type: 'string',
|
|
320802
|
-
|
|
320800
|
+
maxLength: 10,
|
|
320801
|
+
description: 'shorthand suffix — composed with main tf name to form the final CR name',
|
|
320803
320802
|
},
|
|
320804
320803
|
overrides: {
|
|
320805
320804
|
$ref: 'firestartr.dev://terraform/TerraformProviderVariantOverride',
|
|
@@ -321327,26 +321326,26 @@ async function loadClaim(claimRef, org, defaults = loadClaimDefaults(), patchCla
|
|
|
321327
321326
|
if (!variant.name || !variant.overrides) {
|
|
321328
321327
|
throw new Error(`Variant in claim ${claimRef} is missing required field 'name' or 'overrides'`);
|
|
321329
321328
|
}
|
|
321330
|
-
const prohibitedOverrideFields = ['source', 'module'];
|
|
321329
|
+
const prohibitedOverrideFields = ['source', 'module', 'name'];
|
|
321331
321330
|
for (const field of prohibitedOverrideFields) {
|
|
321332
321331
|
if (field in variant.overrides) {
|
|
321333
321332
|
throw new Error(`Variant '${variant.name}' in claim ${claimRef} cannot override '${field}'`);
|
|
321334
321333
|
}
|
|
321335
321334
|
}
|
|
321335
|
+
const composedName = claim.providers.terraform.name + '-' + variant.name;
|
|
321336
321336
|
const variantClaim = lodash_default().cloneDeep(claim);
|
|
321337
|
-
variantClaim.
|
|
321337
|
+
variantClaim._parentClaimName = claim.name;
|
|
321338
|
+
variantClaim.name = composedName;
|
|
321338
321339
|
variantClaim.providers.terraform = lodash_default().merge({}, claim.providers.terraform, variant.overrides);
|
|
321339
|
-
|
|
321340
|
-
variantClaim.providers.terraform.name = variant.name;
|
|
321341
|
-
}
|
|
321340
|
+
variantClaim.providers.terraform.name = composedName;
|
|
321342
321341
|
if (!variantClaim.annotations) {
|
|
321343
321342
|
variantClaim.annotations = {};
|
|
321344
321343
|
}
|
|
321345
321344
|
variantClaim.annotations['firestartr.dev/variant-of'] =
|
|
321346
321345
|
claim.providers.terraform.name;
|
|
321347
|
-
const variantRef = `TFWorkspaceClaim-${
|
|
321346
|
+
const variantRef = `TFWorkspaceClaim-${composedName}`;
|
|
321348
321347
|
if (result[variantRef]) {
|
|
321349
|
-
throw new Error(`Variant name '${variant.name}' from claim '${claimRef}' conflicts with existing claim '${variantRef}'`);
|
|
321348
|
+
throw new Error(`Variant name '${variant.name}' (composed: '${composedName}') from claim '${claimRef}' conflicts with existing claim '${variantRef}'`);
|
|
321350
321349
|
}
|
|
321351
321350
|
logger.info(`Creating synthetic variant claim ${variantRef}`);
|
|
321352
321351
|
result[variantRef] = {};
|
|
@@ -331003,7 +331002,19 @@ var OperationType;
|
|
|
331003
331002
|
OperationType["MARKED_TO_DELETION"] = "MARKED_TO_DELETION";
|
|
331004
331003
|
OperationType["NOTHING"] = "NOTHING";
|
|
331005
331004
|
OperationType["RETRY"] = "RETRY";
|
|
331005
|
+
OperationType["RETRY_SYNC"] = "RETRY_SYNC";
|
|
331006
331006
|
})(OperationType || (OperationType = {}));
|
|
331007
|
+
function retryOpForReason(reason) {
|
|
331008
|
+
if (!reason)
|
|
331009
|
+
return OperationType.RETRY;
|
|
331010
|
+
const base = reason.startsWith('RETRY_') ? reason.slice(6) : reason;
|
|
331011
|
+
switch (base) {
|
|
331012
|
+
case 'SYNC':
|
|
331013
|
+
return OperationType.RETRY_SYNC;
|
|
331014
|
+
default:
|
|
331015
|
+
return OperationType.RETRY;
|
|
331016
|
+
}
|
|
331017
|
+
}
|
|
331007
331018
|
var WorkStatus;
|
|
331008
331019
|
(function (WorkStatus) {
|
|
331009
331020
|
WorkStatus["PENDING"] = "PENDING";
|
|
@@ -331020,6 +331031,7 @@ const TIMEOUTS = {
|
|
|
331020
331031
|
UPDATED: DAY_SECONDS,
|
|
331021
331032
|
CREATED: DAY_SECONDS,
|
|
331022
331033
|
RETRY: 120 * 60,
|
|
331034
|
+
RETRY_SYNC: 120 * 60,
|
|
331023
331035
|
MARKED_TO_DELETION: DAY_SECONDS,
|
|
331024
331036
|
SYNC: DAY_SECONDS,
|
|
331025
331037
|
NOTHING: 10,
|
|
@@ -331257,13 +331269,13 @@ async function ctl_getItemByItemPath(itemPath, apiGroup = catalog_common/* defau
|
|
|
331257
331269
|
const r = await fetchItemByItemPathResponse(itemPath, apiGroup, apiVersion);
|
|
331258
331270
|
if (!r.ok) {
|
|
331259
331271
|
const err = new Error(`Error on getItemByItemPath: ${itemPath}: ${r.statusText}`);
|
|
331260
|
-
operator_src_logger.
|
|
331272
|
+
operator_src_logger.warn(`Error on getItemByItemPath: ${itemPath}: ${r.statusText}`);
|
|
331261
331273
|
throw err;
|
|
331262
331274
|
}
|
|
331263
331275
|
return await r.json();
|
|
331264
331276
|
}
|
|
331265
331277
|
catch (e) {
|
|
331266
|
-
operator_src_logger.
|
|
331278
|
+
operator_src_logger.warn(`Error on getItemByItemPath: ${e instanceof Error ? e.stack || e.message : JSON.stringify(e)}`);
|
|
331267
331279
|
throw e;
|
|
331268
331280
|
}
|
|
331269
331281
|
});
|
|
@@ -331284,13 +331296,13 @@ async function getItemByItemPathOrNull(itemPath, apiGroup = catalog_common/* def
|
|
|
331284
331296
|
}
|
|
331285
331297
|
if (!r.ok) {
|
|
331286
331298
|
const err = new Error(`Error on getItemByItemPathOrNull: ${itemPath}: ${r.statusText}`);
|
|
331287
|
-
operator_src_logger.
|
|
331299
|
+
operator_src_logger.warn(`Error on getItemByItemPathOrNull: ${itemPath}: ${r.statusText}`);
|
|
331288
331300
|
throw err;
|
|
331289
331301
|
}
|
|
331290
331302
|
return await r.json();
|
|
331291
331303
|
}
|
|
331292
331304
|
catch (e) {
|
|
331293
|
-
operator_src_logger.
|
|
331305
|
+
operator_src_logger.warn(`Error on getItemByItemPathOrNull: ${e instanceof Error ? e.stack || e.message : JSON.stringify(e)}`);
|
|
331294
331306
|
throw e;
|
|
331295
331307
|
}
|
|
331296
331308
|
});
|
|
@@ -331456,6 +331468,21 @@ async function upsertResult(namespace, item, result, exitCode = 0, existingRetry
|
|
|
331456
331468
|
headers: opts.headers,
|
|
331457
331469
|
body: JSON.stringify(resultObject),
|
|
331458
331470
|
});
|
|
331471
|
+
if (r.status === 409) {
|
|
331472
|
+
operator_src_logger.debug(`TFResult '${tfResultName}' already exists (409), updating.`);
|
|
331473
|
+
const existingUrl = `${kc.getCurrentCluster().server}/apis/firestartr.dev/v1/namespaces/${namespace}/tfresults/${tfResultName}`;
|
|
331474
|
+
const getResp = await fetch(existingUrl, { ...opts, method: 'GET' });
|
|
331475
|
+
if (!getResp.ok) {
|
|
331476
|
+
throw `TFResult: failed to fetch existing '${tfResultName}': ${getResp.statusText}`;
|
|
331477
|
+
}
|
|
331478
|
+
const existing = await getResp.json();
|
|
331479
|
+
existing.spec.result = result.toString();
|
|
331480
|
+
const updated = await writeManifest('tfresults', namespace, existing, `apis/firestartr.dev/v1/namespaces/${namespace}/tfresults/${tfResultName}`);
|
|
331481
|
+
await tryWriteTFResultStatus(namespace, tfResultName, updated.metadata.resourceVersion, exitCode, newRetryCount);
|
|
331482
|
+
updated.status = updated.status || {};
|
|
331483
|
+
updated.status.retryCount = newRetryCount;
|
|
331484
|
+
return updated;
|
|
331485
|
+
}
|
|
331459
331486
|
if (!r.ok) {
|
|
331460
331487
|
throw `TFResult: ${r.statusText}`;
|
|
331461
331488
|
}
|
|
@@ -332471,15 +332498,20 @@ async function syncer(enqueue) {
|
|
|
332471
332498
|
async function loop(enqueueIfNeeded, api) {
|
|
332472
332499
|
void loopKeeper(api);
|
|
332473
332500
|
while (1) {
|
|
332474
|
-
|
|
332475
|
-
|
|
332476
|
-
|
|
332477
|
-
const
|
|
332478
|
-
|
|
332479
|
-
|
|
332480
|
-
|
|
332501
|
+
try {
|
|
332502
|
+
await fWait();
|
|
332503
|
+
const needRevisionItems = Object.values(syncWatchers).filter((watcher) => watcher.needsRevision);
|
|
332504
|
+
for (const watcher of needRevisionItems) {
|
|
332505
|
+
const item = await getItemIfNeededSync(watcher);
|
|
332506
|
+
operator_src_logger.debug(`Item needs revision ${watcher.itemPath}`);
|
|
332507
|
+
if (item !== null) {
|
|
332508
|
+
enqueueIfNeeded(item);
|
|
332509
|
+
}
|
|
332510
|
+
watcher.needsRevision = false;
|
|
332481
332511
|
}
|
|
332482
|
-
|
|
332512
|
+
}
|
|
332513
|
+
catch (err) {
|
|
332514
|
+
operator_src_logger.error(`Error in sync loop: ${err}`);
|
|
332483
332515
|
}
|
|
332484
332516
|
}
|
|
332485
332517
|
}
|
|
@@ -332499,15 +332531,34 @@ async function loopKeeper(api) {
|
|
|
332499
332531
|
process.exit(1);
|
|
332500
332532
|
}
|
|
332501
332533
|
}
|
|
332502
|
-
async function getItemIfNeededSync(watcher) {
|
|
332503
|
-
const
|
|
332504
|
-
|
|
332505
|
-
|
|
332506
|
-
|
|
332507
|
-
|
|
332508
|
-
|
|
332534
|
+
async function getItemIfNeededSync(watcher, watchers) {
|
|
332535
|
+
const targetWatchers = watchers ?? syncWatchers;
|
|
332536
|
+
try {
|
|
332537
|
+
const item = await ctl_getItemByItemPath(watcher.itemPath);
|
|
332538
|
+
const isProvisioning = item.status?.conditions?.find((condition) => condition.type === 'PROVISIONING' && condition.status === 'True');
|
|
332539
|
+
if (isProvisioning)
|
|
332540
|
+
return null;
|
|
332541
|
+
const isDeleting = item.status?.conditions?.find((condition) => condition.type === 'DELETING' && condition.status === 'True');
|
|
332542
|
+
if (isDeleting)
|
|
332543
|
+
return null;
|
|
332544
|
+
return item;
|
|
332545
|
+
}
|
|
332546
|
+
catch (e) {
|
|
332547
|
+
if (e.message && e.message.includes('Error on getItemByItemPath')) {
|
|
332548
|
+
if (e.message.includes('Not Found')) {
|
|
332549
|
+
operator_src_logger.debug(`Item '${watcher.itemPath}' not found, removing from sync watchers.`);
|
|
332550
|
+
delete targetWatchers[watcher.itemPath];
|
|
332551
|
+
}
|
|
332552
|
+
else {
|
|
332553
|
+
operator_src_logger.warn(`Transient error fetching '${watcher.itemPath}', keeping sync watcher: ${e.message}`);
|
|
332554
|
+
}
|
|
332555
|
+
return null;
|
|
332556
|
+
}
|
|
332557
|
+
else {
|
|
332558
|
+
operator_src_logger.error(e);
|
|
332559
|
+
}
|
|
332509
332560
|
return null;
|
|
332510
|
-
|
|
332561
|
+
}
|
|
332511
332562
|
}
|
|
332512
332563
|
function fWait(segs = 1) {
|
|
332513
332564
|
return new Promise((ok) => {
|
|
@@ -332515,19 +332566,122 @@ function fWait(segs = 1) {
|
|
|
332515
332566
|
});
|
|
332516
332567
|
}
|
|
332517
332568
|
|
|
332569
|
+
;// CONCATENATED MODULE: ../operator/src/retry.debug.ts
|
|
332570
|
+
|
|
332571
|
+
|
|
332572
|
+
|
|
332573
|
+
|
|
332574
|
+
const RETRY_DEBUG_INTERVAL_MS = 60 * 1000;
|
|
332575
|
+
const loggedEvents = new Set();
|
|
332576
|
+
function writeEventIfNew(itemPath, counter, next, maxRetry = 5) {
|
|
332577
|
+
const key = `${itemPath}-retry-${counter}`;
|
|
332578
|
+
if (loggedEvents.has(key))
|
|
332579
|
+
return;
|
|
332580
|
+
loggedEvents.add(key);
|
|
332581
|
+
resolveRetryType(itemPath)
|
|
332582
|
+
.then((type) => {
|
|
332583
|
+
const nextStr = next ?? 'none';
|
|
332584
|
+
const line = `${itemPath} - ${type} - retry ${counter + 1}/${maxRetry} - next: ${nextStr}\n`;
|
|
332585
|
+
return new Promise((ok, ko) => {
|
|
332586
|
+
external_fs_.appendFile('/tmp/retries', line, (err) => {
|
|
332587
|
+
if (err)
|
|
332588
|
+
ko(`Error appending to /tmp/retries: ${err}`);
|
|
332589
|
+
else
|
|
332590
|
+
ok();
|
|
332591
|
+
});
|
|
332592
|
+
});
|
|
332593
|
+
})
|
|
332594
|
+
.catch(() => {
|
|
332595
|
+
operator_src_logger.warn(`Failed to resolve retry type for ${itemPath}`);
|
|
332596
|
+
});
|
|
332597
|
+
}
|
|
332598
|
+
function initRetryDebug(retryWatchers, maxRetry) {
|
|
332599
|
+
loggedEvents.clear();
|
|
332600
|
+
try {
|
|
332601
|
+
external_fs_.writeFileSync('/tmp/retries', '');
|
|
332602
|
+
}
|
|
332603
|
+
catch {
|
|
332604
|
+
operator_src_logger.warn('Failed to clear /tmp/retries');
|
|
332605
|
+
}
|
|
332606
|
+
let running = false;
|
|
332607
|
+
setInterval(() => {
|
|
332608
|
+
if (running)
|
|
332609
|
+
return;
|
|
332610
|
+
running = true;
|
|
332611
|
+
writeRetryDebug(retryWatchers, maxRetry)
|
|
332612
|
+
.then(() => {
|
|
332613
|
+
running = false;
|
|
332614
|
+
})
|
|
332615
|
+
.catch((err) => {
|
|
332616
|
+
operator_src_logger.error(`PANIC cannot evaluate the retry debug!!!: ${err}`);
|
|
332617
|
+
running = false;
|
|
332618
|
+
});
|
|
332619
|
+
}, RETRY_DEBUG_INTERVAL_MS);
|
|
332620
|
+
}
|
|
332621
|
+
async function writeRetryDebug(retryWatchers, maxRetry) {
|
|
332622
|
+
let output = '';
|
|
332623
|
+
for (const watcher of Object.values(retryWatchers)) {
|
|
332624
|
+
const type = await resolveRetryType(watcher.itemPath);
|
|
332625
|
+
const nextStr = watcher.retry
|
|
332626
|
+
? 'pending'
|
|
332627
|
+
: (watcher.nextRetryAt ?? 'unknown');
|
|
332628
|
+
output += `${watcher.itemPath} - ${type} - retry ${watcher.retryCounter + 1}/${maxRetry} - next: ${nextStr}\n`;
|
|
332629
|
+
}
|
|
332630
|
+
return new Promise((ok, ko) => {
|
|
332631
|
+
external_fs_.writeFile('/tmp/retries', output, (err) => {
|
|
332632
|
+
if (err)
|
|
332633
|
+
ko(`Error writing /tmp/retries: ${err}`);
|
|
332634
|
+
else
|
|
332635
|
+
ok();
|
|
332636
|
+
});
|
|
332637
|
+
});
|
|
332638
|
+
}
|
|
332639
|
+
async function resolveRetryType(itemPath) {
|
|
332640
|
+
try {
|
|
332641
|
+
const item = await ctl_getItemByItemPath(itemPath);
|
|
332642
|
+
const errorCondition = item.status?.conditions?.find((c) => c.type === 'ERROR' && c.status === 'True');
|
|
332643
|
+
return retryOpForReason(errorCondition?.reason) || 'RETRY';
|
|
332644
|
+
}
|
|
332645
|
+
catch {
|
|
332646
|
+
return 'RETRY';
|
|
332647
|
+
}
|
|
332648
|
+
}
|
|
332649
|
+
|
|
332518
332650
|
;// CONCATENATED MODULE: ../operator/src/retry.ts
|
|
332519
332651
|
|
|
332520
332652
|
|
|
332653
|
+
|
|
332521
332654
|
// Retries now use exponential backoff, starting at 5 minutes
|
|
332522
332655
|
// and doubling each time, up to the maximum number of retries
|
|
332523
|
-
// configured by
|
|
332524
|
-
|
|
332525
|
-
|
|
332656
|
+
// configured by OPERATOR_MAX_RETRY (getMaxRetry()).
|
|
332657
|
+
//
|
|
332658
|
+
// Both values can be overridden via environment variables for testing:
|
|
332659
|
+
// OPERATOR_NEXT_RETRY_MS — base delay in ms (default: 300000 = 5 min)
|
|
332660
|
+
// OPERATOR_MAX_RETRY — max retry attempts (default: 5)
|
|
332661
|
+
function getNextRetryMs() {
|
|
332662
|
+
const env = process.env.OPERATOR_NEXT_RETRY_MS;
|
|
332663
|
+
if (env) {
|
|
332664
|
+
const n = Number.parseInt(env, 10);
|
|
332665
|
+
if (Number.isFinite(n) && n > 0)
|
|
332666
|
+
return n;
|
|
332667
|
+
}
|
|
332668
|
+
return 1000 * 60 * 5;
|
|
332669
|
+
}
|
|
332670
|
+
function getMaxRetry() {
|
|
332671
|
+
const env = process.env.OPERATOR_MAX_RETRY;
|
|
332672
|
+
if (env) {
|
|
332673
|
+
const n = Number.parseInt(env, 10);
|
|
332674
|
+
if (Number.isFinite(n) && n > 0)
|
|
332675
|
+
return n;
|
|
332676
|
+
}
|
|
332677
|
+
return 5;
|
|
332678
|
+
}
|
|
332526
332679
|
function nextRetryMs(currCounter) {
|
|
332527
|
-
return
|
|
332680
|
+
return getNextRetryMs() * Math.pow(2, currCounter);
|
|
332528
332681
|
}
|
|
332529
332682
|
const retryWatchers = {};
|
|
332530
332683
|
async function initRetry(enqueue) {
|
|
332684
|
+
initRetryDebug(retryWatchers, getMaxRetry());
|
|
332531
332685
|
void retry_loop(enqueue);
|
|
332532
332686
|
return {
|
|
332533
332687
|
errorReconciling(itemPath) {
|
|
@@ -332551,23 +332705,29 @@ function retry(itemPath) {
|
|
|
332551
332705
|
retry: false,
|
|
332552
332706
|
retryCounter: 0,
|
|
332553
332707
|
nextRetry: null,
|
|
332708
|
+
nextRetryAt: null,
|
|
332554
332709
|
};
|
|
332555
332710
|
}
|
|
332556
332711
|
const currCounter = retryWatchers[itemPath].retryCounter;
|
|
332557
|
-
const
|
|
332558
|
-
|
|
332559
|
-
|
|
332712
|
+
const maxRetry = getMaxRetry();
|
|
332713
|
+
const delayMs = nextRetryMs(currCounter);
|
|
332714
|
+
if (currCounter >= maxRetry) {
|
|
332715
|
+
writeEventIfNew(itemPath, currCounter, null, maxRetry);
|
|
332716
|
+
operator_src_logger.debug(`Failed to process item '${itemPath}'. Retry limit (${maxRetry}) reached. No further retries will be attempted.`);
|
|
332560
332717
|
removeFromRetry(itemPath);
|
|
332561
332718
|
return;
|
|
332562
332719
|
}
|
|
332563
|
-
operator_src_logger.debug(`Failed to process item '${itemPath}'. Retrying in '${delayMs / 1000 / 60}' minutes. Remaining retries: '${
|
|
332720
|
+
operator_src_logger.debug(`Failed to process item '${itemPath}'. Retrying in '${delayMs / 1000 / 60}' minutes. Remaining retries: '${maxRetry - currCounter - 1}'.`);
|
|
332564
332721
|
retryWatchers[itemPath].retry = false;
|
|
332565
332722
|
if (retryWatchers[itemPath].nextRetry) {
|
|
332566
332723
|
clearTimeout(retryWatchers[itemPath].nextRetry);
|
|
332567
332724
|
}
|
|
332725
|
+
retryWatchers[itemPath].nextRetryAt = new Date(Date.now() + delayMs).toISOString();
|
|
332568
332726
|
retryWatchers[itemPath].nextRetry = setTimeout(() => {
|
|
332569
|
-
if (itemPath in retryWatchers)
|
|
332727
|
+
if (itemPath in retryWatchers) {
|
|
332570
332728
|
retryWatchers[itemPath].retry = true;
|
|
332729
|
+
retryWatchers[itemPath].nextRetryAt = null;
|
|
332730
|
+
}
|
|
332571
332731
|
}, delayMs);
|
|
332572
332732
|
}
|
|
332573
332733
|
function removeFromRetry(itemPath) {
|
|
@@ -332579,7 +332739,8 @@ function removeFromRetry(itemPath) {
|
|
|
332579
332739
|
async function retry_loop(enqueueIfNeeded) {
|
|
332580
332740
|
while (1) {
|
|
332581
332741
|
await retry_fWait();
|
|
332582
|
-
const
|
|
332742
|
+
const maxRetry = getMaxRetry();
|
|
332743
|
+
const needRetryWatchItem = Object.values(retryWatchers).filter((watcher) => watcher.retryCounter < maxRetry && watcher.retry);
|
|
332583
332744
|
for (const watcher of needRetryWatchItem) {
|
|
332584
332745
|
const item = await getItemIfNeededRetry(watcher);
|
|
332585
332746
|
if (item !== null) {
|
|
@@ -332606,7 +332767,7 @@ async function getItemIfNeededRetry(watcher) {
|
|
|
332606
332767
|
return null;
|
|
332607
332768
|
}
|
|
332608
332769
|
else {
|
|
332609
|
-
|
|
332770
|
+
operator_src_logger.warn(`Unexpected error in retry check for '${watcher.itemPath}': ${e}`);
|
|
332610
332771
|
}
|
|
332611
332772
|
return null;
|
|
332612
332773
|
}
|
|
@@ -332891,7 +333052,7 @@ function enqueue(pluralKind, workItem, queue, compute, syncCtl, retryCtl) {
|
|
|
332891
333052
|
const resolvedExitCode = exitCode !== undefined ? exitCode : /\berror\b/i.test(output) ? 1 : 0;
|
|
332892
333053
|
const retryCount = result?.status?.retryCount ?? 0;
|
|
332893
333054
|
const backoffCounter = Math.max(retryCount - 1, 0);
|
|
332894
|
-
const nextRetryTime = resolvedExitCode === 0 || backoffCounter >=
|
|
333055
|
+
const nextRetryTime = resolvedExitCode === 0 || backoffCounter >= getMaxRetry()
|
|
332895
333056
|
? undefined
|
|
332896
333057
|
: new Date(Date.now() + nextRetryMs(backoffCounter)).toISOString();
|
|
332897
333058
|
await updateRetryStatusInCR(pluralKind, item.metadata.namespace, item.metadata.name, retryCount, nextRetryTime);
|
|
@@ -332906,6 +333067,7 @@ function enqueue(pluralKind, workItem, queue, compute, syncCtl, retryCtl) {
|
|
|
332906
333067
|
itemPath: () => informer_itemPath(pluralKind, workItem.item),
|
|
332907
333068
|
error: () => retryCtl.errorReconciling(informer_itemPath(pluralKind, workItem.item)),
|
|
332908
333069
|
success: () => retryCtl.successReconciling(informer_itemPath(pluralKind, workItem.item)),
|
|
333070
|
+
removeFromRetry: () => retryCtl.successReconciling(informer_itemPath(pluralKind, workItem.item)),
|
|
332909
333071
|
recommendedTimeout: () => {
|
|
332910
333072
|
const customTimeoutAnnotation = catalog_common/* default.generic.getFirestartrAnnotation */.Z.generic.getFirestartrAnnotation('test-custom-timeout');
|
|
332911
333073
|
let customTimeout = null;
|
|
@@ -332925,7 +333087,8 @@ function enqueue(pluralKind, workItem, queue, compute, syncCtl, retryCtl) {
|
|
|
332925
333087
|
}
|
|
332926
333088
|
// only for delete operations
|
|
332927
333089
|
if (operation !== OperationType.MARKED_TO_DELETION) {
|
|
332928
|
-
if (operation === OperationType.RETRY
|
|
333090
|
+
if (operation === OperationType.RETRY ||
|
|
333091
|
+
operation === OperationType.RETRY_SYNC) {
|
|
332929
333092
|
// is the retry a delete operation?
|
|
332930
333093
|
if (!('deletionTimestamp' in workItem.item.metadata)) {
|
|
332931
333094
|
return false;
|
|
@@ -332961,13 +333124,15 @@ function enqueue(pluralKind, workItem, queue, compute, syncCtl, retryCtl) {
|
|
|
332961
333124
|
operation === OperationType.UPDATED ||
|
|
332962
333125
|
operation === OperationType.SYNC ||
|
|
332963
333126
|
operation === OperationType.CREATED ||
|
|
332964
|
-
operation === OperationType.RETRY
|
|
333127
|
+
operation === OperationType.RETRY ||
|
|
333128
|
+
operation === OperationType.RETRY_SYNC;
|
|
332965
333129
|
await setSyncStatus(workItem.handler.itemPath(), operation, 'False', 'Sync process started');
|
|
332966
333130
|
for await (const transition of compute(item, operation, handler)) {
|
|
332967
333131
|
yield transition;
|
|
332968
333132
|
}
|
|
332969
333133
|
if (needsUpdateSyncConditions) {
|
|
332970
|
-
if (operation === OperationType.SYNC
|
|
333134
|
+
if (operation === OperationType.SYNC ||
|
|
333135
|
+
operation === OperationType.RETRY_SYNC) {
|
|
332971
333136
|
// Fetch the CR once and reuse for both hasSyncFailed check and ERROR guard
|
|
332972
333137
|
const currentItem = await ctl_getItemByItemPath(workItem.handler.itemPath());
|
|
332973
333138
|
const syncStatus = await getSyncStatus(workItem.handler.itemPath(), currentItem);
|
|
@@ -332982,7 +333147,10 @@ function enqueue(pluralKind, workItem, queue, compute, syncCtl, retryCtl) {
|
|
|
332982
333147
|
return;
|
|
332983
333148
|
}
|
|
332984
333149
|
}
|
|
332985
|
-
await setSyncStatus(workItem.handler.itemPath(), operation, operation === OperationType.SYNC
|
|
333150
|
+
await setSyncStatus(workItem.handler.itemPath(), operation, operation === OperationType.SYNC ||
|
|
333151
|
+
operation === OperationType.RETRY_SYNC
|
|
333152
|
+
? 'True'
|
|
333153
|
+
: 'False', 'Sync process finished');
|
|
332986
333154
|
void syncCtl.updateItem(informer_itemPath(pluralKind, item));
|
|
332987
333155
|
}
|
|
332988
333156
|
else {
|
|
@@ -333044,18 +333212,21 @@ async function inform(pluralKind, item, op, lastWorkItem = null) {
|
|
|
333044
333212
|
return workItem;
|
|
333045
333213
|
}
|
|
333046
333214
|
return null;
|
|
333047
|
-
case 'onRetry':
|
|
333215
|
+
case 'onRetry': {
|
|
333048
333216
|
if (workItem !== null && workItem.workStatus !== WorkStatus.FINISHED) {
|
|
333049
333217
|
return null;
|
|
333050
333218
|
}
|
|
333219
|
+
const errorCondition = item.status?.conditions?.find((c) => c.type === 'ERROR' && c.status === 'True');
|
|
333220
|
+
const retryOp = retryOpForReason(errorCondition?.reason);
|
|
333051
333221
|
workItem = {
|
|
333052
|
-
operation:
|
|
333222
|
+
operation: retryOp,
|
|
333053
333223
|
item,
|
|
333054
333224
|
workStatus: WorkStatus.PENDING,
|
|
333055
333225
|
onDelete: function () { },
|
|
333056
333226
|
upsertTime: Date.now(),
|
|
333057
333227
|
};
|
|
333058
333228
|
return workItem;
|
|
333229
|
+
}
|
|
333059
333230
|
case 'onAdd':
|
|
333060
333231
|
needed = await needsProvisioningOnCreateOrUpdate(item);
|
|
333061
333232
|
if (needed.needs) {
|
|
@@ -333637,7 +333808,8 @@ class DeferredSchedulingBookkeeper {
|
|
|
333637
333808
|
const op = item.operation;
|
|
333638
333809
|
if (op === OperationType.MARKED_TO_DELETION)
|
|
333639
333810
|
return true;
|
|
333640
|
-
if (op === OperationType.RETRY
|
|
333811
|
+
if ((op === OperationType.RETRY || op === OperationType.RETRY_SYNC) &&
|
|
333812
|
+
item.item?.metadata?.deletionTimestamp)
|
|
333641
333813
|
return true;
|
|
333642
333814
|
return false;
|
|
333643
333815
|
}
|
|
@@ -333913,6 +334085,7 @@ async function writeDiagnosticSnapshot(queue, maxSlots) {
|
|
|
333913
334085
|
const envTfmMirrorRefreshInterval = process.env.TFM_MIRROR_REFRESH_INTERVAL || '900';
|
|
333914
334086
|
const envBackendProvider = process.env.BACKEND_PROVIDER_NAME || 'kubernetes-provider';
|
|
333915
334087
|
const envGithubAppId = process.env.GITHUB_APP_ID || '';
|
|
334088
|
+
const envTfmSkipGitConfig = process.env.TFM_SKIP_GIT_CONFIG || 'false';
|
|
333916
334089
|
// Build YAML output
|
|
333917
334090
|
let output = '';
|
|
333918
334091
|
output += `timestamp: "${now}"\n`;
|
|
@@ -333925,6 +334098,7 @@ async function writeDiagnosticSnapshot(queue, maxSlots) {
|
|
|
333925
334098
|
output += ` TFM_MIRROR_REFRESH_INTERVAL: ${envTfmMirrorRefreshInterval}\n`;
|
|
333926
334099
|
output += ` BACKEND_PROVIDER_NAME: ${envBackendProvider}\n`;
|
|
333927
334100
|
output += ` GITHUB_APP_ID: ${envGithubAppId}\n`;
|
|
334101
|
+
output += ` TFM_SKIP_GIT_CONFIG: ${envTfmSkipGitConfig}\n`;
|
|
333928
334102
|
output += 'queue:\n';
|
|
333929
334103
|
output += ` total: ${queue.length}\n`;
|
|
333930
334104
|
output += ` pending: ${pending}\n`;
|
|
@@ -334683,6 +334857,7 @@ const WEIGHTS = {
|
|
|
334683
334857
|
UPDATED: 10,
|
|
334684
334858
|
CREATED: 9,
|
|
334685
334859
|
RETRY: 8,
|
|
334860
|
+
RETRY_SYNC: 8,
|
|
334686
334861
|
MARKED_TO_DELETION: 6,
|
|
334687
334862
|
SYNC: 1,
|
|
334688
334863
|
NOTHING: 0,
|
|
@@ -335689,16 +335864,26 @@ async function gitFetchPrune(mirrorPath) {
|
|
|
335689
335864
|
});
|
|
335690
335865
|
}
|
|
335691
335866
|
/**
|
|
335692
|
-
* Single package-wide GitHub authentication config writer for repo mirrors and remote workflows.
|
|
335693
335867
|
* Writes the required url rewriting stanza to /home/node/.gitconfig based on the current org's GitHub App token.
|
|
335694
335868
|
* This is the ONLY allowed implementation of project git-auth per package specs.
|
|
335869
|
+
*
|
|
335870
|
+
* When TFM_SKIP_GIT_CONFIG=true is set, the function removes any existing
|
|
335871
|
+
* /home/node/.gitconfig and returns early without writing a new one. This is
|
|
335872
|
+
* used in dev/test environments where no GitHub App credentials are available
|
|
335873
|
+
* (e.g. local dev, smoke tests using prefapp/tfm mirrors).
|
|
335695
335874
|
*/
|
|
335696
335875
|
async function configGit() {
|
|
335876
|
+
const gitconfigPath = '/home/node/.gitconfig';
|
|
335877
|
+
if (process.env.TFM_SKIP_GIT_CONFIG === 'true') {
|
|
335878
|
+
if (external_fs_.existsSync(gitconfigPath)) {
|
|
335879
|
+
external_fs_.rmSync(gitconfigPath);
|
|
335880
|
+
}
|
|
335881
|
+
return;
|
|
335882
|
+
}
|
|
335697
335883
|
// Import github dynamically to avoid Jest ESM issues when not specifically running this function
|
|
335698
335884
|
// (see CONSTITUTION and RULES: must not change test machinery)
|
|
335699
335885
|
const githubModule = await Promise.resolve(/* import() */).then(__nccwpck_require__.bind(__nccwpck_require__, 99029));
|
|
335700
335886
|
const github = githubModule.default || githubModule;
|
|
335701
|
-
const gitconfigPath = '/home/node/.gitconfig';
|
|
335702
335887
|
if (external_fs_.existsSync(gitconfigPath)) {
|
|
335703
335888
|
external_fs_.rmSync(gitconfigPath);
|
|
335704
335889
|
}
|
|
@@ -337221,8 +337406,8 @@ function policyAllowsOp(policy, op, item) {
|
|
|
337221
337406
|
msg = `A RETRY operation is not allowed on a resource with a deletionTimestamp. It means
|
|
337222
337407
|
that the resource is being deleted and it is not possible to retry the operation with policy: ${policy}.
|
|
337223
337408
|
|
|
337224
|
-
To fix this issue, you must first delete the "
|
|
337225
|
-
it will be automatically deleted by
|
|
337409
|
+
To fix this issue, you must first delete the "firestartr.dev/finalizer" from finalizers array in the resource manifest,
|
|
337410
|
+
it will be automatically deleted by Kubernetes. Terraform will not execute any operation on the resource.
|
|
337226
337411
|
`;
|
|
337227
337412
|
return { allowed: false, msg };
|
|
337228
337413
|
}
|
|
@@ -337230,6 +337415,19 @@ it will be automatically deleted by kubernetes. Terraform will not execute any o
|
|
|
337230
337415
|
return { allowed: true, msg };
|
|
337231
337416
|
}
|
|
337232
337417
|
}
|
|
337418
|
+
if (op === OperationType.RETRY_SYNC.toString() &&
|
|
337419
|
+
foundPolicy?.allowedOps.includes(OperationType.SYNC.toString())) {
|
|
337420
|
+
if ('deletionTimestamp' in item.metadata && 'full-control' !== policy) {
|
|
337421
|
+
msg = `A RETRY_SYNC operation is not allowed on a resource with a deletionTimestamp. It means
|
|
337422
|
+
that the resource is being deleted and it is not possible to retry the operation with policy: ${policy}.
|
|
337423
|
+
|
|
337424
|
+
To fix this issue, you must first delete the "firestartr.dev/finalizer" from finalizers array in the resource manifest,
|
|
337425
|
+
it will be automatically deleted by Kubernetes. Terraform will not execute any operation on the resource.
|
|
337426
|
+
`;
|
|
337427
|
+
return { allowed: false, msg };
|
|
337428
|
+
}
|
|
337429
|
+
return { allowed: true, msg };
|
|
337430
|
+
}
|
|
337233
337431
|
if (!foundPolicy) {
|
|
337234
337432
|
msg = `Policy ${policy} not found`;
|
|
337235
337433
|
return { allowed: false, msg };
|
|
@@ -337432,6 +337630,7 @@ function processOperation(item, op, handler) {
|
|
|
337432
337630
|
case OperationType.MARKED_TO_DELETION:
|
|
337433
337631
|
return process_operation_markedToDeletion(item, op, handler);
|
|
337434
337632
|
case OperationType.RETRY:
|
|
337633
|
+
case OperationType.RETRY_SYNC:
|
|
337435
337634
|
return process_operation_retry(item, op, handler);
|
|
337436
337635
|
case OperationType.NOTHING:
|
|
337437
337636
|
return process_operation_nothing(item, op, handler);
|
|
@@ -337449,11 +337648,26 @@ async function* process_operation_observe(item, op, handler) {
|
|
|
337449
337648
|
yield transition;
|
|
337450
337649
|
}
|
|
337451
337650
|
}
|
|
337452
|
-
async function* doPlanJSONFormat(item, op, handler, setResult = function (_r) { }) {
|
|
337651
|
+
async function* doPlanJSONFormat(item, op, handler, setResult = function (_r) { }, emitSyncErrorCondition = true) {
|
|
337453
337652
|
let error = false;
|
|
337454
337653
|
let deps;
|
|
337455
337654
|
let terraformExecutionStarted = false;
|
|
337456
337655
|
const sessionId = generateSessionId();
|
|
337656
|
+
if (op !== OperationType.RETRY && op !== OperationType.RETRY_SYNC) {
|
|
337657
|
+
try {
|
|
337658
|
+
await handler.writeTerraformOutputInTfResult(item, '', 0);
|
|
337659
|
+
}
|
|
337660
|
+
catch (e) {
|
|
337661
|
+
operator_src_logger.warn(`Failed to clear Terraform output: ${e}`);
|
|
337662
|
+
}
|
|
337663
|
+
try {
|
|
337664
|
+
if (handler.removeFromRetry)
|
|
337665
|
+
handler.removeFromRetry();
|
|
337666
|
+
}
|
|
337667
|
+
catch (e) {
|
|
337668
|
+
operator_src_logger.warn(`Failed to clear retry watcher: ${e}`);
|
|
337669
|
+
}
|
|
337670
|
+
}
|
|
337457
337671
|
try {
|
|
337458
337672
|
yield {
|
|
337459
337673
|
item,
|
|
@@ -337582,17 +337796,22 @@ async function* doPlanJSONFormat(item, op, handler, setResult = function (_r) {
|
|
|
337582
337796
|
}
|
|
337583
337797
|
}
|
|
337584
337798
|
if (error) {
|
|
337585
|
-
if (op === OperationType.SYNC) {
|
|
337586
|
-
|
|
337587
|
-
// it would be problematic because the RETRY op kicks in
|
|
337588
|
-
if (error) {
|
|
337799
|
+
if (op === OperationType.SYNC || op === OperationType.RETRY_SYNC) {
|
|
337800
|
+
if (emitSyncErrorCondition) {
|
|
337589
337801
|
yield {
|
|
337590
337802
|
item,
|
|
337591
337803
|
reason: op,
|
|
337592
|
-
type: '
|
|
337804
|
+
type: 'ERROR',
|
|
337593
337805
|
status: 'True',
|
|
337594
337806
|
message: SYNC_DEFAULT_ERROR_MESSAGE,
|
|
337595
337807
|
};
|
|
337808
|
+
yield {
|
|
337809
|
+
item,
|
|
337810
|
+
reason: op,
|
|
337811
|
+
type: 'SYNCHRONIZED',
|
|
337812
|
+
status: 'False',
|
|
337813
|
+
message: SYNC_DEFAULT_ERROR_MESSAGE,
|
|
337814
|
+
};
|
|
337596
337815
|
yield {
|
|
337597
337816
|
item,
|
|
337598
337817
|
reason: op,
|
|
@@ -337614,6 +337833,29 @@ async function* doPlanJSONFormat(item, op, handler, setResult = function (_r) {
|
|
|
337614
337833
|
status: 'False',
|
|
337615
337834
|
message: 'doPlanJSONFormat',
|
|
337616
337835
|
};
|
|
337836
|
+
}
|
|
337837
|
+
else {
|
|
337838
|
+
yield {
|
|
337839
|
+
item,
|
|
337840
|
+
reason: op,
|
|
337841
|
+
type: 'SYNCHRONIZED',
|
|
337842
|
+
status: 'True',
|
|
337843
|
+
message: SYNC_DEFAULT_ERROR_MESSAGE,
|
|
337844
|
+
};
|
|
337845
|
+
yield {
|
|
337846
|
+
item,
|
|
337847
|
+
reason: op,
|
|
337848
|
+
type: 'PROVISIONED',
|
|
337849
|
+
status: 'True',
|
|
337850
|
+
message: 'doPlanJSONFormat',
|
|
337851
|
+
};
|
|
337852
|
+
yield {
|
|
337853
|
+
item,
|
|
337854
|
+
reason: op,
|
|
337855
|
+
type: 'PLANNING',
|
|
337856
|
+
status: 'False',
|
|
337857
|
+
message: 'doPlanJSONFormat',
|
|
337858
|
+
};
|
|
337617
337859
|
yield {
|
|
337618
337860
|
item,
|
|
337619
337861
|
reason: op,
|
|
@@ -337656,9 +337898,16 @@ async function* doPlanJSONFormat(item, op, handler, setResult = function (_r) {
|
|
|
337656
337898
|
}
|
|
337657
337899
|
}
|
|
337658
337900
|
else {
|
|
337659
|
-
|
|
337901
|
+
handler.success();
|
|
337902
|
+
if (op === OperationType.SYNC || op === OperationType.RETRY_SYNC) {
|
|
337660
337903
|
setResult('SYNC_SUCCESS');
|
|
337661
337904
|
}
|
|
337905
|
+
try {
|
|
337906
|
+
await handler.writeTerraformOutputInTfResult(item, '', 0);
|
|
337907
|
+
}
|
|
337908
|
+
catch (e) {
|
|
337909
|
+
operator_src_logger.warn(`Failed to clear Terraform output: ${e}`);
|
|
337910
|
+
}
|
|
337662
337911
|
}
|
|
337663
337912
|
}
|
|
337664
337913
|
}
|
|
@@ -337688,6 +337937,13 @@ async function* process_operation_retry(item, op, handler) {
|
|
|
337688
337937
|
yield transition;
|
|
337689
337938
|
}
|
|
337690
337939
|
}
|
|
337940
|
+
else if (op === OperationType.RETRY_SYNC) {
|
|
337941
|
+
const policy = getPolicy(item, 'firestartr.dev/policy');
|
|
337942
|
+
const syncPolicy = getPolicy(item, 'firestartr.dev/sync-policy');
|
|
337943
|
+
for await (const transition of process_operation_sync(item, OperationType.RETRY_SYNC, handler, syncPolicy, policy)) {
|
|
337944
|
+
yield transition;
|
|
337945
|
+
}
|
|
337946
|
+
}
|
|
337691
337947
|
else {
|
|
337692
337948
|
for await (const transition of doApply(item, op, handler)) {
|
|
337693
337949
|
yield transition;
|
|
@@ -337704,7 +337960,7 @@ async function* process_operation_sync(item, op, handler, syncPolicy, generalPol
|
|
|
337704
337960
|
let doResult = '';
|
|
337705
337961
|
if (!syncPolicy) {
|
|
337706
337962
|
operator_src_logger.debug(`The Terraform processor is only observing item '${item.kind}/${item.metadata.name}' because no sync policy was found for operation '${op}'.`);
|
|
337707
|
-
yield* doPlanJSONFormat(item, op, handler);
|
|
337963
|
+
yield* doPlanJSONFormat(item, op, handler, undefined, false);
|
|
337708
337964
|
return;
|
|
337709
337965
|
}
|
|
337710
337966
|
else if (!catalog_common/* default.policies.policiesAreCompatible */.Z.policies.policiesAreCompatible(syncPolicy, generalPolicy)) {
|
|
@@ -337749,6 +338005,9 @@ async function* process_operation_markedToDeletion(item, op, handler) {
|
|
|
337749
338005
|
let terraformExecutionStarted = false;
|
|
337750
338006
|
const sessionId = generateSessionId();
|
|
337751
338007
|
try {
|
|
338008
|
+
if (op === OperationType.MARKED_TO_DELETION) {
|
|
338009
|
+
await handler.writeTerraformOutputInTfResult(item, '', 0);
|
|
338010
|
+
}
|
|
337752
338011
|
const type = 'DELETING';
|
|
337753
338012
|
yield {
|
|
337754
338013
|
item,
|
|
@@ -337898,6 +338157,21 @@ async function* doApply(item, op, handler) {
|
|
|
337898
338157
|
let deps;
|
|
337899
338158
|
let terraformExecutionStarted = false;
|
|
337900
338159
|
const sessionId = generateSessionId();
|
|
338160
|
+
if (op !== OperationType.RETRY && op !== OperationType.RETRY_SYNC) {
|
|
338161
|
+
try {
|
|
338162
|
+
await handler.writeTerraformOutputInTfResult(item, '', 0);
|
|
338163
|
+
}
|
|
338164
|
+
catch (e) {
|
|
338165
|
+
operator_src_logger.warn(`Failed to clear Terraform output: ${e}`);
|
|
338166
|
+
}
|
|
338167
|
+
try {
|
|
338168
|
+
if (handler.removeFromRetry)
|
|
338169
|
+
handler.removeFromRetry();
|
|
338170
|
+
}
|
|
338171
|
+
catch (e) {
|
|
338172
|
+
operator_src_logger.warn(`Failed to clear retry watcher: ${e}`);
|
|
338173
|
+
}
|
|
338174
|
+
}
|
|
337901
338175
|
try {
|
|
337902
338176
|
yield {
|
|
337903
338177
|
item,
|
|
@@ -342152,6 +342426,7 @@ function process_operation_processOperation(item, op, handler) {
|
|
|
342152
342426
|
case OperationType.MARKED_TO_DELETION:
|
|
342153
342427
|
return gh_process_operation_markedToDeletion(item, op, handler);
|
|
342154
342428
|
case OperationType.RETRY:
|
|
342429
|
+
case OperationType.RETRY_SYNC:
|
|
342155
342430
|
return gh_process_operation_retry(item, op, handler);
|
|
342156
342431
|
case OperationType.NOTHING:
|
|
342157
342432
|
return gh_process_operation_nothing(item, op, handler);
|
|
@@ -342188,6 +342463,11 @@ async function* gh_process_operation_retry(item, op, handler) {
|
|
|
342188
342463
|
yield transition;
|
|
342189
342464
|
}
|
|
342190
342465
|
}
|
|
342466
|
+
else if (op === OperationType.RETRY_SYNC) {
|
|
342467
|
+
for await (const transition of gh_process_operation_sync(item, OperationType.RETRY_SYNC, handler)) {
|
|
342468
|
+
yield transition;
|
|
342469
|
+
}
|
|
342470
|
+
}
|
|
342191
342471
|
else {
|
|
342192
342472
|
for await (const transition of process_operation_doApply(item, op, handler)) {
|
|
342193
342473
|
yield transition;
|
|
@@ -342340,6 +342620,14 @@ async function* process_operation_doApply(item, op, handler) {
|
|
|
342340
342620
|
let checkRunCtl;
|
|
342341
342621
|
let checkRunTFCtl;
|
|
342342
342622
|
let error = false;
|
|
342623
|
+
if (op !== OperationType.RETRY && op !== OperationType.RETRY_SYNC) {
|
|
342624
|
+
try {
|
|
342625
|
+
await handler.writeTerraformOutputInTfResult(item, '', 0);
|
|
342626
|
+
}
|
|
342627
|
+
catch (e) {
|
|
342628
|
+
operator_src_logger.warn(`Failed to reset retry count: ${e instanceof Error ? e.stack || e.message : JSON.stringify(e)}`);
|
|
342629
|
+
}
|
|
342630
|
+
}
|
|
342343
342631
|
try {
|
|
342344
342632
|
yield {
|
|
342345
342633
|
item,
|
|
@@ -342373,6 +342661,7 @@ async function* process_operation_doApply(item, op, handler) {
|
|
|
342373
342661
|
if (op === OperationType.UPDATED ||
|
|
342374
342662
|
op === OperationType.RENAMED ||
|
|
342375
342663
|
op === OperationType.RETRY ||
|
|
342664
|
+
op === OperationType.RETRY_SYNC ||
|
|
342376
342665
|
op === OperationType.SYNC) {
|
|
342377
342666
|
opts['update'] = true;
|
|
342378
342667
|
}
|
|
@@ -521630,7 +521919,7 @@ const crsStatusSubcommand = {
|
|
|
521630
521919
|
};
|
|
521631
521920
|
|
|
521632
521921
|
;// CONCATENATED MODULE: ./package.json
|
|
521633
|
-
const package_namespaceObject = JSON.parse('{"i8":"2.8.0-snapshot-variant-cloning-
|
|
521922
|
+
const package_namespaceObject = JSON.parse('{"i8":"2.8.0-snapshot-variant-cloning-2"}');
|
|
521634
521923
|
;// CONCATENATED MODULE: ../../package.json
|
|
521635
521924
|
const package_namespaceObject_1 = {"i8":"2.7.1"};
|
|
521636
521925
|
;// CONCATENATED MODULE: ./src/subcommands/index.ts
|
|
@@ -1238,10 +1238,6 @@ declare const schemas: {
|
|
|
1238
1238
|
description: string;
|
|
1239
1239
|
type: string;
|
|
1240
1240
|
properties: {
|
|
1241
|
-
name: {
|
|
1242
|
-
type: string;
|
|
1243
|
-
description: string;
|
|
1244
|
-
};
|
|
1245
1241
|
values: {
|
|
1246
1242
|
type: string;
|
|
1247
1243
|
additionalProperties: boolean;
|
|
@@ -1320,6 +1316,7 @@ declare const schemas: {
|
|
|
1320
1316
|
properties: {
|
|
1321
1317
|
name: {
|
|
1322
1318
|
type: string;
|
|
1319
|
+
maxLength: number;
|
|
1323
1320
|
description: string;
|
|
1324
1321
|
};
|
|
1325
1322
|
overrides: {
|
|
@@ -143,10 +143,6 @@ export declare const TerraformSchemas: {
|
|
|
143
143
|
description: string;
|
|
144
144
|
type: string;
|
|
145
145
|
properties: {
|
|
146
|
-
name: {
|
|
147
|
-
type: string;
|
|
148
|
-
description: string;
|
|
149
|
-
};
|
|
150
146
|
values: {
|
|
151
147
|
type: string;
|
|
152
148
|
additionalProperties: boolean;
|
|
@@ -225,6 +221,7 @@ export declare const TerraformSchemas: {
|
|
|
225
221
|
properties: {
|
|
226
222
|
name: {
|
|
227
223
|
type: string;
|
|
224
|
+
maxLength: number;
|
|
228
225
|
description: string;
|
|
229
226
|
};
|
|
230
227
|
overrides: {
|
|
@@ -143,10 +143,6 @@ declare const _default: {
|
|
|
143
143
|
description: string;
|
|
144
144
|
type: string;
|
|
145
145
|
properties: {
|
|
146
|
-
name: {
|
|
147
|
-
type: string;
|
|
148
|
-
description: string;
|
|
149
|
-
};
|
|
150
146
|
values: {
|
|
151
147
|
type: string;
|
|
152
148
|
additionalProperties: boolean;
|
|
@@ -225,6 +221,7 @@ declare const _default: {
|
|
|
225
221
|
properties: {
|
|
226
222
|
name: {
|
|
227
223
|
type: string;
|
|
224
|
+
maxLength: number;
|
|
228
225
|
description: string;
|
|
229
226
|
};
|
|
230
227
|
overrides: {
|
|
@@ -22,8 +22,10 @@ export declare enum OperationType {
|
|
|
22
22
|
SYNC = "SYNC",
|
|
23
23
|
MARKED_TO_DELETION = "MARKED_TO_DELETION",
|
|
24
24
|
NOTHING = "NOTHING",
|
|
25
|
-
RETRY = "RETRY"
|
|
25
|
+
RETRY = "RETRY",
|
|
26
|
+
RETRY_SYNC = "RETRY_SYNC"
|
|
26
27
|
}
|
|
28
|
+
export declare function retryOpForReason(reason: string | undefined): OperationType;
|
|
27
29
|
export declare enum WorkStatus {
|
|
28
30
|
PENDING = "PENDING",
|
|
29
31
|
PROCESSING = "PROCESSING",
|
|
@@ -65,6 +67,7 @@ export type WorkItemHandler = {
|
|
|
65
67
|
itemPath: ItemPathFn;
|
|
66
68
|
error: ErrorFn;
|
|
67
69
|
success: SuccessFn;
|
|
70
|
+
removeFromRetry?: () => void;
|
|
68
71
|
isBlocked?: boolean;
|
|
69
72
|
isPicked?: boolean;
|
|
70
73
|
needsBlocking?: (item: any, operation: OperationType) => boolean;
|
|
@@ -6,3 +6,17 @@ export declare function processOperation(item: any, op: OperationType, handler:
|
|
|
6
6
|
status: string;
|
|
7
7
|
message: string;
|
|
8
8
|
}, void, unknown>;
|
|
9
|
+
export declare function retry(item: any, op: OperationType, handler: any): AsyncGenerator<{
|
|
10
|
+
item: any;
|
|
11
|
+
reason: OperationType;
|
|
12
|
+
type: string;
|
|
13
|
+
status: string;
|
|
14
|
+
message: string;
|
|
15
|
+
}, void, unknown>;
|
|
16
|
+
export declare function sync(item: any, op: OperationType, handler: any): AsyncGenerator<{
|
|
17
|
+
item: any;
|
|
18
|
+
reason: OperationType;
|
|
19
|
+
type: string;
|
|
20
|
+
status: string;
|
|
21
|
+
message: string;
|
|
22
|
+
}, void, unknown>;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
export declare
|
|
2
|
-
export declare const MAXRETRY = 5;
|
|
1
|
+
export declare function getMaxRetry(): number;
|
|
3
2
|
export declare function nextRetryMs(currCounter: number): number;
|
|
4
3
|
export declare function initRetry(enqueue: Function): Promise<{
|
|
5
4
|
errorReconciling(itemPath: string): void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type RetryWatcher = {
|
|
2
|
+
itemPath: string;
|
|
3
|
+
retryCounter: number;
|
|
4
|
+
retry: boolean;
|
|
5
|
+
nextRetryAt: string | null;
|
|
6
|
+
};
|
|
7
|
+
export declare function writeEventIfNew(itemPath: string, counter: number, next: string | null, maxRetry?: number): void;
|
|
8
|
+
export declare function initRetryDebug(retryWatchers: {
|
|
9
|
+
[key: string]: RetryWatcher;
|
|
10
|
+
}, maxRetry: number): void;
|
|
11
|
+
export {};
|
|
@@ -8,3 +8,6 @@ export declare function syncer(enqueue: Function): Promise<{
|
|
|
8
8
|
deleteItem(itemPath: string): void;
|
|
9
9
|
}>;
|
|
10
10
|
export declare function loop(enqueueIfNeeded: Function, api: any): Promise<void>;
|
|
11
|
+
export declare function getItemIfNeededSync(watcher: any, watchers?: {
|
|
12
|
+
[key: string]: SyncWatcher;
|
|
13
|
+
}): Promise<any>;
|
|
@@ -7,6 +7,27 @@ export declare function processOperation(item: any, op: OperationType, handler:
|
|
|
7
7
|
status: string;
|
|
8
8
|
message: any;
|
|
9
9
|
}, void, unknown>;
|
|
10
|
+
export declare function doPlanJSONFormat(item: any, op: OperationType, handler: any, setResult?: (_r: string) => void, emitSyncErrorCondition?: boolean): AsyncGenerator<{
|
|
11
|
+
item: any;
|
|
12
|
+
reason: OperationType;
|
|
13
|
+
type: string;
|
|
14
|
+
status: string;
|
|
15
|
+
message: any;
|
|
16
|
+
}, void, unknown>;
|
|
17
|
+
export declare function retry(item: any, op: OperationType, handler: any): AsyncGenerator<{
|
|
18
|
+
item: any;
|
|
19
|
+
reason: OperationType;
|
|
20
|
+
type: string;
|
|
21
|
+
status: string;
|
|
22
|
+
message: any;
|
|
23
|
+
}, void, unknown>;
|
|
24
|
+
export declare function sync(item: any, op: OperationType, handler: any, syncPolicy: string, generalPolicy: string): AsyncGenerator<{
|
|
25
|
+
item: any;
|
|
26
|
+
reason: OperationType;
|
|
27
|
+
type: string;
|
|
28
|
+
status: string;
|
|
29
|
+
message: any;
|
|
30
|
+
}, void, unknown>;
|
|
10
31
|
/**
|
|
11
32
|
*
|
|
12
33
|
* @param {any} item - CR to be applied
|
|
@@ -38,8 +38,12 @@ export declare function gitRemoteUpdate(mirrorPath: string): Promise<void>;
|
|
|
38
38
|
*/
|
|
39
39
|
export declare function gitFetchPrune(mirrorPath: string): Promise<void>;
|
|
40
40
|
/**
|
|
41
|
-
* Single package-wide GitHub authentication config writer for repo mirrors and remote workflows.
|
|
42
41
|
* Writes the required url rewriting stanza to /home/node/.gitconfig based on the current org's GitHub App token.
|
|
43
42
|
* This is the ONLY allowed implementation of project git-auth per package specs.
|
|
43
|
+
*
|
|
44
|
+
* When TFM_SKIP_GIT_CONFIG=true is set, the function removes any existing
|
|
45
|
+
* /home/node/.gitconfig and returns early without writing a new one. This is
|
|
46
|
+
* used in dev/test environments where no GitHub App credentials are available
|
|
47
|
+
* (e.g. local dev, smoke tests using prefapp/tfm mirrors).
|
|
44
48
|
*/
|
|
45
49
|
export declare function configGit(): Promise<void>;
|