@caelo-cms/provisioning 0.10.44 → 0.10.47

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.
Files changed (146) hide show
  1. package/dist/adc-impersonation.d.ts +28 -0
  2. package/dist/adc-impersonation.d.ts.map +1 -0
  3. package/dist/adc-impersonation.js +148 -0
  4. package/dist/adc-impersonation.js.map +1 -0
  5. package/dist/checkpoint-secrets.d.ts.map +1 -1
  6. package/dist/checkpoint-secrets.js +2 -1
  7. package/dist/checkpoint-secrets.js.map +1 -1
  8. package/dist/cli.js +202 -33
  9. package/dist/cli.js.map +1 -1
  10. package/dist/compose.d.ts +45 -0
  11. package/dist/compose.d.ts.map +1 -1
  12. package/dist/compose.js +112 -29
  13. package/dist/compose.js.map +1 -1
  14. package/dist/gcloud-retry.d.ts +5 -1
  15. package/dist/gcloud-retry.d.ts.map +1 -1
  16. package/dist/gcloud-retry.js.map +1 -1
  17. package/dist/gcloud.d.ts +2 -1
  18. package/dist/gcloud.d.ts.map +1 -1
  19. package/dist/gcloud.js +11 -13
  20. package/dist/gcloud.js.map +1 -1
  21. package/dist/index.d.ts +3 -0
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +3 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/infra-contract.d.ts +24 -0
  26. package/dist/infra-contract.d.ts.map +1 -0
  27. package/dist/infra-contract.js +25 -0
  28. package/dist/infra-contract.js.map +1 -0
  29. package/dist/install-state.d.ts +66 -2
  30. package/dist/install-state.d.ts.map +1 -1
  31. package/dist/install-state.js +162 -22
  32. package/dist/install-state.js.map +1 -1
  33. package/dist/lifecycle.d.ts +6 -0
  34. package/dist/lifecycle.d.ts.map +1 -1
  35. package/dist/lifecycle.js +189 -819
  36. package/dist/lifecycle.js.map +1 -1
  37. package/dist/migration-runner.d.ts +3 -0
  38. package/dist/migration-runner.d.ts.map +1 -1
  39. package/dist/migration-runner.js +7 -5
  40. package/dist/migration-runner.js.map +1 -1
  41. package/dist/ops-backend.d.ts +46 -0
  42. package/dist/ops-backend.d.ts.map +1 -0
  43. package/dist/ops-backend.js +370 -0
  44. package/dist/ops-backend.js.map +1 -0
  45. package/dist/provisioner-identity.d.ts +103 -0
  46. package/dist/provisioner-identity.d.ts.map +1 -0
  47. package/dist/provisioner-identity.js +323 -0
  48. package/dist/provisioner-identity.js.map +1 -0
  49. package/dist/regions.d.ts.map +1 -1
  50. package/dist/regions.js +2 -1
  51. package/dist/regions.js.map +1 -1
  52. package/dist/release-contract.d.ts +37 -0
  53. package/dist/release-contract.d.ts.map +1 -0
  54. package/dist/release-contract.js +55 -0
  55. package/dist/release-contract.js.map +1 -0
  56. package/dist/release-manifest.d.ts +140 -0
  57. package/dist/release-manifest.d.ts.map +1 -0
  58. package/dist/release-manifest.js +319 -0
  59. package/dist/release-manifest.js.map +1 -0
  60. package/dist/self-command.d.ts +16 -0
  61. package/dist/self-command.d.ts.map +1 -0
  62. package/dist/self-command.js +20 -0
  63. package/dist/self-command.js.map +1 -0
  64. package/dist/self-hosted-release.d.ts +81 -0
  65. package/dist/self-hosted-release.d.ts.map +1 -0
  66. package/dist/self-hosted-release.js +148 -0
  67. package/dist/self-hosted-release.js.map +1 -0
  68. package/dist/self-hosted-upgrade.d.ts +91 -0
  69. package/dist/self-hosted-upgrade.d.ts.map +1 -0
  70. package/dist/self-hosted-upgrade.js +355 -0
  71. package/dist/self-hosted-upgrade.js.map +1 -0
  72. package/dist/stack-converge.d.ts.map +1 -1
  73. package/dist/stack-converge.js +2 -1
  74. package/dist/stack-converge.js.map +1 -1
  75. package/dist/state-attach.d.ts +23 -0
  76. package/dist/state-attach.d.ts.map +1 -0
  77. package/dist/state-attach.js +112 -0
  78. package/dist/state-attach.js.map +1 -0
  79. package/dist/state-backend.d.ts +114 -0
  80. package/dist/state-backend.d.ts.map +1 -0
  81. package/dist/state-backend.js +200 -0
  82. package/dist/state-backend.js.map +1 -0
  83. package/dist/state-command.d.ts +20 -0
  84. package/dist/state-command.d.ts.map +1 -0
  85. package/dist/state-command.js +237 -0
  86. package/dist/state-command.js.map +1 -0
  87. package/dist/state-migrate.d.ts +121 -0
  88. package/dist/state-migrate.d.ts.map +1 -0
  89. package/dist/state-migrate.js +290 -0
  90. package/dist/state-migrate.js.map +1 -0
  91. package/dist/state-pulumi.d.ts +17 -0
  92. package/dist/state-pulumi.d.ts.map +1 -0
  93. package/dist/state-pulumi.js +218 -0
  94. package/dist/state-pulumi.js.map +1 -0
  95. package/dist/state-store.d.ts +82 -0
  96. package/dist/state-store.d.ts.map +1 -0
  97. package/dist/state-store.js +205 -0
  98. package/dist/state-store.js.map +1 -0
  99. package/dist/upgrade/app-roll.d.ts +164 -0
  100. package/dist/upgrade/app-roll.d.ts.map +1 -0
  101. package/dist/upgrade/app-roll.js +270 -0
  102. package/dist/upgrade/app-roll.js.map +1 -0
  103. package/dist/upgrade/backup.d.ts +48 -0
  104. package/dist/upgrade/backup.d.ts.map +1 -0
  105. package/dist/upgrade/backup.js +71 -0
  106. package/dist/upgrade/backup.js.map +1 -0
  107. package/dist/upgrade/converge.d.ts +45 -0
  108. package/dist/upgrade/converge.d.ts.map +1 -0
  109. package/dist/upgrade/converge.js +287 -0
  110. package/dist/upgrade/converge.js.map +1 -0
  111. package/dist/upgrade/gcp-lookup.d.ts +23 -0
  112. package/dist/upgrade/gcp-lookup.d.ts.map +1 -0
  113. package/dist/upgrade/gcp-lookup.js +95 -0
  114. package/dist/upgrade/gcp-lookup.js.map +1 -0
  115. package/dist/upgrade/health.d.ts +99 -0
  116. package/dist/upgrade/health.d.ts.map +1 -0
  117. package/dist/upgrade/health.js +214 -0
  118. package/dist/upgrade/health.js.map +1 -0
  119. package/dist/upgrade/release-images.d.ts +125 -0
  120. package/dist/upgrade/release-images.d.ts.map +1 -0
  121. package/dist/upgrade/release-images.js +315 -0
  122. package/dist/upgrade/release-images.js.map +1 -0
  123. package/dist/upgrade/reporter.d.ts +17 -0
  124. package/dist/upgrade/reporter.d.ts.map +1 -0
  125. package/dist/upgrade/reporter.js +28 -0
  126. package/dist/upgrade/reporter.js.map +1 -0
  127. package/dist/upgrade/upgrade.d.ts +79 -0
  128. package/dist/upgrade/upgrade.d.ts.map +1 -0
  129. package/dist/upgrade/upgrade.js +105 -0
  130. package/dist/upgrade/upgrade.js.map +1 -0
  131. package/dist/wizard.d.ts.map +1 -1
  132. package/dist/wizard.js +7 -3
  133. package/dist/wizard.js.map +1 -1
  134. package/dist/wizards/gcp-cost.d.ts.map +1 -1
  135. package/dist/wizards/gcp-cost.js +7 -1
  136. package/dist/wizards/gcp-cost.js.map +1 -1
  137. package/dist/wizards/gcp-pulumi.d.ts +104 -8
  138. package/dist/wizards/gcp-pulumi.d.ts.map +1 -1
  139. package/dist/wizards/gcp-pulumi.js +159 -50
  140. package/dist/wizards/gcp-pulumi.js.map +1 -1
  141. package/dist/wizards/gcp.d.ts.map +1 -1
  142. package/dist/wizards/gcp.js +246 -78
  143. package/dist/wizards/gcp.js.map +1 -1
  144. package/package.json +4 -3
  145. package/stacks/self-hosted/README.md +4 -0
  146. package/stacks/self-hosted/index.ts +10 -2
