@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,28 @@
1
+ import { type GcloudRunner, type Sleep } from "./gcloud-retry.js";
2
+ export type AdcCheck = {
3
+ readonly ok: true;
4
+ } | {
5
+ readonly ok: false;
6
+ /** `no-adc`: no Application Default Credentials; `denied`: they can't impersonate. */
7
+ readonly reason: "no-adc" | "denied" | "error";
8
+ readonly error: string;
9
+ };
10
+ /**
11
+ * Verify the credential chain Pulumi will use: the operator's Application
12
+ * Default Credentials exist and may mint a token for the provisioner. Run
13
+ * before `pulumi up` so a missing login or grant fails here with the fix,
14
+ * not halfway through the stack. `freshGrant` waits out IAM propagation
15
+ * (a new binding can take minutes to apply). Both tokens stay in this
16
+ * function: neither is printed nor kept.
17
+ */
18
+ export declare function checkAdcImpersonation(target: {
19
+ readonly projectId: string;
20
+ readonly operatorAccount: string;
21
+ freshGrant: boolean;
22
+ }, deps?: {
23
+ run?: GcloudRunner;
24
+ sleep?: Sleep;
25
+ fetch?: typeof fetch;
26
+ env?: NodeJS.ProcessEnv;
27
+ }): Promise<AdcCheck>;
28
+ //# sourceMappingURL=adc-impersonation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adc-impersonation.d.ts","sourceRoot":"","sources":["../src/adc-impersonation.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,KAAK,YAAY,EAAa,KAAK,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAa7E,MAAM,MAAM,QAAQ,GAChB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAA;CAAE,GACrB;IACE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,sFAAsF;IACtF,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAEN;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,EAC7F,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,YAAY,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAO,GAC9F,OAAO,CAAC,QAAQ,CAAC,CAqGnB"}
@@ -0,0 +1,148 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * Pre-flight for the keyless provisioner's credential chain (#696): before
4
+ * `pulumi up`, verify that the operator's Application Default Credentials
5
+ * exist and may mint a token for `caelo-provisioner` — the exact chain
6
+ * Pulumi's GCP provider uses (wizards/gcp-pulumi.ts `pulumiGcpEnv`). A
7
+ * missing login or grant then fails here with the fix, not halfway through
8
+ * the stack. See provisioner-identity.ts for the design.
9
+ *
10
+ * Both access tokens involved (the ADC source token and the minted one)
11
+ * stay in local variables: never printed, logged, returned or written.
12
+ */
13
+ import { gcloud as defaultGcloud } from "./gcloud.js";
14
+ import { realSleep } from "./gcloud-retry.js";
15
+ import { operatorMember, PROPAGATION_DELAYS_MS, provisionerServiceAccountEmail, TOKEN_CREATOR_ROLE, withoutAmbientGoogleCredentials, } from "./provisioner-identity.js";
16
+ /** A user-managed service account's email, as IAM reports it. */
17
+ const SERVICE_ACCOUNT_EMAIL = /^[a-z][a-z0-9-]{4,28}[a-z0-9]@[a-z][a-z0-9.:-]*[a-z0-9]\.iam\.gserviceaccount\.com$/;
18
+ /**
19
+ * Verify the credential chain Pulumi will use: the operator's Application
20
+ * Default Credentials exist and may mint a token for the provisioner. Run
21
+ * before `pulumi up` so a missing login or grant fails here with the fix,
22
+ * not halfway through the stack. `freshGrant` waits out IAM propagation
23
+ * (a new binding can take minutes to apply). Both tokens stay in this
24
+ * function: neither is printed nor kept.
25
+ */
26
+ export async function checkAdcImpersonation(target, deps = {}) {
27
+ const run = deps.run ?? defaultGcloud;
28
+ const sleep = deps.sleep ?? realSleep;
29
+ const doFetch = deps.fetch ?? fetch;
30
+ const sa = provisionerServiceAccountEmail(target.projectId);
31
+ const env = withoutAmbientGoogleCredentials(deps.env ?? process.env);
32
+ const adc = await run(["auth", "application-default", "print-access-token"], { env });
33
+ const sourceToken = adc.ok ? adc.stdout.trim() : "";
34
+ if (!sourceToken) {
35
+ return {
36
+ ok: false,
37
+ reason: "no-adc",
38
+ error: [
39
+ "No Application Default Credentials on this machine.",
40
+ `Infrastructure runs authenticate with your own Google login and impersonate ${sa}; no key file is used.`,
41
+ `Run \`gcloud auth application-default login\` (sign in as ${target.operatorAccount}), then re-run.`,
42
+ ].join("\n"),
43
+ };
44
+ }
45
+ // The account to impersonate is the one IAM reports, not a string
46
+ // assembled from install.json: what goes into the request is an email
47
+ // Google confirmed exists in the project (CodeQL js/file-access-to-http:
48
+ // local file data never reaches the network unchecked).
49
+ const described = await run([
50
+ "iam",
51
+ "service-accounts",
52
+ "describe",
53
+ sa,
54
+ `--project=${target.projectId}`,
55
+ "--format=value(email)",
56
+ ], { env });
57
+ const confirmed = described.ok ? described.stdout.trim().toLowerCase() : "";
58
+ if (!SERVICE_ACCOUNT_EMAIL.test(confirmed) || confirmed !== sa.toLowerCase()) {
59
+ return {
60
+ ok: false,
61
+ reason: "error",
62
+ error: `Could not find ${sa} in project ${target.projectId}${described.ok ? "" : `: ${described.stderr.trim().split("\n").slice(-1)[0] ?? ""}`}. Re-run the installer so it creates the provisioner service account.`,
63
+ };
64
+ }
65
+ const delays = target.freshGrant ? PROPAGATION_DELAYS_MS : [];
66
+ let status = 0;
67
+ let detail = "";
68
+ for (let attempt = 0;; attempt++) {
69
+ try {
70
+ const res = await doFetch(`https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${encodeURIComponent(confirmed)}:generateAccessToken`, {
71
+ method: "POST",
72
+ headers: {
73
+ authorization: `Bearer ${sourceToken}`,
74
+ "content-type": "application/json",
75
+ },
76
+ body: JSON.stringify({
77
+ scope: ["https://www.googleapis.com/auth/cloud-platform"],
78
+ lifetime: "300s",
79
+ }),
80
+ });
81
+ status = res.status;
82
+ // Drain the body without keeping the minted token; only the error text matters.
83
+ const text = await res.text();
84
+ if (res.ok)
85
+ return { ok: true };
86
+ detail = errorMessage(text);
87
+ }
88
+ catch (e) {
89
+ return {
90
+ ok: false,
91
+ reason: "error",
92
+ error: `Could not reach the IAM Credentials API: ${e instanceof Error ? e.message : String(e)}`,
93
+ };
94
+ }
95
+ const delay = delays[attempt];
96
+ if (status !== 403 || delay === undefined)
97
+ break;
98
+ await sleep(delay);
99
+ }
100
+ if (status !== 403) {
101
+ return {
102
+ ok: false,
103
+ reason: "error",
104
+ error: `Impersonating ${sa} failed (HTTP ${status}): ${detail}`,
105
+ };
106
+ }
107
+ const adcAccount = await tokenAccount(doFetch, sourceToken);
108
+ const mismatch = adcAccount && adcAccount.toLowerCase() !== target.operatorAccount.trim().toLowerCase();
109
+ return {
110
+ ok: false,
111
+ reason: "denied",
112
+ error: [
113
+ `Your Application Default Credentials${adcAccount ? ` (${adcAccount})` : ""} may not impersonate ${sa}: ${detail}`,
114
+ mismatch
115
+ ? `They belong to another account than gcloud (${target.operatorAccount}), which holds ${TOKEN_CREATOR_ROLE} on it. Run \`gcloud auth application-default login\` as ${target.operatorAccount}, then re-run.`
116
+ : `The account needs ${TOKEN_CREATOR_ROLE} on ${sa}. A grant made moments ago can take a few minutes to apply: wait, then re-run. Otherwise ask a project Owner to run:\n gcloud iam service-accounts add-iam-policy-binding ${sa} --project=${target.projectId} --member=${operatorMember(adcAccount || target.operatorAccount)} --role=${TOKEN_CREATOR_ROLE} --condition=None`,
117
+ ].join("\n"),
118
+ };
119
+ }
120
+ function errorMessage(body) {
121
+ try {
122
+ const parsed = JSON.parse(body);
123
+ if (parsed.error?.message)
124
+ return parsed.error.message;
125
+ }
126
+ catch {
127
+ // not JSON — fall through to the raw text
128
+ }
129
+ return body.trim().slice(0, 300) || "(no body)";
130
+ }
131
+ /** The email an access token belongs to (Google's tokeninfo), or "" when unknown. */
132
+ async function tokenAccount(doFetch, accessToken) {
133
+ try {
134
+ const res = await doFetch("https://oauth2.googleapis.com/tokeninfo", {
135
+ method: "POST",
136
+ headers: { "content-type": "application/x-www-form-urlencoded" },
137
+ body: new URLSearchParams({ access_token: accessToken }).toString(),
138
+ });
139
+ if (!res.ok)
140
+ return "";
141
+ const info = (await res.json());
142
+ return typeof info.email === "string" ? info.email : "";
143
+ }
144
+ catch {
145
+ return "";
146
+ }
147
+ }
148
+ //# sourceMappingURL=adc-impersonation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adc-impersonation.js","sourceRoot":"","sources":["../src/adc-impersonation.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"checkpoint-secrets.d.ts","sourceRoot":"","sources":["../src/checkpoint-secrets.ts"],"names":[],"mappings":"AA4BA,qFAAqF;AACrF,MAAM,WAAW,aAAa;IAC5B,mGAAmG;IACnG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,gBAAgB,GAAG,WAAW,GAAG,YAAY,CAAC;IAC7D,gEAAgE;IAChE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AA2CD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,SAAK,GAAG,aAAa,EAAE,CAetE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAElE;AAED,0FAA0F;AAC1F,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAEjF;AAcD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,OAAO,GAAG,aAAa,EAAE,CAO1E;AAcD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAgBtD;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC,GACtE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzB;AAED,4CAA4C;AAC5C,MAAM,WAAW,WAAW;IAC1B,+FAA+F;IAC/F,QAAQ,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;CAC5C;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAO3D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CASlE;AAID;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAuB5F;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD"}
1
+ {"version":3,"file":"checkpoint-secrets.d.ts","sourceRoot":"","sources":["../src/checkpoint-secrets.ts"],"names":[],"mappings":"AA6BA,qFAAqF;AACrF,MAAM,WAAW,aAAa;IAC5B,mGAAmG;IACnG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,gBAAgB,GAAG,WAAW,GAAG,YAAY,CAAC;IAC7D,gEAAgE;IAChE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AA2CD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,SAAK,GAAG,aAAa,EAAE,CAetE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAElE;AAED,0FAA0F;AAC1F,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAEjF;AAcD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,OAAO,GAAG,aAAa,EAAE,CAO1E;AAcD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAgBtD;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC,GACtE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzB;AAED,4CAA4C;AAC5C,MAAM,WAAW,WAAW;IAC1B,+FAA+F;IAC/F,QAAQ,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;CAC5C;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAO3D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CASlE;AAID;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAsB5F;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD"}
@@ -22,6 +22,7 @@
22
22
  * future secret output is caught without being listed here.
