@codyswann/lisa 4.22.8 → 4.22.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +2 -1
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/package.json +3 -3
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +95 -44
- package/plugins/lisa/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +95 -44
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +95 -44
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +95 -44
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +95 -44
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +95 -44
|
@@ -56,6 +56,11 @@ const ROLE_ARN =
|
|
|
56
56
|
/^arn:(?:aws|aws-us-gov|aws-cn):iam::\d{12}:role\/[\w+=,.@/-]+$/;
|
|
57
57
|
const PUBLICATION_COORDINATION_SCOPE = "AWS_BOOTSTRAP_";
|
|
58
58
|
const PUBLICATION_LOCK_TTL_MS = 30 * 60 * 1000;
|
|
59
|
+
// Every provider and AWS child has its own 30-second deadline. Stop starting
|
|
60
|
+
// target mutations five minutes before another publisher may reap this lock,
|
|
61
|
+
// leaving ample room for the in-flight child to finish. This is a monotonic
|
|
62
|
+
// duration budget, not a wall clock used to order or expire provider records.
|
|
63
|
+
const PUBLICATION_CRITICAL_SECTION_BUDGET_MS = 25 * 60 * 1000;
|
|
59
64
|
|
|
60
65
|
/**
|
|
61
66
|
* Validate and normalize one complete bundle without changing its serialized
|
|
@@ -257,6 +262,22 @@ function writeProviderValue(cfg, id, value, write) {
|
|
|
257
262
|
}
|
|
258
263
|
}
|
|
259
264
|
|
|
265
|
+
function publicationBudgetGuard(startedAt, monotonicNow) {
|
|
266
|
+
return () => {
|
|
267
|
+
const elapsed = monotonicNow() - startedAt;
|
|
268
|
+
if (!Number.isFinite(elapsed) || elapsed < 0) {
|
|
269
|
+
throw new Error(
|
|
270
|
+
"publication lock monotonic timer became invalid; refusing further provider mutation"
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
if (elapsed >= PUBLICATION_CRITICAL_SECTION_BUDGET_MS) {
|
|
274
|
+
throw new Error(
|
|
275
|
+
"publication lock execution budget exceeded; refusing further provider mutation"
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
|
|
260
281
|
/**
|
|
261
282
|
* Enter the provider election for one AWS bootstrap record.
|
|
262
283
|
*
|
|
@@ -427,23 +448,29 @@ export function releasePublicationLock(cfg, lock, operations = {}) {
|
|
|
427
448
|
* snapshot can never overwrite a publication that finished while this process
|
|
428
449
|
* was entering the election.
|
|
429
450
|
*/
|
|
430
|
-
function withPublicationLock(cfg, operations, task) {
|
|
451
|
+
function withPublicationLock(cfg, operations, task, completedMessage) {
|
|
431
452
|
const fetch = operations.fetch ?? fetchAll;
|
|
432
453
|
const acquire = operations.acquireLock ?? acquirePublicationLock;
|
|
433
454
|
const release = operations.releaseLock ?? releasePublicationLock;
|
|
455
|
+
const monotonicNow = operations.monotonicNow ?? (() => performance.now());
|
|
456
|
+
const startedAt = monotonicNow();
|
|
457
|
+
const assertWithinBudget = publicationBudgetGuard(startedAt, monotonicNow);
|
|
434
458
|
const target = currentEntry(cfg, fetch);
|
|
435
459
|
const lock = acquire(cfg, target, operations);
|
|
436
460
|
let result;
|
|
437
461
|
let taskError;
|
|
438
462
|
|
|
439
463
|
try {
|
|
464
|
+
assertWithinBudget();
|
|
440
465
|
const current = currentEntry(cfg, fetch);
|
|
441
466
|
if (current.id !== target.id || current.projectId !== target.projectId) {
|
|
442
467
|
throw new Error(
|
|
443
468
|
`${BOOTSTRAP_KEY} moved after publication lock acquisition; retry from the new provider record`
|
|
444
469
|
);
|
|
445
470
|
}
|
|
446
|
-
|
|
471
|
+
assertWithinBudget();
|
|
472
|
+
result = task(current, assertWithinBudget);
|
|
473
|
+
assertWithinBudget();
|
|
447
474
|
} catch (error) {
|
|
448
475
|
taskError = error;
|
|
449
476
|
}
|
|
@@ -455,15 +482,18 @@ function withPublicationLock(cfg, operations, task) {
|
|
|
455
482
|
if (taskError) {
|
|
456
483
|
throw new Error(`${firstLine(taskError)}; ${releaseReason}`);
|
|
457
484
|
}
|
|
458
|
-
throw new Error(
|
|
485
|
+
throw new Error(
|
|
486
|
+
`${completedMessage}; ${releaseReason}; remove the coordination record before the next publication`
|
|
487
|
+
);
|
|
459
488
|
}
|
|
460
489
|
|
|
461
490
|
if (taskError) throw taskError;
|
|
462
491
|
return result;
|
|
463
492
|
}
|
|
464
493
|
|
|
465
|
-
function preflightUnderLock(cfg, entry, write) {
|
|
494
|
+
function preflightUnderLock(cfg, entry, write, assertWithinBudget) {
|
|
466
495
|
try {
|
|
496
|
+
assertWithinBudget();
|
|
467
497
|
writeProviderValue(cfg, entry.id, entry.value, write);
|
|
468
498
|
} catch (error) {
|
|
469
499
|
throw new Error(
|
|
@@ -482,8 +512,12 @@ function preflightUnderLock(cfg, entry, write) {
|
|
|
482
512
|
*/
|
|
483
513
|
export function preflightAwsBootstrap(cfg, operations = {}) {
|
|
484
514
|
const write = operations.write ?? writeSecret;
|
|
485
|
-
return withPublicationLock(
|
|
486
|
-
|
|
515
|
+
return withPublicationLock(
|
|
516
|
+
cfg,
|
|
517
|
+
operations,
|
|
518
|
+
(entry, assertWithinBudget) =>
|
|
519
|
+
preflightUnderLock(cfg, entry, write, assertWithinBudget),
|
|
520
|
+
"preflight completed"
|
|
487
521
|
);
|
|
488
522
|
}
|
|
489
523
|
|
|
@@ -496,12 +530,20 @@ export function preflightAwsBootstrap(cfg, operations = {}) {
|
|
|
496
530
|
* @param {Function} write Provider writer.
|
|
497
531
|
* @returns {string} Human-readable rollback outcome with no secret material.
|
|
498
532
|
*/
|
|
499
|
-
function rollback(
|
|
533
|
+
function rollback(
|
|
534
|
+
cfg,
|
|
535
|
+
previous,
|
|
536
|
+
candidateRaw,
|
|
537
|
+
fetch,
|
|
538
|
+
write,
|
|
539
|
+
assertWithinBudget
|
|
540
|
+
) {
|
|
500
541
|
try {
|
|
501
542
|
const current = currentEntry(cfg, fetch);
|
|
502
543
|
if (current.value !== candidateRaw) {
|
|
503
544
|
return "rollback skipped because the provider changed after this publication";
|
|
504
545
|
}
|
|
546
|
+
assertWithinBudget();
|
|
505
547
|
writeProviderValue(cfg, previous.id, previous.value, write);
|
|
506
548
|
const restored = currentEntry(cfg, fetch);
|
|
507
549
|
if (restored.value !== previous.value) {
|
|
@@ -528,47 +570,56 @@ export function publishAwsBootstrap(raw, cfg, operations = {}) {
|
|
|
528
570
|
const write = operations.write ?? writeSecret;
|
|
529
571
|
const verify = operations.verify ?? verifyAwsBootstrap;
|
|
530
572
|
const candidate = validateAwsBootstrap(raw);
|
|
531
|
-
return withPublicationLock(
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
573
|
+
return withPublicationLock(
|
|
574
|
+
cfg,
|
|
575
|
+
operations,
|
|
576
|
+
(previous, assertWithinBudget) => {
|
|
577
|
+
preflightUnderLock(cfg, previous, write, assertWithinBudget);
|
|
578
|
+
|
|
579
|
+
// Verify before the write. A candidate that cannot assume one of its roles
|
|
580
|
+
// never becomes the value every new remote session receives.
|
|
581
|
+
verify(candidate);
|
|
582
|
+
assertWithinBudget();
|
|
583
|
+
|
|
584
|
+
if (candidate.raw === previous.value) {
|
|
585
|
+
return {
|
|
586
|
+
changed: false,
|
|
587
|
+
profiles: candidate.profiles.map(profile => profile.name),
|
|
588
|
+
};
|
|
589
|
+
}
|
|
544
590
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
591
|
+
try {
|
|
592
|
+
assertWithinBudget();
|
|
593
|
+
writeProviderValue(cfg, previous.id, candidate.raw, write);
|
|
594
|
+
const stored = currentEntry(cfg, fetch);
|
|
595
|
+
if (stored.value !== candidate.raw) {
|
|
596
|
+
throw new Error(
|
|
597
|
+
"provider read-back did not match the candidate exactly"
|
|
598
|
+
);
|
|
599
|
+
}
|
|
600
|
+
const storedCandidate = validateAwsBootstrap(stored.value);
|
|
601
|
+
verify(storedCandidate);
|
|
602
|
+
assertWithinBudget();
|
|
603
|
+
return {
|
|
604
|
+
changed: true,
|
|
605
|
+
profiles: storedCandidate.profiles.map(profile => profile.name),
|
|
606
|
+
};
|
|
607
|
+
} catch (error) {
|
|
608
|
+
const rollbackOutcome = rollback(
|
|
609
|
+
cfg,
|
|
610
|
+
previous,
|
|
611
|
+
candidate.raw,
|
|
612
|
+
fetch,
|
|
613
|
+
write,
|
|
614
|
+
assertWithinBudget
|
|
615
|
+
);
|
|
549
616
|
throw new Error(
|
|
550
|
-
|
|
617
|
+
`${BOOTSTRAP_KEY} publication failed: ${firstLine(error)}; ${rollbackOutcome}`
|
|
551
618
|
);
|
|
552
619
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
changed: true,
|
|
557
|
-
profiles: storedCandidate.profiles.map(profile => profile.name),
|
|
558
|
-
};
|
|
559
|
-
} catch (error) {
|
|
560
|
-
const rollbackOutcome = rollback(
|
|
561
|
-
cfg,
|
|
562
|
-
previous,
|
|
563
|
-
candidate.raw,
|
|
564
|
-
fetch,
|
|
565
|
-
write
|
|
566
|
-
);
|
|
567
|
-
throw new Error(
|
|
568
|
-
`${BOOTSTRAP_KEY} publication failed: ${firstLine(error)}; ${rollbackOutcome}`
|
|
569
|
-
);
|
|
570
|
-
}
|
|
571
|
-
});
|
|
620
|
+
},
|
|
621
|
+
"publication completed"
|
|
622
|
+
);
|
|
572
623
|
}
|
|
573
624
|
|
|
574
625
|
/** Read a candidate from stdin without ever placing it in argv. */
|
|
@@ -56,6 +56,11 @@ const ROLE_ARN =
|
|
|
56
56
|
/^arn:(?:aws|aws-us-gov|aws-cn):iam::\d{12}:role\/[\w+=,.@/-]+$/;
|
|
57
57
|
const PUBLICATION_COORDINATION_SCOPE = "AWS_BOOTSTRAP_";
|
|
58
58
|
const PUBLICATION_LOCK_TTL_MS = 30 * 60 * 1000;
|
|
59
|
+
// Every provider and AWS child has its own 30-second deadline. Stop starting
|
|
60
|
+
// target mutations five minutes before another publisher may reap this lock,
|
|
61
|
+
// leaving ample room for the in-flight child to finish. This is a monotonic
|
|
62
|
+
// duration budget, not a wall clock used to order or expire provider records.
|
|
63
|
+
const PUBLICATION_CRITICAL_SECTION_BUDGET_MS = 25 * 60 * 1000;
|
|
59
64
|
|
|
60
65
|
/**
|
|
61
66
|
* Validate and normalize one complete bundle without changing its serialized
|
|
@@ -257,6 +262,22 @@ function writeProviderValue(cfg, id, value, write) {
|
|
|
257
262
|
}
|
|
258
263
|
}
|
|
259
264
|
|
|
265
|
+
function publicationBudgetGuard(startedAt, monotonicNow) {
|
|
266
|
+
return () => {
|
|
267
|
+
const elapsed = monotonicNow() - startedAt;
|
|
268
|
+
if (!Number.isFinite(elapsed) || elapsed < 0) {
|
|
269
|
+
throw new Error(
|
|
270
|
+
"publication lock monotonic timer became invalid; refusing further provider mutation"
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
if (elapsed >= PUBLICATION_CRITICAL_SECTION_BUDGET_MS) {
|
|
274
|
+
throw new Error(
|
|
275
|
+
"publication lock execution budget exceeded; refusing further provider mutation"
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
|
|
260
281
|
/**
|
|
261
282
|
* Enter the provider election for one AWS bootstrap record.
|
|
262
283
|
*
|
|
@@ -427,23 +448,29 @@ export function releasePublicationLock(cfg, lock, operations = {}) {
|
|
|
427
448
|
* snapshot can never overwrite a publication that finished while this process
|
|
428
449
|
* was entering the election.
|
|
429
450
|
*/
|
|
430
|
-
function withPublicationLock(cfg, operations, task) {
|
|
451
|
+
function withPublicationLock(cfg, operations, task, completedMessage) {
|
|
431
452
|
const fetch = operations.fetch ?? fetchAll;
|
|
432
453
|
const acquire = operations.acquireLock ?? acquirePublicationLock;
|
|
433
454
|
const release = operations.releaseLock ?? releasePublicationLock;
|
|
455
|
+
const monotonicNow = operations.monotonicNow ?? (() => performance.now());
|
|
456
|
+
const startedAt = monotonicNow();
|
|
457
|
+
const assertWithinBudget = publicationBudgetGuard(startedAt, monotonicNow);
|
|
434
458
|
const target = currentEntry(cfg, fetch);
|
|
435
459
|
const lock = acquire(cfg, target, operations);
|
|
436
460
|
let result;
|
|
437
461
|
let taskError;
|
|
438
462
|
|
|
439
463
|
try {
|
|
464
|
+
assertWithinBudget();
|
|
440
465
|
const current = currentEntry(cfg, fetch);
|
|
441
466
|
if (current.id !== target.id || current.projectId !== target.projectId) {
|
|
442
467
|
throw new Error(
|
|
443
468
|
`${BOOTSTRAP_KEY} moved after publication lock acquisition; retry from the new provider record`
|
|
444
469
|
);
|
|
445
470
|
}
|
|
446
|
-
|
|
471
|
+
assertWithinBudget();
|
|
472
|
+
result = task(current, assertWithinBudget);
|
|
473
|
+
assertWithinBudget();
|
|
447
474
|
} catch (error) {
|
|
448
475
|
taskError = error;
|
|
449
476
|
}
|
|
@@ -455,15 +482,18 @@ function withPublicationLock(cfg, operations, task) {
|
|
|
455
482
|
if (taskError) {
|
|
456
483
|
throw new Error(`${firstLine(taskError)}; ${releaseReason}`);
|
|
457
484
|
}
|
|
458
|
-
throw new Error(
|
|
485
|
+
throw new Error(
|
|
486
|
+
`${completedMessage}; ${releaseReason}; remove the coordination record before the next publication`
|
|
487
|
+
);
|
|
459
488
|
}
|
|
460
489
|
|
|
461
490
|
if (taskError) throw taskError;
|
|
462
491
|
return result;
|
|
463
492
|
}
|
|
464
493
|
|
|
465
|
-
function preflightUnderLock(cfg, entry, write) {
|
|
494
|
+
function preflightUnderLock(cfg, entry, write, assertWithinBudget) {
|
|
466
495
|
try {
|
|
496
|
+
assertWithinBudget();
|
|
467
497
|
writeProviderValue(cfg, entry.id, entry.value, write);
|
|
468
498
|
} catch (error) {
|
|
469
499
|
throw new Error(
|
|
@@ -482,8 +512,12 @@ function preflightUnderLock(cfg, entry, write) {
|
|
|
482
512
|
*/
|
|
483
513
|
export function preflightAwsBootstrap(cfg, operations = {}) {
|
|
484
514
|
const write = operations.write ?? writeSecret;
|
|
485
|
-
return withPublicationLock(
|
|
486
|
-
|
|
515
|
+
return withPublicationLock(
|
|
516
|
+
cfg,
|
|
517
|
+
operations,
|
|
518
|
+
(entry, assertWithinBudget) =>
|
|
519
|
+
preflightUnderLock(cfg, entry, write, assertWithinBudget),
|
|
520
|
+
"preflight completed"
|
|
487
521
|
);
|
|
488
522
|
}
|
|
489
523
|
|
|
@@ -496,12 +530,20 @@ export function preflightAwsBootstrap(cfg, operations = {}) {
|
|
|
496
530
|
* @param {Function} write Provider writer.
|
|
497
531
|
* @returns {string} Human-readable rollback outcome with no secret material.
|
|
498
532
|
*/
|
|
499
|
-
function rollback(
|
|
533
|
+
function rollback(
|
|
534
|
+
cfg,
|
|
535
|
+
previous,
|
|
536
|
+
candidateRaw,
|
|
537
|
+
fetch,
|
|
538
|
+
write,
|
|
539
|
+
assertWithinBudget
|
|
540
|
+
) {
|
|
500
541
|
try {
|
|
501
542
|
const current = currentEntry(cfg, fetch);
|
|
502
543
|
if (current.value !== candidateRaw) {
|
|
503
544
|
return "rollback skipped because the provider changed after this publication";
|
|
504
545
|
}
|
|
546
|
+
assertWithinBudget();
|
|
505
547
|
writeProviderValue(cfg, previous.id, previous.value, write);
|
|
506
548
|
const restored = currentEntry(cfg, fetch);
|
|
507
549
|
if (restored.value !== previous.value) {
|
|
@@ -528,47 +570,56 @@ export function publishAwsBootstrap(raw, cfg, operations = {}) {
|
|
|
528
570
|
const write = operations.write ?? writeSecret;
|
|
529
571
|
const verify = operations.verify ?? verifyAwsBootstrap;
|
|
530
572
|
const candidate = validateAwsBootstrap(raw);
|
|
531
|
-
return withPublicationLock(
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
573
|
+
return withPublicationLock(
|
|
574
|
+
cfg,
|
|
575
|
+
operations,
|
|
576
|
+
(previous, assertWithinBudget) => {
|
|
577
|
+
preflightUnderLock(cfg, previous, write, assertWithinBudget);
|
|
578
|
+
|
|
579
|
+
// Verify before the write. A candidate that cannot assume one of its roles
|
|
580
|
+
// never becomes the value every new remote session receives.
|
|
581
|
+
verify(candidate);
|
|
582
|
+
assertWithinBudget();
|
|
583
|
+
|
|
584
|
+
if (candidate.raw === previous.value) {
|
|
585
|
+
return {
|
|
586
|
+
changed: false,
|
|
587
|
+
profiles: candidate.profiles.map(profile => profile.name),
|
|
588
|
+
};
|
|
589
|
+
}
|
|
544
590
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
591
|
+
try {
|
|
592
|
+
assertWithinBudget();
|
|
593
|
+
writeProviderValue(cfg, previous.id, candidate.raw, write);
|
|
594
|
+
const stored = currentEntry(cfg, fetch);
|
|
595
|
+
if (stored.value !== candidate.raw) {
|
|
596
|
+
throw new Error(
|
|
597
|
+
"provider read-back did not match the candidate exactly"
|
|
598
|
+
);
|
|
599
|
+
}
|
|
600
|
+
const storedCandidate = validateAwsBootstrap(stored.value);
|
|
601
|
+
verify(storedCandidate);
|
|
602
|
+
assertWithinBudget();
|
|
603
|
+
return {
|
|
604
|
+
changed: true,
|
|
605
|
+
profiles: storedCandidate.profiles.map(profile => profile.name),
|
|
606
|
+
};
|
|
607
|
+
} catch (error) {
|
|
608
|
+
const rollbackOutcome = rollback(
|
|
609
|
+
cfg,
|
|
610
|
+
previous,
|
|
611
|
+
candidate.raw,
|
|
612
|
+
fetch,
|
|
613
|
+
write,
|
|
614
|
+
assertWithinBudget
|
|
615
|
+
);
|
|
549
616
|
throw new Error(
|
|
550
|
-
|
|
617
|
+
`${BOOTSTRAP_KEY} publication failed: ${firstLine(error)}; ${rollbackOutcome}`
|
|
551
618
|
);
|
|
552
619
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
changed: true,
|
|
557
|
-
profiles: storedCandidate.profiles.map(profile => profile.name),
|
|
558
|
-
};
|
|
559
|
-
} catch (error) {
|
|
560
|
-
const rollbackOutcome = rollback(
|
|
561
|
-
cfg,
|
|
562
|
-
previous,
|
|
563
|
-
candidate.raw,
|
|
564
|
-
fetch,
|
|
565
|
-
write
|
|
566
|
-
);
|
|
567
|
-
throw new Error(
|
|
568
|
-
`${BOOTSTRAP_KEY} publication failed: ${firstLine(error)}; ${rollbackOutcome}`
|
|
569
|
-
);
|
|
570
|
-
}
|
|
571
|
-
});
|
|
620
|
+
},
|
|
621
|
+
"publication completed"
|
|
622
|
+
);
|
|
572
623
|
}
|
|
573
624
|
|
|
574
625
|
/** Read a candidate from stdin without ever placing it in argv. */
|