@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,270 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ import { gatewayServiceAccountEmail, runServiceAccountEmail } from "../gcp-names.js";
3
+ import { adminMediaVolume } from "../stack-contract.js";
4
+ import { liveContainerEnv, liveContainerMemory, liveVolumes, planAdminMemory, planContractEnv, planMediaVolume, rollService, serviceRollArgs, } from "../stack-converge.js";
5
+ import { restoreCommand } from "./backup.js";
6
+ import { describeServiceJson, findCurrentRevision, findServiceUrl, pinTraffic, resolveGcpResourceName, } from "./gcp-lookup.js";
7
+ /** The roll order: the gateway follows the admin, never the other way round. */
8
+ export const ROLL_ORDER = ["admin", "gateway"];
9
+ /**
10
+ * Read both services and plan their rolls: prior revisions (the rollback
11
+ * targets), env-contract changes, the admin's memory and media volume. Makes
12
+ * no change; fails when anything a roll needs is missing.
13
+ */
14
+ export async function planAppRoll(install, images, run) {
15
+ const services = [];
16
+ for (const slug of ROLL_ORDER) {
17
+ const prefix = `caelo-${install.env}-${slug}`;
18
+ const serviceName = await resolveGcpResourceName(run, "run-service", prefix, install.projectId, install.region);
19
+ if (!serviceName)
20
+ return { ok: false, error: `Could not find the ${prefix}* Cloud Run service` };
21
+ const priorRevision = await findCurrentRevision(run, install.projectId, install.region, serviceName);
22
+ if (!priorRevision) {
23
+ return {
24
+ ok: false,
25
+ error: `Could not capture the current ${slug} revision — refusing to roll`,
26
+ };
27
+ }
28
+ const json = await describeServiceJson(run, install.projectId, install.region, serviceName);
29
+ if (!json) {
30
+ return {
31
+ ok: false,
32
+ error: `Could not read the ${slug} service's configuration — refusing to roll`,
33
+ };
34
+ }
35
+ services.push({
36
+ slug,
37
+ serviceName,
38
+ ...images[slug],
39
+ priorRevision,
40
+ liveEnv: liveContainerEnv(json),
41
+ liveMemory: liveContainerMemory(json),
42
+ liveVolumes: liveVolumes(json),
43
+ });
44
+ }
45
+ const env = planEnv(install, services, []);
46
+ if (!env.ok)
47
+ return { ok: false, error: `the install's env contract can't be applied: ${env.error}` };
48
+ // Without the media volume every upload is lost on the next revision or
49
+ // scale-to-zero, so a volume the roll cannot add fails the plan.
50
+ const admin = services.find((s) => s.slug === "admin");
51
+ const media = planMediaVolume(admin.liveVolumes, adminMediaVolume(install.projectId, install.env));
52
+ if (!media.ok)
53
+ return { ok: false, error: `the admin's media volume can't be set up: ${media.error}` };
54
+ const warnings = [];
55
+ const rolls = services.map((s) => {
56
+ // #553 — the admin runs the Lighthouse quality audit; raise it to the
57
+ // stack's memory default (never lowered; an unparsable value is kept).
58
+ const memory = s.slug === "admin" ? planAdminMemory(s.liveMemory) : null;
59
+ if (memory && !memory.ok)
60
+ warnings.push(`admin memory left as is: ${memory.error}`);
61
+ return {
62
+ ...s,
63
+ envFlags: env.services[s.slug].flags,
64
+ envChanges: env.services[s.slug].changes,
65
+ resourceFlags: memory?.ok ? memory.flags : [],
66
+ volumeFlags: s.slug === "admin" ? media.flags : [],
67
+ volumeChanges: s.slug === "admin" ? media.changes : [],
68
+ };
69
+ });
70
+ return { ok: true, plan: { install, services: rolls, warnings } };
71
+ }
72
+ function planEnv(install, services, leaveUntouched) {
73
+ const deployed = Object.fromEntries(services.map((s) => [s.slug, { serviceName: s.serviceName, liveEnv: s.liveEnv }]));
74
+ return planContractEnv({
75
+ provider: install.provider,
76
+ projectId: install.projectId,
77
+ env: install.env,
78
+ domain: install.domain,
79
+ region: install.region,
80
+ stagingHost: install.stagingHost,
81
+ }, deployed, { leaveUntouched });
82
+ }
83
+ /**
84
+ * The plan with `names` left exactly as the services have them — for env
85
+ * vars that point at something a converge step could not set up.
86
+ */
87
+ export function leavingEnvUntouched(plan, names) {
88
+ if (names.length === 0)
89
+ return plan;
90
+ const env = planEnv(plan.install, plan.services, names);
91
+ if (!env.ok)
92
+ return plan;
93
+ return {
94
+ ...plan,
95
+ services: plan.services.map((s) => ({
96
+ ...s,
97
+ envFlags: env.services[s.slug].flags,
98
+ envChanges: env.services[s.slug].changes,
99
+ })),
100
+ };
101
+ }
102
+ /** Print what the plan will change, one line per change. */
103
+ export function reportPlan(plan, reporter) {
104
+ for (const w of plan.warnings)
105
+ reporter.warn(w);
106
+ for (const s of plan.services) {
107
+ for (const c of s.volumeChanges)
108
+ reporter.info(`${s.slug} media: ${c}`);
109
+ for (const f of s.resourceFlags) {
110
+ reporter.info(`${s.slug} resources: ${s.liveMemory ?? "(default)"} → ${f}`);
111
+ }
112
+ for (const c of s.envChanges) {
113
+ reporter.info(`${s.slug} env ${c.name}: ${c.from === undefined ? "(unset)" : c.from} → ${c.to === undefined ? "(removed)" : c.to}`);
114
+ }
115
+ }
116
+ }
117
+ /** Run the app-roll. See the file comment for the sequence. */
118
+ export async function executeAppRoll(input, hooks, deps) {
119
+ const { reporter: r, run } = deps;
120
+ const { install } = input.plan;
121
+ let plan = input.plan;
122
+ const fail = (phase, migrated) => ({
123
+ ok: false,
124
+ phase,
125
+ migrated,
126
+ });
127
+ // A probe that cannot reach the install now would only fail after the
128
+ // migrations, and roll a healthy release back.
129
+ if (deps.health) {
130
+ const s = r.step("Checking the health check can reach admin + gateway...");
131
+ const base = await deps.health.baseline().catch((e) => ({
132
+ ok: false,
133
+ error: e instanceof Error ? e.message : String(e),
134
+ }));
135
+ if (!base.ok) {
136
+ s.failed(`Health check can't reach the install: ${base.error}`);
137
+ r.warn("No migrations ran and no traffic moved. Fix the access problem, or re-run with --skip-health-check to roll with Cloud Run's readiness check only.");
138
+ return fail("health-baseline", false);
139
+ }
140
+ s.done(`Health check reaches the install (${base.detail})`);
141
+ }
142
+ else {
143
+ r.warn("--skip-health-check set — the new revisions get Cloud Run's readiness check only.");
144
+ }
145
+ // Migrations BEFORE any traffic moves, with the NEW admin image: the old
146
+ // image does not carry the release's migration files (v0.9.2).
147
+ const admin = plan.services.find((s) => s.slug === "admin");
148
+ const sMig = r.step("Applying DB migrations (idempotent)...");
149
+ const mig = await deps.migrate(admin.imageRef);
150
+ if (!mig.ok) {
151
+ sMig.failed(`Migrations failed (${mig.error ?? "unknown"}). Aborting upgrade.`);
152
+ r.warn(`No traffic was shifted. Inspect the Cloud Run Job logs:\n gcloud logging read 'resource.type=cloud_run_job AND resource.labels.job_name=~"caelo-migrate-.*"' --project=${install.projectId} --limit=50\n${restoreHint(input, "if a migration left the schema half-applied")}`);
153
+ return fail("migrations", true);
154
+ }
155
+ sMig.done("Migrations applied");
156
+ if (hooks.afterMigrations) {
157
+ const converged = await hooks.afterMigrations();
158
+ if (!converged.ok)
159
+ return fail("converge", true);
160
+ plan = leavingEnvUntouched(plan, converged.leaveUntouched);
161
+ }
162
+ const rolled = [];
163
+ const rollBack = async (alsoCurrent) => {
164
+ const services = alsoCurrent ? [...rolled, alsoCurrent] : rolled;
165
+ if (services.length === 0)
166
+ return;
167
+ r.warn(`Rolling back ${services.length} service(s) to the revisions that served before...`);
168
+ for (const p of [...services].reverse()) {
169
+ const ok = await pinTraffic(run, install.projectId, install.region, p.serviceName, p.priorRevision);
170
+ if (ok)
171
+ r.info(` ${p.slug} traffic restored to ${p.priorRevision}`);
172
+ else
173
+ r.error(` ${p.slug} rollback FAILED — pin ${p.priorRevision} by hand`);
174
+ await hooks.afterRollback?.(p.slug);
175
+ }
176
+ };
177
+ for (const p of plan.services) {
178
+ const s = r.step(`Rolling ${p.slug} → ${p.digest.slice(0, 19)}...`);
179
+ const before = (await hooks.beforeRoll?.(p.slug)) ?? { ok: true };
180
+ if (!before.ok) {
181
+ s.failed(before.error);
182
+ await rollBack();
183
+ return fail("roll", true);
184
+ }
185
+ const upd = await rollService(serviceRollArgs({
186
+ serviceName: p.serviceName,
187
+ region: install.region,
188
+ projectId: install.projectId,
189
+ imageRef: p.imageRef,
190
+ serviceAccount: p.slug === "admin"
191
+ ? runServiceAccountEmail(install.projectId, install.env)
192
+ : gatewayServiceAccountEmail(install.projectId, install.env),
193
+ envFlags: p.envFlags,
194
+ resourceFlags: p.resourceFlags,
195
+ volumeFlags: p.volumeFlags,
196
+ }), { run, ...(deps.sleep ? { sleep: deps.sleep } : {}) });
197
+ if (!upd.ok) {
198
+ s.failed(`Failed: ${upd.stderr.trim()}`);
199
+ // The failed update created no serving revision; only undo what the
200
+ // hook changed for it, then the services that rolled before.
201
+ await hooks.afterRollback?.(p.slug);
202
+ await rollBack();
203
+ return fail("roll", true);
204
+ }
205
+ // `update --image` only moves traffic when the service has no explicit
206
+ // traffic config — but a rollback pins traffic to the prior revision,
207
+ // and that pin survives later updates. Moving traffic to latest on
208
+ // every roll is idempotent and un-pins services an earlier failed
209
+ // upgrade left pinned.
210
+ const flip = await run([
211
+ "run",
212
+ "services",
213
+ "update-traffic",
214
+ p.serviceName,
215
+ "--region",
216
+ install.region,
217
+ "--project",
218
+ install.projectId,
219
+ "--to-latest",
220
+ "--quiet",
221
+ ]);
222
+ if (!flip.ok) {
223
+ s.failed(`Traffic flip to latest failed: ${flip.stderr.trim()}`);
224
+ await rollBack(p);
225
+ return fail("roll", true);
226
+ }
227
+ if (!(await findServiceUrl(run, install.projectId, install.region, p.serviceName))) {
228
+ s.failed(`Could not resolve the service URL for ${p.slug} — rolling back`);
229
+ await rollBack(p);
230
+ return fail("roll", true);
231
+ }
232
+ s.done(`${p.slug} rolled to ${p.digest.slice(0, 19)}...`);
233
+ rolled.push(p);
234
+ }
235
+ if (deps.health) {
236
+ const s = r.step("Deep health check (database, migrations, version)...");
237
+ // A probe that throws is a failed check: roll back, never leave the
238
+ // new revisions serving unverified.
239
+ const deep = await deps.health.deep({ version: input.targetVersion }).catch((e) => ({
240
+ ok: false,
241
+ error: e instanceof Error ? e.message : String(e),
242
+ }));
243
+ if (!deep.ok) {
244
+ s.failed(`Deep health check failed: ${deep.error}`);
245
+ await rollBack();
246
+ r.warn(restoreHint(input, "if the previous release now fails against the migrated schema"));
247
+ return fail("health", true);
248
+ }
249
+ s.done(`Healthy: ${deep.detail}`);
250
+ }
251
+ const digests = {
252
+ admin: plan.services.find((s) => s.slug === "admin").digest,
253
+ gateway: plan.services.find((s) => s.slug === "gateway").digest,
254
+ };
255
+ await deps.recordDigests(digests);
256
+ return { ok: true, digests };
257
+ }
258
+ /**
259
+ * The restore hint after migrations ran and the roll failed. Expand-only
260
+ * migrations leave a schema the previous release still runs on, so restoring
261
+ * is only advised outright for contract-type migrations.
262
+ */
263
+ function restoreHint(input, when) {
264
+ const cmd = restoreCommand(input.backup);
265
+ if (input.migrationsContract === true) {
266
+ return `This release's migrations are contract-type: the previous release may not work against the migrated schema. Restore the pre-upgrade backup ${input.backup.backupId} (overwrites all data written since):\n ${cmd}`;
267
+ }
268
+ return `Pre-upgrade backup: ${input.backup.backupId}. Restore it only ${when} (overwrites all data written since):\n ${cmd}`;
269
+ }
270
+ //# sourceMappingURL=app-roll.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-roll.js","sourceRoot":"","sources":["../../src/upgrade/app-roll.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * On-demand Cloud SQL backups (epic #696): the `backup` lifecycle command and
3
+ * the backup every upgrade takes before its migrations. Both GCP providers
4
+ * (`gcp`, `gcp-firebase`) keep their data in the same `caelo-<env>-pg*` Cloud
5
+ * SQL instance, so one implementation serves both.
6
+ *
7
+ * The backup id is what makes the pre-upgrade backup useful: it lands in the
8
+ * upgrade's output and in the restore hint printed when the upgrade has to
9
+ * roll back after migrations ran.
10
+ */
11
+ import type { GcloudRunner } from "../gcloud-retry.js";
12
+ /** A finished on-demand backup. */
13
+ export interface SqlBackup {
14
+ readonly projectId: string;
15
+ /** Cloud SQL instance name (Pulumi-suffixed). */
16
+ readonly instance: string;
17
+ /** Cloud SQL backup run id. */
18
+ readonly backupId: string;
19
+ }
20
+ export type SqlBackupResult = {
21
+ readonly ok: true;
22
+ readonly backup: SqlBackup;
23
+ } | {
24
+ readonly ok: false;
25
+ readonly error: string;
26
+ };
27
+ /**
28
+ * Take an on-demand backup of the install's Cloud SQL instance and return its
29
+ * id. `gcloud sql backups create` waits for the backup to finish but does not
30
+ * print the id in a stable shape, so the backup carries a unique description
31
+ * and is looked up by it afterwards.
32
+ *
33
+ * @param purpose short reason recorded in the backup's description, e.g. "pre-upgrade to 0.11.0"
34
+ */
35
+ export declare function takeSqlBackup(run: GcloudRunner, install: {
36
+ readonly projectId: string;
37
+ readonly env: string;
38
+ }, purpose: string, now?: () => Date): Promise<SqlBackupResult>;
39
+ /** The command that restores `backup` over its instance (overwrites the current data). */
40
+ export declare function restoreCommand(backup: SqlBackup): string;
41
+ /**
42
+ * What to tell the operator when a pre-upgrade backup failed: why nothing
43
+ * happened, and how to get past it.
44
+ */
45
+ export declare function backupFailureHelp(install: {
46
+ readonly projectId: string;
47
+ }): string;
48
+ //# sourceMappingURL=backup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup.d.ts","sourceRoot":"","sources":["../../src/upgrade/backup.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIvD,mCAAmC;AACnC,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,+BAA+B;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GACjD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnD;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,YAAY,EACjB,OAAO,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAC7D,OAAO,EAAE,MAAM,EACf,GAAG,GAAE,MAAM,IAAuB,GACjC,OAAO,CAAC,eAAe,CAAC,CA8C1B;AAED,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAExD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAQjF"}
@@ -0,0 +1,71 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ import { gcpNamePrefix } from "../gcp-names.js";
3
+ import { resolveGcpResourceName } from "./gcp-lookup.js";
4
+ /**
5
+ * Take an on-demand backup of the install's Cloud SQL instance and return its
6
+ * id. `gcloud sql backups create` waits for the backup to finish but does not
7
+ * print the id in a stable shape, so the backup carries a unique description
8
+ * and is looked up by it afterwards.
9
+ *
10
+ * @param purpose short reason recorded in the backup's description, e.g. "pre-upgrade to 0.11.0"
11
+ */
12
+ export async function takeSqlBackup(run, install, purpose, now = () => new Date()) {
13
+ const instance = await resolveGcpResourceName(run, "sql-instance", `${gcpNamePrefix(install.env)}-pg`, install.projectId);
14
+ if (!instance) {
15
+ return {
16
+ ok: false,
17
+ error: `no ${gcpNamePrefix(install.env)}-pg* Cloud SQL instance in project ${install.projectId} (or listing it was denied)`,
18
+ };
19
+ }
20
+ const description = `caelo-cms ${purpose} ${now().toISOString()}`;
21
+ const project = ["--project", install.projectId];
22
+ const create = await run([
23
+ "sql",
24
+ "backups",
25
+ "create",
26
+ "--instance",
27
+ instance,
28
+ ...project,
29
+ "--description",
30
+ description,
31
+ ]);
32
+ if (!create.ok) {
33
+ return { ok: false, error: `backup of ${instance} failed: ${create.stderr.trim()}` };
34
+ }
35
+ const list = await run([
36
+ "sql",
37
+ "backups",
38
+ "list",
39
+ "--instance",
40
+ instance,
41
+ ...project,
42
+ `--filter=description="${description}"`,
43
+ "--format=value(id)",
44
+ ]);
45
+ const backupId = list.ok ? list.stdout.trim().split("\n")[0]?.trim() : "";
46
+ if (!backupId) {
47
+ return {
48
+ ok: false,
49
+ error: `backup of ${instance} was created but its id could not be read (${list.ok ? "no backup carries the description" : list.stderr.trim()}); find it with: gcloud sql backups list --instance=${instance} --project=${install.projectId}`,
50
+ };
51
+ }
52
+ return { ok: true, backup: { projectId: install.projectId, instance, backupId } };
53
+ }
54
+ /** The command that restores `backup` over its instance (overwrites the current data). */
55
+ export function restoreCommand(backup) {
56
+ return `gcloud sql backups restore ${backup.backupId} --restore-instance=${backup.instance} --project=${backup.projectId}`;
57
+ }
58
+ /**
59
+ * What to tell the operator when a pre-upgrade backup failed: why nothing
60
+ * happened, and how to get past it.
61
+ */
62
+ export function backupFailureHelp(install) {
63
+ return [
64
+ "Nothing was changed: no migrations ran and no traffic moved.",
65
+ "Fix the cause and re-run upgrade. Common causes:",
66
+ ` - the account lacks Cloud SQL backup rights (roles/cloudsql.editor or owner on ${install.projectId})`,
67
+ " - another backup or maintenance operation is running on the instance (wait, then retry)",
68
+ ` - the instance is stopped: gcloud sql instances describe <instance> --project=${install.projectId}`,
69
+ ].join("\n");
70
+ }
71
+ //# sourceMappingURL=backup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup.js","sourceRoot":"","sources":["../../src/upgrade/backup.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAcnC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAezD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAiB,EACjB,OAA6D,EAC7D,OAAe,EACf,MAAkB,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE;IAElC,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAC3C,GAAG,EACH,cAAc,EACd,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAClC,OAAO,CAAC,SAAS,CAClB,CAAC;IACF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,MAAM,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,sCAAsC,OAAO,CAAC,SAAS,6BAA6B;SAC5H,CAAC;IACJ,CAAC;IACD,MAAM,WAAW,GAAG,aAAa,OAAO,IAAI,GAAG,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IAClE,MAAM,OAAO,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC;QACvB,KAAK;QACL,SAAS;QACT,QAAQ;QACR,YAAY;QACZ,QAAQ;QACR,GAAG,OAAO;QACV,eAAe;QACf,WAAW;KACZ,CAAC,CAAC;IACH,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,QAAQ,YAAY,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC;IACvF,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC;QACrB,KAAK;QACL,SAAS;QACT,MAAM;QACN,YAAY;QACZ,QAAQ;QACR,GAAG,OAAO;QACV,yBAAyB,WAAW,GAAG;QACvC,oBAAoB;KACrB,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,aAAa,QAAQ,8CAA8C,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,uDAAuD,QAAQ,cAAc,OAAO,CAAC,SAAS,EAAE;SAC7O,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,CAAC;AACpF,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,cAAc,CAAC,MAAiB;IAC9C,OAAO,8BAA8B,MAAM,CAAC,QAAQ,uBAAuB,MAAM,CAAC,QAAQ,cAAc,MAAM,CAAC,SAAS,EAAE,CAAC;AAC7H,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAuC;IACvE,OAAO;QACL,8DAA8D;QAC9D,kDAAkD;QAClD,oFAAoF,OAAO,CAAC,SAAS,GAAG;QACxG,2FAA2F;QAC3F,mFAAmF,OAAO,CAAC,SAAS,EAAE;KACvG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
@@ -0,0 +1,45 @@
1
+ import type { GcloudRunner, Sleep } from "../gcloud-retry.js";
2
+ import type { InstallMetadata } from "../install-state.js";
3
+ import { type HttpFetch } from "../runtime-secrets.js";
4
+ import type { AppRollHooks, AppRollPlan } from "./app-roll.js";
5
+ import type { UpgradeReporter } from "./reporter.js";
6
+ /**
7
+ * Whether the install must converge before an app-roll to a release that
8
+ * expects infrastructure contract `targetVersion` (infra-contract.ts). An
9
+ * install with no recorded version has never completed a converge under
10
+ * this scheme and always needs one.
11
+ */
12
+ export declare function needsConverge(install: Pick<InstallMetadata, "infraContractVersion">, targetVersion: number): boolean;
13
+ export interface ConvergeDeps {
14
+ readonly run: GcloudRunner;
15
+ readonly sleep?: Sleep;
16
+ /** Cloud SQL Admin API calls (database role passwords). */
17
+ readonly http?: HttpFetch;
18
+ readonly reporter: UpgradeReporter;
19
+ /**
20
+ * The operator's own identity step, run first: the CLI moves the
21
+ * provisioner SA to keyless impersonation (provisioner-identity.ts), which
22
+ * needs the operator's gcloud account and local install dir. False aborts.
23
+ */
24
+ readonly provisionerIdentity?: () => Promise<boolean>;
25
+ }
26
+ export interface ConvergeSession {
27
+ /**
28
+ * Before the app-roll: runtime identities + secrets, stack invariants, MCP
29
+ * access. False when a step the install cannot work without failed —
30
+ * nothing app-side changed then.
31
+ */
32
+ beforeAppRoll(): Promise<boolean>;
33
+ /** The steps the app-roll runs between its own. */
34
+ readonly hooks: AppRollHooks;
35
+ /** After a successful app-roll: retire bindings nothing reads any more. */
36
+ afterAppRoll(): Promise<void>;
37
+ /**
38
+ * Whether every converge step succeeded — only then may the install's
39
+ * infrastructure contract version be recorded.
40
+ */
41
+ complete(): boolean;
42
+ }
43
+ /** Start a converge for the install `plan` rolls. */
44
+ export declare function startConverge(plan: AppRollPlan, ownerEmail: string, deps: ConvergeDeps): ConvergeSession;
45
+ //# sourceMappingURL=converge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converge.d.ts","sourceRoot":"","sources":["../../src/upgrade/converge.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,EAGL,KAAK,SAAS,EAGf,MAAM,uBAAuB,CAAC;AAQ/B,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAsB,MAAM,eAAe,CAAC;AACnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE,sBAAsB,CAAC,EACtD,aAAa,EAAE,MAAM,GACpB,OAAO,CAET;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,2EAA2E;IAC3E,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B;;;OAGG;IACH,QAAQ,IAAI,OAAO,CAAC;CACrB;AAED,qDAAqD;AACrD,wBAAgB,aAAa,CAC3B,IAAI,EAAE,WAAW,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,YAAY,GACjB,eAAe,CAmQjB"}