@@ -0,0 +1,20 @@
1
+ /** Where install-dir archives go: `~/.caelo-backups/` (mode 700). */
2
+ export declare function backupsDir(home?: string): string;
3
+ /**
4
+ * Archive `~/.caelo-<id>/` (secrets and state included) to
5
+ * `~/.caelo-backups/<id>-<time>.tar.zst`, or `.tar.gz` when `zstd` is not
6
+ * installed. The archive and its directory are private (600 / 700): it
7
+ * holds the passphrase. Throws when the archive can't be made.
8
+ *
9
+ * @returns the archive's path
10
+ */
11
+ export declare function backupInstallDir(installId: string, opts?: {
12
+ home?: string;
13
+ now?: Date;
14
+ hasZstd?: boolean;
15
+ }): string;
16
+ /** `cms-provision state migrate …`. */
17
+ export declare function stateCommand(argv: readonly string[]): Promise<void>;
18
+ /** `cms-provision attach --project <id>`. */
19
+ export declare function attachCommand(argv: readonly string[]): Promise<void>;
20
+ //# sourceMappingURL=state-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-command.d.ts","sourceRoot":"","sources":["../src/state-command.ts"],"names":[],"mappings":"AAiDA,qEAAqE;AACrE,wBAAgB,UAAU,CAAC,IAAI,GAAE,MAAkB,GAAG,MAAM,CAE3D;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAC1D,MAAM,CAiCR;AAeD,uCAAuC;AACvC,wBAAsB,YAAY,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuJzE;AAED,6CAA6C;AAC7C,wBAAsB,aAAa,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB1E"}
@@ -0,0 +1,237 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * CLI wiring for `cms-provision state migrate` and `cms-provision attach`
4
+ * (#696): parses the flags, picks the install, and hands the engines
5
+ * (state-migrate.ts, state-attach.ts) the real gcloud, Pulumi and file
6
+ * system.
7
+ */
8
+ import { spawnSync } from "node:child_process";
9
+ import { randomBytes } from "node:crypto";
10
+ import { chmodSync, existsSync, mkdirSync, renameSync, rmSync } from "node:fs";
11
+ import { homedir } from "node:os";
12
+ import { join } from "node:path";
13
+ import { confirm, isCancel, log, note } from "@clack/prompts";
14
+ import { bold, red } from "kleur/colors";
15
+ import { activeAccount } from "./gcloud.js";
16
+ import { adoptStateBackend, currentMetadata, ensureInstallDir, installFlag, installRoot, installStagingHost, listInstalls, readSecret, recordedImageDigests, selectInstall, writeSecret, } from "./install-state.js";
17
+ import { installIapAllowlist } from "./operator-access.js";
18
+ import { ensureOpsBackend } from "./ops-backend.js";
19
+ import { provisionerServiceAccountEmail } from "./provisioner-identity.js";
20
+ import { selfCommand } from "./self-command.js";
21
+ import { attachInstall } from "./state-attach.js";
22
+ import { gcsBackendRecord, hasLocalPulumiState, installBackend, localStateDir, parseStateBackend, resolveBackend, } from "./state-backend.js";
23
+ import { migrateState } from "./state-migrate.js";
24
+ import { realStatePulumiOps } from "./state-pulumi.js";
25
+ import { acquireStateLock, GcsStateStore, realSyncGcloud } from "./state-store.js";
26
+ import { clackReporter } from "./upgrade/reporter.js";
27
+ import { GCP_STACK_KNOB_DEFAULTS } from "./wizards/gcp-pulumi.js";
28
+ /** Where install-dir archives go: `~/.caelo-backups/` (mode 700). */
29
+ export function backupsDir(home = homedir()) {
30
+ return join(home, ".caelo-backups");
31
+ }
32
+ /**
33
+ * Archive `~/.caelo-<id>/` (secrets and state included) to
34
+ * `~/.caelo-backups/<id>-<time>.tar.zst`, or `.tar.gz` when `zstd` is not
35
+ * installed. The archive and its directory are private (600 / 700): it
36
+ * holds the passphrase. Throws when the archive can't be made.
37
+ *
38
+ * @returns the archive's path
39
+ */
40
+ export function backupInstallDir(installId, opts = {}) {
41
+ const home = opts.home ?? homedir();
42
+ const dir = backupsDir(home);
43
+ if (!existsSync(dir))
44
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
45
+ chmodSync(dir, 0o700);
46
+ const stamp = (opts.now ?? new Date()).toISOString().replace(/[:.]/g, "-");
47
+ const base = join(dir, `${installId}-${stamp}`);
48
+ const zstd = opts.hasZstd ?? spawnSync("zstd", ["--version"], { stdio: "ignore" }).status === 0;
49
+ const source = ["-C", home, `.caelo-${installId}`];
50
+ const run = (cmd, args) => {
51
+ const r = spawnSync(cmd, args, { stdio: ["ignore", "ignore", "pipe"], encoding: "utf8" });
52
+ if (r.status !== 0) {
53
+ throw new Error(`${cmd} failed while archiving ~/.caelo-${installId}: ${(r.stderr ?? "").trim()}`);
54
+ }
55
+ };
56
+ if (zstd) {
57
+ const tar = `${base}.tar`;
58
+ try {
59
+ run("tar", ["-cf", tar, ...source]);
60
+ chmodSync(tar, 0o600);
61
+ run("zstd", ["-q", "--rm", "-o", `${tar}.zst`, tar]);
62
+ }
63
+ finally {
64
+ rmSync(tar, { force: true });
65
+ }
66
+ chmodSync(`${tar}.zst`, 0o600);
67
+ return `${tar}.zst`;
68
+ }
69
+ const out = `${base}.tar.gz`;
70
+ run("tar", ["-czf", out, ...source]);
71
+ chmodSync(out, 0o600);
72
+ return out;
73
+ }
74
+ /** The value of `--<name> <v>` / `--<name>=<v>` on argv. */
75
+ function flagValue(argv, name) {
76
+ for (let i = 0; i < argv.length; i++) {
77
+ const a = argv[i] ?? "";
78
+ if (a === `--${name}`)
79
+ return argv[i + 1];
80
+ if (a.startsWith(`--${name}=`))
81
+ return a.slice(name.length + 3);
82
+ }
83
+ return undefined;
84
+ }
85
+ const USAGE = "Usage: cms-provision state migrate [--install <install-id or domain>] [--to remote|local] [--dry-run] [--yes]";
86
+ /** `cms-provision state migrate …`. */
87
+ export async function stateCommand(argv) {
88
+ if (argv[3] !== "migrate") {
89
+ console.log(USAGE);
90
+ process.exit(2);
91
+ }
92
+ const to = flagValue(argv, "to") ?? "remote";
93
+ if (to !== "remote" && to !== "local") {
94
+ console.error(`--to must be remote or local.\n${USAGE}`);
95
+ process.exit(2);
96
+ }
97
+ const dryRun = argv.includes("--dry-run");
98
+ const selected = selectInstall(listInstalls(), installFlag(argv));
99
+ if (!selected.ok) {
100
+ console.error(selected.message);
101
+ process.exit(1);
102
+ }
103
+ const meta = currentMetadata(selected.meta);
104
+ const { installId } = meta;
105
+ const root = installRoot(installId);
106
+ if ((meta.provider !== "gcp" && meta.provider !== "gcp-firebase") ||
107
+ !meta.projectId ||
108
+ !meta.region) {
109
+ log.error(red(`${installId} (${meta.provider}) keeps its state on the host or has no project/region recorded; state migrate is for gcp and gcp-firebase installs.`));
110
+ process.exit(1);
111
+ }
112
+ const { projectId, region, provider } = meta;
113
+ const imageDigests = recordedImageDigests(meta);
114
+ if (!imageDigests) {
115
+ log.error(red(`install.json of ${installId} records no image digests. Run ${bold(selfCommand("upgrade", "--install", installId))} first, then migrate.`));
116
+ process.exit(1);
117
+ }
118
+ const operator = await activeAccount();
119
+ if (!operator) {
120
+ log.error(red("No active gcloud account. Run `gcloud auth login`, then re-run."));
121
+ process.exit(1);
122
+ }
123
+ const provisioner = provisionerServiceAccountEmail(projectId);
124
+ note([
125
+ `Install: ${bold(meta.domain)} (${installId}, project ${projectId}, ${region})`,
126
+ `Direction: ${to === "remote" ? `this machine → gs://${gcsBackendRecord(projectId, region).bucket} + Cloud KMS` : "the install's bucket → this machine"}`,
127
+ dryRun
128
+ ? "Dry run: nothing will be changed"
129
+ : "The source stays in use until the copy is verified.",
130
+ ].join("\n"), "state migrate");
131
+ const result = await migrateState(meta, { to, dryRun }, {
132
+ pulumi: realStatePulumiOps({
133
+ provider,
134
+ installRoot: root,
135
+ impersonateServiceAccount: provisioner,
136
+ stackConfig: {
137
+ ...GCP_STACK_KNOB_DEFAULTS,
138
+ provider,
139
+ projectId,
140
+ domain: meta.domain,
141
+ stagingDomain: installStagingHost(meta),
142
+ ownerEmail: meta.ownerEmail,
143
+ region,
144
+ iapAllowlist: installIapAllowlist(meta.ownerEmail),
145
+ imageDigests,
146
+ },
147
+ }),
148
+ report: clackReporter(),
149
+ resolve: (record) => resolveBackend({ installId, stateBackend: record }, { installRoot: root, readPassphrase: () => readSecret(installId, "pulumi-passphrase") }),
150
+ confirmCost: async (costNote) => {
151
+ log.info(costNote);
152
+ if (argv.includes("--yes"))
153
+ return true;
154
+ if (!process.stdin.isTTY) {
155
+ log.error(red("Not a terminal: pass --yes to accept the cost above."));
156
+ return false;
157
+ }
158
+ const yes = await confirm({ message: "Create them and continue?", initialValue: true });
159
+ return !isCancel(yes) && yes === true;
160
+ },
161
+ ensureRemote: (dry) => ensureOpsBackend({ projectId, region, operatorAccount: operator, provisionerEmail: provisioner }, { dryRun: dry }),
162
+ backup: async () => backupInstallDir(installId),
163
+ localStateEmpty: () => !hasLocalPulumiState(root),
164
+ prepareLocalTarget: () => {
165
+ mkdirSync(localStateDir(root), { recursive: true, mode: 0o700 });
166
+ if (!readSecret(installId, "pulumi-passphrase")) {
167
+ writeSecret(installId, "pulumi-passphrase", randomBytes(32).toString("hex"));
168
+ }
169
+ },
170
+ lock: async () => {
171
+ // The source's lock (local file or bucket object) keeps installer
172
+ // runs out; the bucket's also keeps out a migration started on
173
+ // another machine when the bucket is the target.
174
+ const source = meta.stateBackend ?? { kind: "local" };
175
+ const releases = [acquireStateLock(source, root, "state migrate")];
176
+ if (source.kind === "local" && to === "remote") {
177
+ try {
178
+ releases.push(acquireStateLock(gcsBackendRecord(projectId, region), root, "state migrate"));
179
+ }
180
+ catch (e) {
181
+ for (const r of releases)
182
+ r();
183
+ throw e;
184
+ }
185
+ }
186
+ return async () => {
187
+ for (const r of releases.reverse())
188
+ r();
189
+ };
190
+ },
191
+ remoteRecordedBackend: () => {
192
+ const text = new GcsStateStore(gcsBackendRecord(projectId, region).bucket, root).peek("install.json");
193
+ if (text === null)
194
+ return null;
195
+ return installBackend({ stateBackend: parseStateBackend(JSON.parse(text).stateBackend) })
196
+ .kind;
197
+ },
198
+ adopt: (record) => {
199
+ adoptStateBackend(installId, record);
200
+ },
201
+ retireLocalState: () => {
202
+ const dir = localStateDir(root);
203
+ if (!existsSync(dir))
204
+ return null;
205
+ const moved = `${dir}.migrated-${new Date().toISOString().replace(/[:.]/g, "-")}`;
206
+ renameSync(dir, moved);
207
+ return moved;
208
+ },
209
+ });
210
+ if (!result.ok) {
211
+ log.error(red(result.error));
212
+ process.exit(1);
213
+ }
214
+ }
215
+ /** `cms-provision attach --project <id>`. */
216
+ export async function attachCommand(argv) {
217
+ const projectId = flagValue(argv, "project");
218
+ if (!projectId || projectId.startsWith("-")) {
219
+ console.log("Usage: cms-provision attach --project <gcp-project-id>");
220
+ process.exit(2);
221
+ }
222
+ const r = attachInstall(projectId, {
223
+ run: realSyncGcloud,
224
+ rootFor: installRoot,
225
+ hasLocalState: hasLocalPulumiState,
226
+ });
227
+ if (!r.ok) {
228
+ log.error(red(r.error));
229
+ process.exit(1);
230
+ }
231
+ ensureInstallDir(r.installId);
232
+ log.success(r.status === "refreshed"
233
+ ? `${r.domain} was already attached; its local copy of install.json is up to date.`
234
+ : `Attached ${bold(r.domain)} (${r.installId}). status, upgrade, backup and re-running the installer now work from this machine.`);
235
+ log.info("Infrastructure runs need Application Default Credentials once on this machine: gcloud auth application-default login");
236
+ }
237
+ //# sourceMappingURL=state-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-command.js","sourceRoot":"","sources":["../src/state-command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * `cms-provision state migrate` (#696): move an existing install's Pulumi
3
+ * state, secrets provider and install metadata between this machine
4
+ * (`~/.caelo-<id>/state` + passphrase) and the install's own GCP project
5
+ * (`gs://<project>-caelo-ops` + Cloud KMS), in either direction.
6
+ *
7
+ * The source stays authoritative until the very end:
8
+ *
9
+ * 1. preflight — Pulumi CLI version (`pulumi stack migrate` from
10
+ * {@link STACK_MIGRATE_MIN_VERSION}, else export/import +
11
+ * change-secrets-provider), the source stack exists, has no pending
12
+ * operations, and a preview of it shows no changes (an unconverged
13
+ * stack can't prove the copy is identical, so it is refused);
14
+ * 2. a mode-600 archive of `~/.caelo-<id>/` (tar.zst, else tar.gz);
15
+ * 3. the target: bucket + KMS key ensured (remote) or an empty local
16
+ * state dir + passphrase (local); a leftover copy from an interrupted
17
+ * run is removed — it was never authoritative;
18
+ * 4. copy, re-encrypting the secrets for the target's provider;
19
+ * 5. verify — a preview of the target shows no changes and its outputs
20
+ * (secrets included) hash identically to the source's; on any
21
+ * mismatch the target copy is removed and nothing else changes;
22
+ * 6. flip — install.json records the new backend (locally and in the
23
+ * bucket); the old local state dir is renamed, never deleted.
24
+ *
25
+ * `--dry-run` runs the read-only preflight and reports what it would do.
26
+ * The engine takes its side effects as {@link MigrateDeps} so the whole
27
+ * sequence is tested against fakes (state-migrate.test.ts); state-command.ts
28
+ * wires the real Pulumi CLI, gcloud and file system.
29
+ */
30
+ import type { OpsBackendResult } from "./ops-backend.js";
31
+ import { type ResolvedBackend, type StateBackendRecord } from "./state-backend.js";
32
+ import type { UpgradeReporter } from "./upgrade/reporter.js";
33
+ /** First Pulumi CLI release with `pulumi stack migrate` between DIY backends. */
34
+ export declare const STACK_MIGRATE_MIN_VERSION = "3.254.0";
35
+ /** What the ops bucket + KMS key cost (wizards/gcp-cost.ts carries the same line). */
36
+ export declare const OPS_BACKEND_COST_NOTE = "Creates (if missing) a versioned Cloud Storage bucket + one Cloud KMS key in the install's project: < $0.10/mo (KMS key version $0.06/mo, a few MB of state).";
37
+ /** The Pulumi operations a migration needs, against one backend at a time. */
38
+ export interface StatePulumiOps {
39
+ /** `pulumi version` without the `v`, or null when the CLI is missing. */
40
+ cliVersion(): Promise<string | null>;
41
+ stackExists(backend: ResolvedBackend): Promise<boolean>;
42
+ /** Pending operations recorded in the stack's state (an interrupted run). */
43
+ pendingOperations(backend: ResolvedBackend): Promise<number>;
44
+ /** Steps a preview would take other than "same". */
45
+ previewChanges(backend: ResolvedBackend): Promise<number>;
46
+ /** sha256 of the stack outputs, secrets included. Never the values. */
47
+ outputsDigest(backend: ResolvedBackend): Promise<string>;
48
+ /** Whether a Pulumi operation holds the stack's lock in `backend` right now. */
49
+ locked(backend: ResolvedBackend): Promise<boolean>;
50
+ /** sha256 of the stack's exported checkpoint (ciphertext; never decrypted). */
51
+ stateDigest(backend: ResolvedBackend): Promise<string>;
52
+ /** `pulumi stack migrate <from> --secrets-provider <to's>` into `to`. */
53
+ stackMigrate(from: ResolvedBackend, to: ResolvedBackend): Promise<void>;
54
+ /** export → init → import → change-secrets-provider (older CLIs). */
55
+ exportImport(from: ResolvedBackend, to: ResolvedBackend): Promise<void>;
56
+ /** Remove the stack's state from `backend` (cloud resources untouched). */
57
+ removeStack(backend: ResolvedBackend): Promise<void>;
58
+ }
59
+ /** Everything the migration touches outside Pulumi. */
60
+ export interface MigrateDeps {
61
+ readonly pulumi: StatePulumiOps;
62
+ readonly report: UpgradeReporter;
63
+ /** The install's backend resolved for Pulumi. */
64
+ resolve(record: StateBackendRecord): ResolvedBackend;
65
+ /** Ask the operator to accept the ops backend's cost; false = cancel. */
66
+ confirmCost(note: string): Promise<boolean>;
67
+ /** Ensure (or, dry, inspect) the ops bucket + KMS key. */
68
+ ensureRemote(dryRun: boolean): Promise<OpsBackendResult>;
69
+ /** Archive `~/.caelo-<id>/`; returns the archive's path. */
70
+ backup(): Promise<string>;
71
+ /** Whether the local state dir is absent or holds no stack. */
72
+ localStateEmpty(): boolean;
73
+ /** Create the local state dir (mode 700) and `secrets/pulumi-passphrase` if missing. */
74
+ prepareLocalTarget(): void;
75
+ /**
76
+ * The backend the bucket's install.json names (`null` when the bucket or
77
+ * the document doesn't exist). `gcs` there means the bucket copy is
78
+ * authoritative — some machine finished a migration — and must never be
79
+ * replaced from this machine's (then stale) local state.
80
+ */
81
+ remoteRecordedBackend(): StateBackendRecord["kind"] | null;
82
+ /** Record the new backend (install-state.ts adoptStateBackend). */
83
+ adopt(record: StateBackendRecord): void;
84
+ /**
85
+ * Take the install's state lock (state-store.ts acquireStateLock: the
86
+ * source's, plus the bucket's when it is the target), which installer
87
+ * runs hold through `pulumi up` too; throws when another run holds it.
88
+ * Returns the release function.
89
+ */
90
+ lock(): Promise<() => Promise<void>>;
91
+ /** Rename the local state dir out of the way; returns where it went. */
92
+ retireLocalState(): string | null;
93
+ }
94
+ export interface MigrateOptions {
95
+ readonly to: "remote" | "local";
96
+ readonly dryRun: boolean;
97
+ }
98
+ export type MigrateResult = {
99
+ readonly ok: true;
100
+ readonly changed: boolean;
101
+ } | {
102
+ readonly ok: false;
103
+ readonly error: string;
104
+ };
105
+ /** The subset of install metadata a migration reads. */
106
+ export interface MigrateInstall {
107
+ readonly installId: string;
108
+ readonly provider: string;
109
+ readonly projectId: string | null;
110
+ readonly region: string | null;
111
+ readonly stateBackend?: StateBackendRecord;
112
+ }
113
+ /** a >= b for dotted numeric versions (`3.254.0`). */
114
+ export declare function versionAtLeast(a: string, b: string): boolean;
115
+ /**
116
+ * Run the migration. Never throws for an expected failure: the result says
117
+ * what failed, and at every failure point the source backend is still the
118
+ * one install.json names.
119
+ */
120
+ export declare function migrateState(meta: MigrateInstall, opts: MigrateOptions, deps: MigrateDeps): Promise<MigrateResult>;
121
+ //# sourceMappingURL=state-migrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-migrate.d.ts","sourceRoot":"","sources":["../src/state-migrate.ts"],"names":[],"mappings":"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"}