23
23
  */
24
24
  import { existsSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
25
+ import { selfCommand } from "./self-command.js";
25
26
  import { DATABASE_ROLE_SECRET } from "./stack-contract.js";
26
27
  /** `scheme://user:password@` — the user-info of a URL that carries a password. */
27
28
  const CREDENTIAL_URL = /[a-z][a-z0-9+.-]{0,31}:\/\/([^\s:@/]*):([^\s@/]+)@/gi;
@@ -216,7 +217,7 @@ const ROLE_BY_USER = DATABASE_ROLE_SECRET;
216
217
  * @param installId the install, named in each command so it acts on the right one
217
218
  */
218
219
  export function rotationHints(removed, installId) {
219
- const rotate = (secret) => `bunx @caelo-cms/provisioning rotate-secret ${secret} --install ${installId}`;
220
+ const rotate = (secret) => selfCommand("rotate-secret", secret, "--install", installId);
220
221
  const hints = new Set();
221
222
  for (const f of removed) {
222
223
  if (f.kind === "credential-url") {
@@ -1 +1 @@
1
- {"version":3,"file":"checkpoint-secrets.js","sourceRoot":"","sources":["../src/checkpoint-secrets.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"checkpoint-secrets.js","sourceRoot":"","sources":["../src/checkpoint-secrets.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtF,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAqB,MAAM,qBAAqB,CAAC;AAgB9E,kFAAkF;AAClF,MAAM,cAAc,GAAG,sDAAsD,CAAC;AAE9E,0FAA0F;AAC1F,MAAM,WAAW,GACf,6FAA6F,CAAC;AAEhG;;;;GAIG;AACH,MAAM,UAAU,GAAG,4EAA4E,CAAC;AAEhG,SAAS,WAAW,CAAC,GAAW;IAC9B,MAAM,CAAC,GAAG,GAAG;SACV,WAAW,EAAE;SACb,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;SACzB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACvB,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC5B,CAAC;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,IAAI,CAAC;QACH,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,KAAa,EAAE,IAAY;IACjD,MAAM,KAAK,GAAoB,EAAE,CAAC;IAClC,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QAC/C,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACzE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,KAAc,EAAE,IAAI,GAAG,EAAE;IACnD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,cAAc,CAAC,KAAK,EAAE,IAAI,IAAI,SAAS,CAAC,CAAC;IAC/E,MAAM,IAAI,GAAG,CAAC,CAAkB,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACzE,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClF,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE;YAC9C,kEAAkE;YAClE,kDAAkD;YAClD,IAAI,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,EAAE,IAAI,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC1F,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,YAAqB,EAAE,CAAC,CAAC;YAC1D,CAAC;YACD,OAAO,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc,EAAE,IAAY;IAC1D,cAAc,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;AAC3C,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,yBAAyB,CAAC,UAAmB,EAAE,IAAY;IACzE,cAAc,CAAC,qBAAqB,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,cAAc,CAAC,KAA+B,EAAE,IAAY;IACnE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAC/B,MAAM,IAAI,KAAK,CACb,wCAAwC,IAAI,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;QACvG,sHAAsH,CACzH,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAO,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,UAAmB;IACvD,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,WAAW,CAAC,UAAU,CAAC,CAAC;IAC1D,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,UAAU,CAAC;IACtC,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC;QAC7B,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC;QAC3F,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,wFAAwF;AACxF,SAAS,wBAAwB,CAAC,UAAmB;IACnD,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,cAAc,CAAC,UAAU,CAAC,CAAC;IAC7D,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,UAAU,CAAC;IACtC,OAAO;QACL,GAAI,cAAc,CAAC,IAAI,CAA6B;QACpD,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC;YACpB,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACnF,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC;KAC1B,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK;aACT,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;aACnE,GAAG,CAAC,cAAc,CAAC,CAAC;IACzB,CAAC;IACD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3C,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,CAAC;gBAAE,SAAS;YAC9F,GAAG,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAAuE;IAEvE,MAAM,IAAI,GAA4B,EAAE,CAAC;IACzC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC,CAAC,MAAM;YAAE,SAAS;QACvB,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QACvD,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;IACpB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAQD;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC9C,MAAM,UAAU,GAAY,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IACnE,MAAM,OAAO,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAClD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,CAAC;IAC7C,eAAe,CAAC,IAAI,EAAE,wBAAwB,CAAC,UAAU,CAAC,CAAC,CAAC;IAC5D,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,KAAc;IAC1D,MAAM,GAAG,GAAG,GAAG,IAAI,QAAQ,OAAO,CAAC,GAAG,EAAE,CAAC;IACzC,IAAI,CAAC;QACH,aAAa,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3E,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACxB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7B,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC;AAED,MAAM,YAAY,GAAG,oBAAoE,CAAC;AAE1F;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,OAAiC,EAAE,SAAiB;IAChF,MAAM,MAAM,GAAG,CAAC,MAAc,EAAE,EAAE,CAAC,WAAW,CAAC,eAAe,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;IAChG,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;YAChC,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAoB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACzE,KAAK,CAAC,GAAG,CACP,MAAM;gBACJ,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,uDAAuD,MAAM,CAAC,MAAM,CAAC,EAAE;gBAClF,CAAC,CAAC,iCAAiC,CAAC,CAAC,IAAI,IAAI,GAAG,kCAAkC,CAAC,CAAC,IAAI,eAAe,CAC1G,CAAC;QACJ,CAAC;aAAM,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAClC,KAAK,CAAC,GAAG,CACP,yLAAyL,CAC1L,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,GAAG,CACP,+CAA+C,CAAC,CAAC,IAAI,mCAAmC,CACzF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,IAAI,CAAC,OAAO,CAAC,oDAAoD,EAAE,SAAS,CAAC,CAAC;AACvF,CAAC"}
package/dist/cli.js CHANGED
@@ -5,10 +5,16 @@
5
5
  *
6
6
  * Sub-commands:
7
7
  * init [--domain D --owner-email E] — first-time setup; generates
8
- * secrets, writes .caelo/, runs
9
- * `docker compose up -d`, prints
10
- * the bootstrap token URL.
8
+ * secrets, resolves + cosign-verifies
9
+ * the release images, writes .caelo/,
10
+ * prints the start steps + the
11
+ * bootstrap token URL. `--dev` runs a
12
+ * Caelo checkout instead (contributors).
11
13
  * up — re-runs against existing config.
14
+ * migrate — applies DB migrations with the
15
+ * admin image the install runs.
16
+ * upgrade [--version X] — verified, backed-up, health-checked
17
+ * image roll with rollback.
12
18
  * regenerate-caddy — re-emits Caddyfile from the
13
19
  * domains table; runs `caddy reload`.
14
20
  * backup --to <path> — pgBackRest full + MinIO mirror →
@@ -22,19 +28,38 @@
22
28
  */
23
29
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
24
30
  import { resolve } from "node:path";
25
- import { defaultStagingHost, normalizeStagingHost, stagingHostProblem } from "@caelo-cms/shared";
31
+ import { CAELO_VERSION, defaultStagingHost, normalizeStagingHost, stagingHostProblem, } from "@caelo-cms/shared";
26
32
  import { generateBootstrapToken } from "./bootstrap-token.js";
27
33
  import { generateCaddyfile } from "./caddy.js";
28
34
  import { redactCredentials } from "./checkpoint-secrets.js";
29
35
  import { initDelegatesToWizard, resolveCliRoute } from "./cli-routing.js";
30
- import { generateDockerCompose } from "./compose.js";
36
+ import { BOOTSTRAP_DIR, generateDockerCompose, } from "./compose.js";
37
+ import { selfCommand } from "./self-command.js";
38
+ import { bunHostRunner, readRelease, recordRelease, releaseImages, resolveVerifiedRelease, } from "./self-hosted-release.js";
31
39
  import { convergeSelfHostedRoles, decideUp } from "./self-hosted-roles.js";
32
40
  const REPO_ROOT = resolve(import.meta.dir, "../../..");
33
- const CAELO_DIR = resolve(REPO_ROOT, ".caelo");
41
+ /**
42
+ * Whether this CLI runs from a Caelo source checkout (contributor) rather
43
+ * than from an installed package (`bunx @caelo-cms/provisioning` puts it in
44
+ * a package cache, where `../../..` is a `node_modules` dir).
45
+ */
46
+ const IN_REPO_CHECKOUT = existsSync(resolve(REPO_ROOT, "packages/provisioning/package.json")) &&
47
+ existsSync(resolve(REPO_ROOT, "bun.lock"));
48
+ /**
49
+ * The install's `.caelo/` dir: `$CAELO_SELF_HOSTED_DIR` when set; in a
50
+ * checkout the repo's own `.caelo/` (dev mode bind-mounts `../..` from it);
51
+ * otherwise `./.caelo` in the working directory — never inside a package
52
+ * cache, which `bunx` may wipe.
53
+ */
54
+ const CAELO_DIR = process.env.CAELO_SELF_HOSTED_DIR
55
+ ? resolve(process.env.CAELO_SELF_HOSTED_DIR)
56
+ : resolve(IN_REPO_CHECKOUT ? REPO_ROOT : process.cwd(), ".caelo");
34
57
  const CONFIG_PATH = resolve(CAELO_DIR, "config.json");
35
58
  const COMPOSE_PATH = resolve(CAELO_DIR, "docker-compose.yml");
36
59
  const CADDYFILE_PATH = resolve(CAELO_DIR, "Caddyfile");
37
- const PENDING_TOKEN_PATH = resolve(CAELO_DIR, "pending-token.json");
60
+ // The admin container mounts only `.caelo/bootstrap/` (compose.ts), never the
61
+ // secrets next to it, and consumes the token from there on first boot.
62
+ const PENDING_TOKEN_PATH = resolve(CAELO_DIR, BOOTSTRAP_DIR, "pending-token.json");
38
63
  // P15 — `cms-provision init --provider <name>` writes here so subsequent
39
64
  // commands route to the right Pulumi stack. Defaults to "self-hosted"
40
65
  // when missing (preserves the P14 path).
@@ -110,23 +135,7 @@ function emitConfig(cfg, extraDomains = []) {
110
135
  cfg.stagingDomain = defaultStagingHost(cfg.domain);
111
136
  saveConfig(cfg);
112
137
  }
113
- if (!cfg.rolePasswords) {
114
- // `init` sets them and `up` back-fills + applies them before calling here.
115
- throw new Error("config has no rolePasswords — run `cms-provision up`");
116
- }
117
- // Generate compose + Caddyfile from the canonical config.
118
- const compose = generateDockerCompose({
119
- domain: cfg.domain,
120
- postgresPassword: cfg.postgresPassword,
121
- rolePasswords: cfg.rolePasswords,
122
- minioRootUser: cfg.minioRootUser,
123
- minioRootPassword: cfg.minioRootPassword,
124
- caeloSecretKek: cfg.caeloSecretKek,
125
- anthropicApiKey: cfg.anthropicApiKey,
126
- resendApiKey: cfg.resendApiKey,
127
- diskSize: "20Gi",
128
- });
129
- writeFileSync(COMPOSE_PATH, compose);
138
+ writeFileSync(COMPOSE_PATH, renderCompose(cfg, installImages(cfg)), { mode: 0o600 });
130
139
  // Seed the install with the operator's primary domain plus a staging
131
140
  // sibling. Extra domains added via /settings/domains are appended by
132
141
  // regenerate-caddy when it queries the live domains table.
@@ -145,6 +154,44 @@ function emitConfig(cfg, extraDomains = []) {
145
154
  });
146
155
  writeFileSync(CADDYFILE_PATH, caddy);
147
156
  }
157
+ /** The Compose file for `cfg` running `images` (secrets come from config.json). */
158
+ function renderCompose(cfg, images) {
159
+ if (!cfg.rolePasswords) {
160
+ // `init` sets them and `up` back-fills + applies them before calling here.
161
+ throw new Error("config has no rolePasswords — run `cms-provision up`");
162
+ }
163
+ if (!cfg.caeloSecretKek)
164
+ throw new Error("config has no caeloSecretKek — run `cms-provision up`");
165
+ return generateDockerCompose({
166
+ domain: cfg.domain,
167
+ postgresPassword: cfg.postgresPassword,
168
+ rolePasswords: cfg.rolePasswords,
169
+ minioRootUser: cfg.minioRootUser,
170
+ minioRootPassword: cfg.minioRootPassword,
171
+ caeloSecretKek: cfg.caeloSecretKek,
172
+ anthropicApiKey: cfg.anthropicApiKey,
173
+ resendApiKey: cfg.resendApiKey,
174
+ diskSize: "20Gi",
175
+ images,
176
+ });
177
+ }
178
+ /**
179
+ * The admin + gateway images the install runs: the checkout in dev mode,
180
+ * else the digests recorded in release.json. An install with neither (made
181
+ * before #696, still running the repo bind mount) is moved to the prebuilt
182
+ * images by `upgrade` — no silent fallback to the bind mount.
183
+ */
184
+ function installImages(cfg) {
185
+ if (cfg.imageMode === "dev")
186
+ return { mode: "dev" };
187
+ const release = readRelease(CAELO_DIR);
188
+ if (!release) {
189
+ throw new Error(`${CAELO_DIR}/release.json records no release images. This install predates the prebuilt\n` +
190
+ `images (it ran the repo bind mount): run \`${selfCommand("upgrade")}\` to move it to the signed\n` +
191
+ 'release images. (A contributor checkout that wants the bind mount sets "imageMode": "dev" in config.json.)');
192
+ }
193
+ return releaseImages(release);
194
+ }
148
195
  function dedupeDomains(list) {
149
196
  // Two domain entries with the same (hostname, kind) collapse to the
150
197
  // first occurrence — the seed wins over operator additions on a
@@ -178,7 +225,7 @@ async function init() {
178
225
  return;
179
226
  }
180
227
  if (!domain || !ownerEmail) {
181
- console.error("Usage: cms-provision init [--provider self-hosted] --domain example.com [--staging-domain staging.example.com] --owner-email me@example.com\n" +
228
+ console.error("Usage: cms-provision init [--provider self-hosted] --domain example.com [--staging-domain staging.example.com] --owner-email me@example.com [--version x.y.z] [--skip-verify] [--dev]\n" +
182
229
  "Cloud providers (gcp | gcp-firebase | aws | azure) run the wizard: cms-provision --provider <name>");
183
230
  process.exit(2);
184
231
  }
@@ -197,6 +244,33 @@ async function init() {
197
244
  console.error(`--staging-domain: ${stagingProblem}`);
198
245
  process.exit(2);
199
246
  }
247
+ // #696 — the prebuilt release images, resolved to digests and
248
+ // cosign-verified BEFORE anything is written, so a failed check leaves no
249
+ // half-made install. `--dev` (contributors only) runs this checkout instead.
250
+ const dev = process.argv.includes("--dev");
251
+ if (dev && !IN_REPO_CHECKOUT) {
252
+ console.error("--dev runs the admin + gateway from a Caelo source checkout and only works from one\n" +
253
+ "(bun packages/provisioning/src/cli.ts init --dev …). End-user installs omit it.");
254
+ process.exit(2);
255
+ }
256
+ const version = (arg("version") ?? CAELO_VERSION).replace(/^v/, "");
257
+ const skipVerify = process.argv.includes("--skip-verify");
258
+ let images = { mode: "dev" };
259
+ if (!dev) {
260
+ console.log(`Resolving + verifying the Caelo ${version} release images …`);
261
+ const resolved = await resolveVerifiedRelease(version, {
262
+ runner: bunHostRunner,
263
+ skipVerify,
264
+ onProgress: (m) => console.log(` ${m}`),
265
+ });
266
+ if (!resolved.ok) {
267
+ console.error(resolved.error);
268
+ process.exit(1);
269
+ }
270
+ if (skipVerify)
271
+ console.warn("--skip-verify set — image signatures NOT verified.");
272
+ images = resolved.images;
273
+ }
200
274
  saveProvider(providerArg);
201
275
  const cfg = {
202
276
  domain,
@@ -211,8 +285,12 @@ async function init() {
211
285
  caeloSecretKek: randomSecret(32),
212
286
  anthropicApiKey: process.env.ANTHROPIC_API_KEY,
213
287
  resendApiKey: process.env.RESEND_API_KEY,
288
+ imageMode: dev ? "dev" : "release",
214
289
  };
215
290
  saveConfig(cfg);
291
+ if (images.mode === "release") {
292
+ recordRelease(CAELO_DIR, { version, images }, { from: null, to: version, outcome: "installed" });
293
+ }
216
294
  emitConfig(cfg);
217
295
  // Mint the bootstrap token and stage it for hooks.server.ts to insert
218
296
  // on first request. The CLI doesn't talk to Postgres directly because
@@ -220,7 +298,8 @@ async function init() {
220
298
  // first boot, calls owner_bootstrap_tokens.insert, then deletes the
221
299
  // staging file.
222
300
  const tok = generateBootstrapToken();
223
- writeFileSync(PENDING_TOKEN_PATH, JSON.stringify(tok, null, 2));
301
+ mkdirSync(resolve(CAELO_DIR, BOOTSTRAP_DIR), { recursive: true, mode: 0o700 });
302
+ writeFileSync(PENDING_TOKEN_PATH, JSON.stringify(tok, null, 2), { mode: 0o600 });
224
303
  // P15.1 — mint the shared HMAC secret for /api/internal/* endpoints.
225
304
  // Same secret is read by:
226
305
  // - admin app (process.env.CAELO_INTERNAL_SECRET),
@@ -236,10 +315,15 @@ async function init() {
236
315
  console.log(`Wrote ${CADDYFILE_PATH}`);
237
316
  console.log(`Wrote ${PENDING_TOKEN_PATH} (admin will insert on first boot)`);
238
317
  console.log("");
318
+ console.log(images.mode === "release"
319
+ ? `Images: Caelo ${version}, pinned by digest (${images.admin.split("@")[1]?.slice(0, 19)}…)`
320
+ : "Images: DEV MODE — admin + gateway run this checkout (contributors only).");
321
+ console.log("");
239
322
  console.log("Next steps:");
240
- console.log(` cd ${CAELO_DIR}`);
241
- console.log(" docker compose up -d");
242
- console.log(" # Wait ~30s for Postgres + Caddy + ACME");
323
+ console.log(` docker compose -f ${COMPOSE_PATH} up -d postgres`);
324
+ console.log(` ${selfCommand("migrate")} # applies the database migrations`);
325
+ console.log(` docker compose -f ${COMPOSE_PATH} up -d`);
326
+ console.log(" # Wait ~30s for Caddy + ACME");
243
327
  console.log("");
244
328
  console.log("Then visit:");
245
329
  console.log(` https://${domain}/setup?token=${tok.token}`);
@@ -579,6 +663,75 @@ async function restore() {
579
663
  }).exited;
580
664
  console.log("Restore complete.");
581
665
  }
666
+ /**
667
+ * #696 — `migrate`: apply the database migrations with the admin image the
668
+ * install runs (a one-off `docker compose run` of its migration entrypoint,
669
+ * as the GCP migrate job does). Postgres must be up; idempotent.
670
+ */
671
+ async function migrate() {
672
+ requireSelfHosted("migrate");
673
+ if (!existsSync(COMPOSE_PATH)) {
674
+ console.error(`no Compose file — run \`${selfCommand("init")}\` first`);
675
+ process.exit(2);
676
+ }
677
+ const { runMigrations } = await import("./self-hosted-upgrade.js");
678
+ const r = await runMigrations(CAELO_DIR, bunHostRunner);
679
+ if (!r.ok) {
680
+ console.error(r.error);
681
+ process.exit(1);
682
+ }
683
+ console.log("Migrations applied (cms_admin + cms_public).");
684
+ }
685
+ /**
686
+ * Whether `upgrade` targets this directory's self-hosted Compose install.
687
+ * `--install <id|domain|all>` always names cloud installs (install.json),
688
+ * so it goes to the lifecycle selector even where a `.caelo/` exists.
689
+ */
690
+ function selfHostedInstallPresent() {
691
+ return (arg("install") === undefined && existsSync(CONFIG_PATH) && loadProvider() === "self-hosted");
692
+ }
693
+ /**
694
+ * #696 — `upgrade` for a self-hosted install: verified digests, pg_dump
695
+ * backup, pull, migrations, admin-then-gateway roll with health checks and
696
+ * rollback (self-hosted-upgrade.ts).
697
+ */
698
+ async function upgradeSelfHostedCommand(opts) {
699
+ const cfg = loadConfig();
700
+ if (!cfg) {
701
+ console.error("no config — run `cms-provision init` first");
702
+ process.exit(2);
703
+ }
704
+ if (cfg.imageMode === "dev") {
705
+ console.error("This is a DEV MODE install: the admin + gateway run your Caelo checkout, so there are\n" +
706
+ "no images to upgrade. Update the checkout (git pull), then `bun packages/provisioning/src/cli.ts migrate` and\n" +
707
+ `\`docker compose -f ${COMPOSE_PATH} restart caelo-admin caelo-gateway\`.`);
708
+ process.exit(2);
709
+ }
710
+ const { upgradeSelfHosted } = await import("./self-hosted-upgrade.js");
711
+ const result = await upgradeSelfHosted(opts, {
712
+ caeloDir: CAELO_DIR,
713
+ runner: bunHostRunner,
714
+ renderCompose: (images) => renderCompose(cfg, images),
715
+ log: {
716
+ step: (m) => console.log(`\n==> ${m}`),
717
+ info: (m) => console.log(` ${m}`),
718
+ warn: (m) => console.warn(` ! ${m}`),
719
+ error: (m) => console.error(` x ${m}`),
720
+ },
721
+ });
722
+ if (result.ok) {
723
+ if (result.status === "upgraded" && cfg.imageMode !== "release") {
724
+ cfg.imageMode = "release";
725
+ saveConfig(cfg);
726
+ }
727
+ return;
728
+ }
729
+ console.error(`\nUpgrade failed at "${result.stage}":\n${result.error}`);
730
+ console.error(result.previousRunning
731
+ ? "The previous release is still the one running."
732
+ : "The install may be degraded — see above.");
733
+ process.exit(1);
734
+ }
582
735
  const cmd = process.argv[2];
583
736
  /**
584
737
  * P15 — `pulumi-output-sync`. Reads `pulumi stack output --json` from
@@ -667,6 +820,7 @@ const handlers = {
667
820
  init,
668
821
  up,
669
822
  "regenerate-caddy": regenerateCaddy,
823
+ migrate,
670
824
  // §11.C lifecycle dispatchers route by provider via install metadata.
671
825
  // Self-hosted bodies remain reachable as `<command>-self-hosted` for
672
826
  // back-compat scripts that bypassed the dispatcher.
@@ -681,6 +835,9 @@ const handlers = {
681
835
  truncate: lifecycleTruncate,
682
836
  "admin-domain": adminDomain,
683
837
  "staging-domain": stagingDomain,
838
+ // #696 — Pulumi state in the install's own project.
839
+ state: async () => (await import("./state-command.js")).stateCommand(process.argv),
840
+ attach: async () => (await import("./state-command.js")).attachCommand(process.argv),
684
841
  // Misc
685
842
  "pulumi-output-sync": pulumiOutputSync,
686
843
  version,
@@ -695,7 +852,6 @@ async function lifecycleStatus() {
695
852
  await statusCommand();
696
853
  }
697
854
  async function lifecycleUpgrade() {
698
- const { upgradeCommand } = await import("./lifecycle.js");
699
855
  // P20 — version + channel flags. Default = latest stable.
700
856
  // bunx @caelo-cms/provisioning upgrade
701
857
  // bunx @caelo-cms/provisioning upgrade --version 0.5.3
@@ -708,14 +864,27 @@ async function lifecycleUpgrade() {
708
864
  ? channelArg
709
865
  : undefined;
710
866
  const skipVerify = process.argv.includes("--skip-verify");
867
+ if (selfHostedInstallPresent()) {
868
+ await upgradeSelfHostedCommand({
869
+ ...(version ? { version } : {}),
870
+ ...(channel ? { channel } : {}),
871
+ ...(skipVerify ? { skipVerify: true } : {}),
872
+ });
873
+ return;
874
+ }
875
+ // #696 — `--skip-health-check` rolls without the post-roll deep health
876
+ // check (Cloud Run readiness only), e.g. for a release that predates it.
877
+ const skipHealthCheck = process.argv.includes("--skip-health-check");
711
878
  // #607 — optional; must match the install's recorded region (upgrade
712
879
  // never moves an install between regions).
713
880
  const region = arg("region");
881
+ const { upgradeCommand } = await import("./lifecycle.js");
714
882
  await upgradeCommand({
715
883
  ...(region ? { region } : {}),
716
884
  ...(version ? { version } : {}),
717
885
  ...(channel ? { channel } : {}),
718
886
  ...(skipVerify ? { skipVerify: true } : {}),
887
+ ...(skipHealthCheck ? { skipHealthCheck: true } : {}),
719
888
  });
720
889
  }
721
890
  async function lifecycleBackup() {
@@ -761,7 +930,7 @@ async function domainMappingCommand(kind) {
761
930
  console.log(`Usage: cms-provision ${command} enable [--install <install-id>]${kind === "staging" ? " [--staging-domain <host>] [--rotate-staging-password] [--show-staging-password]" : ""}`);
762
931
  process.exit(2);
763
932
  }
764
- const { installFlag, installStagingHost, listInstalls, recordableStagingHost, selectInstall, writeMetadata, } = await import("./install-state.js");
933
+ const { installFlag, installStagingHost, currentMetadata, listInstalls, recordableStagingHost, selectInstall, writeMetadata, } = await import("./install-state.js");
765
934
  const { enableAdminDomain, enableStagingDomain } = await import("./admin-domain.js");
766
935
  // Guessing among several installs could map the domain in the wrong project.
767
936
  const selected = selectInstall(listInstalls().filter((m) => m.projectId), installFlag(process.argv));
@@ -769,7 +938,7 @@ async function domainMappingCommand(kind) {
769
938
  console.error(selected.message);
770
939
  process.exit(1);
771
940
  }
772
- let meta = selected.meta;
941
+ let meta = currentMetadata(selected.meta);
773
942
  // The command to re-run after a stop before the admin was updated: an
774
943
  // explicitly requested host must survive it, or the retry would map the
775
944
  // admin's old host (codex review on #681).
@@ -981,7 +1150,7 @@ if (route.kind === "handler" || route.kind === "wizard") {
981
1150
  }
982
1151
  }
983
1152
  else {
984
- console.log("Usage: cms-provision [wizard] [--provider <name> --domain <d> [--staging-domain <host>] --owner-email <e> --region <r>] | <init|up|status|upgrade|backup|restore|rotate-secret|truncate|destroy|regenerate-caddy|admin-domain|staging-domain|pulumi-output-sync|version> [options]\n" +
1153
+ console.log("Usage: cms-provision [wizard] [--provider <name> --domain <d> [--staging-domain <host>] --owner-email <e> --region <r>] | <init|up|migrate|status|upgrade|backup|restore|rotate-secret|truncate|destroy|regenerate-caddy|admin-domain|staging-domain|state migrate|attach|pulumi-output-sync|version> [options]\n" +
985
1154
  "With several installs on this machine, pick one with --install <install-id or domain> (status, upgrade and backup also take --install all); in a terminal you are asked otherwise.\n" +
986
1155
  "Pass --no-wizard with no sub-command to print this usage instead of the wizard.");
987
1156
  process.exit(cmd && !cmd.startsWith("-") ? 2 : 0);