@caelo-cms/provisioning 0.11.10 → 0.11.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter.d.ts +6 -0
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adopt-existing.d.ts +6 -2
- package/dist/adopt-existing.d.ts.map +1 -1
- package/dist/adopt-existing.js +57 -0
- package/dist/adopt-existing.js.map +1 -1
- package/dist/agent/command.d.ts +5 -2
- package/dist/agent/command.d.ts.map +1 -1
- package/dist/agent/command.js +1 -1
- package/dist/agent/command.js.map +1 -1
- package/dist/agent-db.js +25 -8
- package/dist/cli-routing.js +1 -1
- package/dist/cli-routing.js.map +1 -1
- package/dist/cli.js +59 -7
- package/dist/cli.js.map +1 -1
- package/dist/cloudsql-tls.d.ts +30 -0
- package/dist/cloudsql-tls.d.ts.map +1 -1
- package/dist/cloudsql-tls.js +7 -1
- package/dist/cloudsql-tls.js.map +1 -1
- package/dist/compose.d.ts +14 -0
- package/dist/compose.d.ts.map +1 -1
- package/dist/compose.js +54 -1
- package/dist/compose.js.map +1 -1
- package/dist/converge-db-trust.d.ts +44 -0
- package/dist/converge-db-trust.d.ts.map +1 -0
- package/dist/converge-db-trust.js +158 -0
- package/dist/converge-db-trust.js.map +1 -0
- package/dist/converge-job-gcp.d.ts +5 -2
- package/dist/converge-job-gcp.d.ts.map +1 -1
- package/dist/converge-job-gcp.js +9 -2
- package/dist/converge-job-gcp.js.map +1 -1
- package/dist/converge-job-preflight.d.ts.map +1 -1
- package/dist/converge-job-preflight.js +8 -0
- package/dist/converge-job-preflight.js.map +1 -1
- package/dist/converge-job.d.ts +17 -0
- package/dist/converge-job.d.ts.map +1 -1
- package/dist/converge-job.js +12 -0
- package/dist/converge-job.js.map +1 -1
- package/dist/gcp-names.d.ts +13 -0
- package/dist/gcp-names.d.ts.map +1 -1
- package/dist/gcp-names.js +21 -0
- package/dist/gcp-names.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/infra-contract.d.ts +1 -1
- package/dist/infra-contract.d.ts.map +1 -1
- package/dist/infra-contract.js +22 -1
- package/dist/infra-contract.js.map +1 -1
- package/dist/install-job.d.ts +4 -2
- package/dist/install-job.d.ts.map +1 -1
- package/dist/install-job.js +4 -1
- package/dist/install-job.js.map +1 -1
- package/dist/install-state.d.ts +7 -0
- package/dist/install-state.d.ts.map +1 -1
- package/dist/install-state.js.map +1 -1
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/lifecycle.js +3 -0
- package/dist/lifecycle.js.map +1 -1
- package/dist/migration-runner.d.ts.map +1 -1
- package/dist/migration-runner.js +8 -3
- package/dist/migration-runner.js.map +1 -1
- package/dist/migration-targets.d.ts +11 -0
- package/dist/migration-targets.d.ts.map +1 -0
- package/dist/migration-targets.js +12 -0
- package/dist/migration-targets.js.map +1 -0
- package/dist/operator-access.d.ts +10 -0
- package/dist/operator-access.d.ts.map +1 -1
- package/dist/operator-access.js +5 -0
- package/dist/operator-access.js.map +1 -1
- package/dist/pool-budget-stack.d.ts +13 -1
- package/dist/pool-budget-stack.d.ts.map +1 -1
- package/dist/pool-budget-stack.js +11 -1
- package/dist/pool-budget-stack.js.map +1 -1
- package/dist/public-role-isolation.d.ts +7 -3
- package/dist/public-role-isolation.d.ts.map +1 -1
- package/dist/public-role-isolation.js +25 -13
- package/dist/public-role-isolation.js.map +1 -1
- package/dist/release-contract.d.ts.map +1 -1
- package/dist/release-contract.js +3 -0
- package/dist/release-contract.js.map +1 -1
- package/dist/runtime-secrets.d.ts +2 -0
- package/dist/runtime-secrets.d.ts.map +1 -1
- package/dist/runtime-secrets.js +19 -15
- package/dist/runtime-secrets.js.map +1 -1
- package/dist/scheduler-setup.d.ts +75 -0
- package/dist/scheduler-setup.d.ts.map +1 -0
- package/dist/scheduler-setup.js +331 -0
- package/dist/scheduler-setup.js.map +1 -0
- package/dist/self-hosted-roles.d.ts +16 -9
- package/dist/self-hosted-roles.d.ts.map +1 -1
- package/dist/self-hosted-roles.js +49 -15
- package/dist/self-hosted-roles.js.map +1 -1
- package/dist/self-hosted-scheduler-interval.d.ts +21 -0
- package/dist/self-hosted-scheduler-interval.d.ts.map +1 -0
- package/dist/self-hosted-scheduler-interval.js +68 -0
- package/dist/self-hosted-scheduler-interval.js.map +1 -0
- package/dist/self-hosted-upgrade.d.ts +7 -4
- package/dist/self-hosted-upgrade.d.ts.map +1 -1
- package/dist/self-hosted-upgrade.js +9 -5
- package/dist/self-hosted-upgrade.js.map +1 -1
- package/dist/stack-contract.d.ts +67 -6
- package/dist/stack-contract.d.ts.map +1 -1
- package/dist/stack-contract.js +87 -6
- package/dist/stack-contract.js.map +1 -1
- package/dist/staging-database.d.ts +22 -0
- package/dist/staging-database.d.ts.map +1 -0
- package/dist/staging-database.js +117 -0
- package/dist/staging-database.js.map +1 -0
- package/dist/upgrade/converge.d.ts +5 -0
- package/dist/upgrade/converge.d.ts.map +1 -1
- package/dist/upgrade/converge.js +110 -10
- package/dist/upgrade/converge.js.map +1 -1
- package/dist/upgrade/upgrade.d.ts +6 -0
- package/dist/upgrade/upgrade.d.ts.map +1 -1
- package/dist/upgrade/upgrade.js +3 -0
- package/dist/upgrade/upgrade.js.map +1 -1
- package/dist/upgrader-gcp.d.ts +5 -4
- package/dist/upgrader-gcp.d.ts.map +1 -1
- package/dist/upgrader-gcp.js +5 -4
- package/dist/upgrader-gcp.js.map +1 -1
- package/dist/wizard.d.ts +7 -0
- package/dist/wizard.d.ts.map +1 -1
- package/dist/wizard.js +11 -0
- package/dist/wizard.js.map +1 -1
- package/dist/wizards/gcp-cost.d.ts +31 -0
- package/dist/wizards/gcp-cost.d.ts.map +1 -1
- package/dist/wizards/gcp-cost.js +81 -11
- package/dist/wizards/gcp-cost.js.map +1 -1
- package/dist/wizards/gcp.d.ts.map +1 -1
- package/dist/wizards/gcp.js +87 -11
- package/dist/wizards/gcp.js.map +1 -1
- package/package.json +2 -2
- package/src/adapter.ts +6 -0
- package/src/admin-memory.test.ts +1 -1
- package/src/adopt-existing.test.ts +46 -0
- package/src/adopt-existing.ts +58 -2
- package/src/agent/command.ts +6 -3
- package/src/caddy-redirects.test.ts +1 -1
- package/src/cli-routing.test.ts +1 -1
- package/src/cli-routing.ts +1 -1
- package/src/cli.ts +63 -8
- package/src/cloudsql-tls.test.ts +30 -0
- package/src/cloudsql-tls.ts +10 -3
- package/src/compose.ts +68 -0
- package/src/converge-db-trust.test.ts +237 -0
- package/src/converge-db-trust.ts +212 -0
- package/src/converge-job-gcp.ts +9 -1
- package/src/converge-job-preflight.test.ts +5 -0
- package/src/converge-job-preflight.ts +8 -0
- package/src/converge-job.test.ts +70 -0
- package/src/converge-job.ts +32 -0
- package/src/database-tls-builders.test.ts +3 -2
- package/src/deployed-release.test.ts +3 -0
- package/src/gateway-env-isolation.test.ts +40 -7
- package/src/gcp-names.ts +25 -0
- package/src/index.test.ts +3 -3
- package/src/index.ts +6 -0
- package/src/infra-contract.test.ts +5 -3
- package/src/infra-contract.ts +22 -1
- package/src/install-job.ts +4 -1
- package/src/install-state.ts +7 -0
- package/src/lifecycle.ts +3 -0
- package/src/migration-runner.ts +14 -9
- package/src/migration-targets.ts +12 -0
- package/src/operator-access.test.ts +15 -0
- package/src/operator-access.ts +14 -0
- package/src/pool-budget-stack.ts +15 -0
- package/src/pool-budget-stacks.test.ts +38 -13
- package/src/public-role-isolation.test.ts +18 -8
- package/src/public-role-isolation.ts +31 -17
- package/src/release-contract.ts +3 -0
- package/src/runtime-secrets.test.ts +18 -8
- package/src/runtime-secrets.ts +37 -18
- package/src/scheduler-setup.test.ts +201 -0
- package/src/scheduler-setup.ts +375 -0
- package/src/self-hosted-backup.test.ts +1 -0
- package/src/self-hosted-compose.test.ts +72 -1
- package/src/self-hosted-roles.integration.test.ts +2 -0
- package/src/self-hosted-roles.test.ts +49 -19
- package/src/self-hosted-roles.ts +60 -20
- package/src/self-hosted-scheduler-interval.test.ts +66 -0
- package/src/self-hosted-scheduler-interval.ts +79 -0
- package/src/self-hosted-start.test.ts +1 -0
- package/src/self-hosted-upgrade.test.ts +2 -1
- package/src/self-hosted-upgrade.ts +14 -8
- package/src/stack-contract.test.ts +31 -3
- package/src/stack-contract.ts +113 -6
- package/src/stack-converge-secrets.test.ts +2 -0
- package/src/stack-converge.test.ts +6 -4
- package/src/staging-database.test.ts +114 -0
- package/src/staging-database.ts +148 -0
- package/src/upgrade/converge.ts +130 -9
- package/src/upgrade/upgrade.test.ts +85 -2
- package/src/upgrade/upgrade.ts +9 -0
- package/src/upgrader-gcp.ts +5 -4
- package/src/wizard.ts +19 -0
- package/src/wizards/gcp-cost.test.ts +54 -1
- package/src/wizards/gcp-cost.ts +101 -11
- package/src/wizards/gcp.ts +109 -8
- package/stacks/aws/Pulumi.yaml +1 -1
- package/stacks/aws/index.ts +41 -1
- package/stacks/azure/index.ts +51 -3
- package/stacks/gcp/Pulumi.yaml +1 -1
- package/stacks/gcp/README.md +1 -0
- package/stacks/gcp/index.ts +50 -1
- package/stacks/gcp-firebase/Pulumi.yaml +1 -1
- package/stacks/gcp-firebase/index.ts +50 -1
- package/stacks/self-hosted/Pulumi.yaml +3 -0
- package/stacks/self-hosted/README.md +4 -0
- package/stacks/self-hosted/index.ts +29 -4
|
@@ -41,8 +41,10 @@ import {
|
|
|
41
41
|
runServiceAccountId,
|
|
42
42
|
} from "../../dist/gcp-names.js";
|
|
43
43
|
import {
|
|
44
|
+
DEFAULT_ADMIN_MAX_INSTANCES,
|
|
44
45
|
DEFAULT_GATEWAY_MAX_INSTANCES,
|
|
45
46
|
DEFAULT_MAX_CONNECTIONS,
|
|
47
|
+
DEFAULT_STAGING_GATEWAY_MAX_INSTANCES,
|
|
46
48
|
stackPoolBudget,
|
|
47
49
|
} from "../../dist/pool-budget-stack.js";
|
|
48
50
|
import {
|
|
@@ -109,7 +111,10 @@ const adminMinInstances = Number.parseInt(cfg.get("adminMinInstances") ?? "0", 1
|
|
|
109
111
|
// #553 — the admin also runs the Lighthouse quality audit; same knob and
|
|
110
112
|
// default on every adapter (stack-contract.ts ADMIN_MEMORY_DEFAULT).
|
|
111
113
|
const adminMemory = cfg.get("adminMemory") ?? ADMIN_MEMORY_DEFAULT;
|
|
112
|
-
const adminMaxInstances = Number.parseInt(
|
|
114
|
+
const adminMaxInstances = Number.parseInt(
|
|
115
|
+
cfg.get("adminMaxInstances") ?? String(DEFAULT_ADMIN_MAX_INSTANCES),
|
|
116
|
+
10,
|
|
117
|
+
);
|
|
113
118
|
const gatewayMinInstances = Number.parseInt(cfg.get("gatewayMinInstances") ?? "0", 10);
|
|
114
119
|
// #1254 — part of the connection budget (stacks/gcp has the long comment).
|
|
115
120
|
const gatewayMaxInstances = Number.parseInt(
|
|
@@ -125,6 +130,8 @@ const poolBudget = stackPoolBudget("gcp-firebase", {
|
|
|
125
130
|
maxConnections,
|
|
126
131
|
adminMaxInstances,
|
|
127
132
|
gatewayMaxInstances,
|
|
133
|
+
// #1329 — the staging gateway (P3b-2) is budgeted from this release on.
|
|
134
|
+
stagingGatewayMaxInstances: DEFAULT_STAGING_GATEWAY_MAX_INSTANCES,
|
|
128
135
|
});
|
|
129
136
|
const backupRetentionDays = Number.parseInt(cfg.get("backupRetentionDays") ?? "7", 10);
|
|
130
137
|
const iapAllowlistRaw = cfg.get("iapAllowlist");
|
|
@@ -262,6 +269,8 @@ const runtimeSecretIds: Record<RuntimeSecret, pulumi.Input<string>> = {
|
|
|
262
269
|
"tool-approval-secret": gcpSecretId(env, "tool-approval-secret"),
|
|
263
270
|
"staging-gate-secret": gcpSecretId(env, "staging-gate-secret"),
|
|
264
271
|
"public-role-password": gcpSecretId(env, "public-role-password"),
|
|
272
|
+
// #1329 — the staging gateway's login, never the live one's.
|
|
273
|
+
"public-staging-role-password": gcpSecretId(env, "public-staging-role-password"),
|
|
265
274
|
// #914 / #806 — the Owner-set Google sign-in client (a placeholder until
|
|
266
275
|
// then; IAP login, IAP programmatic access and the remote-MCP broker) and
|
|
267
276
|
// the broker's seal key, both CLI-generated.
|
|
@@ -278,6 +287,14 @@ const publicRolePassword = pulumi.secret(
|
|
|
278
287
|
{ provider: gcpProvider },
|
|
279
288
|
).secretData,
|
|
280
289
|
);
|
|
290
|
+
// #1329 — public_staging_role's own password (CLI-generated like the one
|
|
291
|
+
// above): the staging gateway's only login, on cms_public_staging only.
|
|
292
|
+
const publicStagingRolePassword = pulumi.secret(
|
|
293
|
+
gcp.secretmanager.getSecretVersionOutput(
|
|
294
|
+
{ project, secret: gcpSecretId(env, "public-staging-role-password") },
|
|
295
|
+
{ provider: gcpProvider },
|
|
296
|
+
).secretData,
|
|
297
|
+
);
|
|
281
298
|
|
|
282
299
|
// =========================================================================
|
|
283
300
|
// Tier 4 — Cloud SQL Postgres (private IP only; HA configurable)
|
|
@@ -334,6 +351,13 @@ const cmsPublicDb = new gcp.sql.Database(
|
|
|
334
351
|
{ instance: sqlInstance.name, name: "cms_public" },
|
|
335
352
|
opts,
|
|
336
353
|
);
|
|
354
|
+
// #1329 — staging's own data: the twin of cms_public on the same instance
|
|
355
|
+
// (no extra cost), reached by the staging gateway only.
|
|
356
|
+
const cmsPublicStagingDb = new gcp.sql.Database(
|
|
357
|
+
`${namePrefix}-cms-public-staging`,
|
|
358
|
+
{ instance: sqlInstance.name, name: "cms_public_staging" },
|
|
359
|
+
opts,
|
|
360
|
+
);
|
|
337
361
|
|
|
338
362
|
const pgAdminUser = new gcp.sql.User(
|
|
339
363
|
`${namePrefix}-admin-user`,
|
|
@@ -352,6 +376,14 @@ new gcp.sql.User(
|
|
|
352
376
|
{ instance: sqlInstance.name, name: "public_role", password: publicRolePassword },
|
|
353
377
|
opts,
|
|
354
378
|
);
|
|
379
|
+
// #1329 — the staging gateway's login: an Admin API user like public_role,
|
|
380
|
+
// so the same membership revoke (public-role-isolation.ts) and the same
|
|
381
|
+
// audit apply; migration 0530 gives it CONNECT on cms_public_staging only.
|
|
382
|
+
new gcp.sql.User(
|
|
383
|
+
`${namePrefix}-public-staging-user`,
|
|
384
|
+
{ instance: sqlInstance.name, name: "public_staging_role", password: publicStagingRolePassword },
|
|
385
|
+
opts,
|
|
386
|
+
);
|
|
355
387
|
|
|
356
388
|
// #1338 — the instance's DNS name, resolved to its private IP by a private
|
|
357
389
|
// zone in the VPC (Cloud SQL assigns the name, it does not resolve it).
|
|
@@ -729,6 +761,7 @@ function cloudRunService(args: CloudRunArgs): gcp.cloudrunv2.Service {
|
|
|
729
761
|
pgAdminUser,
|
|
730
762
|
cmsAdminDb,
|
|
731
763
|
cmsPublicDb,
|
|
764
|
+
cmsPublicStagingDb,
|
|
732
765
|
// The env contract names the media bucket as a string; keep it
|
|
733
766
|
// ordered before the services that use it.
|
|
734
767
|
mediaBucket,
|
|
@@ -756,6 +789,8 @@ const envContractInputs = {
|
|
|
756
789
|
admin: dbUrls.admin,
|
|
757
790
|
publicAdmin: dbUrls.publicAdmin,
|
|
758
791
|
public: dbUrls.public,
|
|
792
|
+
publicStagingAdmin: dbUrls.publicStagingAdmin,
|
|
793
|
+
publicStaging: dbUrls.publicStaging,
|
|
759
794
|
},
|
|
760
795
|
} as const;
|
|
761
796
|
|
|
@@ -1129,6 +1164,18 @@ new gcp.iap.WebCloudRunServiceIamMember(
|
|
|
1129
1164
|
// (packages/provisioning/src/capture-job-setup.ts), for the same reason as
|
|
1130
1165
|
// the audit job above.
|
|
1131
1166
|
|
|
1167
|
+
// =========================================================================
|
|
1168
|
+
// Scheduler tick — deliberately NOT here
|
|
1169
|
+
// =========================================================================
|
|
1170
|
+
//
|
|
1171
|
+
// #1140 — one Cloud Scheduler job starts a Cloud Workflows execution every
|
|
1172
|
+
// `schedulerIntervalMinutes` (1–15, default 5); the workflow signs an IAP
|
|
1173
|
+
// credential as the scheduler's own service account and POSTs the admin's
|
|
1174
|
+
// /api/internal/scheduler/tick, where the admin runs its periodic work and
|
|
1175
|
+
// plugin workers from its due-table. The CLI owns the account, its grants,
|
|
1176
|
+
// the workflow and the job (packages/provisioning/src/scheduler-setup.ts),
|
|
1177
|
+
// for the same reason as the audit job above.
|
|
1178
|
+
|
|
1132
1179
|
// =========================================================================
|
|
1133
1180
|
// Operator access — deliberately NOT here
|
|
1134
1181
|
// =========================================================================
|
|
@@ -1213,6 +1260,7 @@ const out: CloudAdapterOutputs = {
|
|
|
1213
1260
|
// Password-less — the password lives only in Secret Manager.
|
|
1214
1261
|
adminDatabaseUrl: dbUrls.admin as unknown as string,
|
|
1215
1262
|
publicDatabaseUrl: dbUrls.public as unknown as string,
|
|
1263
|
+
publicStagingDatabaseUrl: dbUrls.publicStaging as unknown as string,
|
|
1216
1264
|
mediaStorageUrl: pulumi.interpolate`gs://${mediaBucket.name}` as unknown as string,
|
|
1217
1265
|
// Firebase Hosting serves media via its own CDN; we proxy through
|
|
1218
1266
|
// the Firebase site's apex domain for canonical URLs.
|
|
@@ -1229,6 +1277,7 @@ const out: CloudAdapterOutputs = {
|
|
|
1229
1277
|
|
|
1230
1278
|
export const adminDatabaseUrlOut = out.adminDatabaseUrl;
|
|
1231
1279
|
export const publicDatabaseUrlOut = out.publicDatabaseUrl;
|
|
1280
|
+
export const publicStagingDatabaseUrlOut = out.publicStagingDatabaseUrl;
|
|
1232
1281
|
export const mediaStorageUrlOut = out.mediaStorageUrl;
|
|
1233
1282
|
export const mediaCdnBaseUrlOut = out.mediaCdnBaseUrl;
|
|
1234
1283
|
export const bootstrapUrlOut = out.bootstrapUrl;
|
|
@@ -29,3 +29,6 @@ config:
|
|
|
29
29
|
type: string
|
|
30
30
|
default: "2Gi"
|
|
31
31
|
description: Memory reserved for the admin container (it runs the Lighthouse quality audit).
|
|
32
|
+
caelo-self-hosted:schedulerIntervalMinutes:
|
|
33
|
+
type: integer
|
|
34
|
+
description: Minutes between scheduler ticks (1-15, default 5; #1140). On an install `cms-provision init` set up, `.caelo/config.json` records it and this key must match.
|
|
@@ -33,6 +33,10 @@ pulumi stack output bootstrapUrl
|
|
|
33
33
|
|
|
34
34
|
Open that URL once Caddy has issued the cert (~30 s).
|
|
35
35
|
|
|
36
|
+
## Scheduler tick
|
|
37
|
+
|
|
38
|
+
The Compose file runs a `caelo-scheduler` container (the admin image, no database access, only the internal secret it signs with) that POSTs the admin's `/api/internal/scheduler/tick` every `schedulerIntervalMinutes` (#1140; 1–15, default 5). The admin runs its periodic work and plugin workers on that tick. Set the interval with `cms-provision init --scheduler-interval-minutes 2` (recorded in `.caelo/config.json`, which every CLI render reads) or, on an install without a `config.json`, with `pulumi config set caelo-self-hosted:schedulerIntervalMinutes 2`. The stack reads `.caelo/config.json` too, so a `pulumi up` keeps the recorded interval; a Pulumi key that disagrees with it is refused. An install from before the scheduler gets the container on its next `upgrade`, which rewrites the Compose file.
|
|
39
|
+
|
|
36
40
|
## Connection budget
|
|
37
41
|
|
|
38
42
|
The generated Compose file starts Postgres with `max_connections=100` and sizes every pool from it (#1254, docs/dev/connection-budget.md): the admin gets a cms_admin pool of 77 and a cms_public pool of 4, the gateway a pool of 2, and static builds 2 per pool.
|
|
@@ -34,7 +34,12 @@ import {
|
|
|
34
34
|
generateDockerCompose,
|
|
35
35
|
SITE_OUTPUT_ROOT,
|
|
36
36
|
} from "../../dist/compose.js";
|
|
37
|
+
import { MIGRATION_TARGETS } from "../../dist/migration-targets.js";
|
|
37
38
|
import { selfHostedBootstrapScript } from "../../dist/self-hosted-roles.js";
|
|
39
|
+
import {
|
|
40
|
+
recordedSchedulerIntervalMinutes,
|
|
41
|
+
selfHostedSchedulerIntervalMinutes,
|
|
42
|
+
} from "../../dist/self-hosted-scheduler-interval.js";
|
|
38
43
|
|
|
39
44
|
const cfg = new pulumi.Config();
|
|
40
45
|
const domain = cfg.require("domain");
|
|
@@ -44,6 +49,17 @@ const ownerEmail = cfg.require("ownerEmail");
|
|
|
44
49
|
const caeloDir = cfg.get("caeloDir") ?? "./.caelo";
|
|
45
50
|
// #553 — same knob as every adapter; undefined = stack-contract default.
|
|
46
51
|
const adminMemory = cfg.get("adminMemory");
|
|
52
|
+
// #1140 — how often the scheduler container calls the admin's tick (1–15
|
|
53
|
+
// minutes, default 5). `init --scheduler-interval-minutes` records it in
|
|
54
|
+
// <caeloDir>/config.json, which the CLI renders from; the stack reads the
|
|
55
|
+
// same record so a `pulumi up` does not put it back to the default, and
|
|
56
|
+
// refuses a Pulumi key that disagrees with it.
|
|
57
|
+
const caeloConfigPath = resolve(caeloDir, "config.json");
|
|
58
|
+
const schedulerIntervalMinutes = selfHostedSchedulerIntervalMinutes(
|
|
59
|
+
cfg.getNumber("schedulerIntervalMinutes"),
|
|
60
|
+
recordedSchedulerIntervalMinutes(caeloConfigPath),
|
|
61
|
+
caeloConfigPath,
|
|
62
|
+
);
|
|
47
63
|
// #696 — the prebuilt, cosign-verified release images, pinned by digest
|
|
48
64
|
// (`ghcr.io/caelo-cms/<svc>@sha256:…`; the generator refuses anything else).
|
|
49
65
|
// `cms-provision init` resolves + verifies them and records them in
|
|
@@ -69,21 +85,30 @@ const postgresPassword = pulumi.secret(randomHex(32));
|
|
|
69
85
|
// public_role one (#635: no cms_admin login).
|
|
70
86
|
const adminRolePassword = pulumi.secret(randomHex(32));
|
|
71
87
|
const publicRolePassword = pulumi.secret(randomHex(32));
|
|
88
|
+
// #1329 — the staging gateway's own login on cms_public_staging.
|
|
89
|
+
const publicStagingRolePassword = pulumi.secret(randomHex(32));
|
|
72
90
|
// P18 — the KEK that encrypts stored provider keys.
|
|
73
91
|
const caeloSecretKek = pulumi.secret(randomHex(32));
|
|
74
92
|
|
|
75
93
|
const composeYaml = pulumi
|
|
76
|
-
.all([
|
|
77
|
-
|
|
94
|
+
.all([
|
|
95
|
+
postgresPassword,
|
|
96
|
+
adminRolePassword,
|
|
97
|
+
publicRolePassword,
|
|
98
|
+
publicStagingRolePassword,
|
|
99
|
+
caeloSecretKek,
|
|
100
|
+
])
|
|
101
|
+
.apply(([pgPw, adminPw, publicPw, publicStagingPw, kek]) =>
|
|
78
102
|
generateDockerCompose({
|
|
79
103
|
domain,
|
|
80
104
|
postgresPassword: pgPw,
|
|
81
|
-
rolePasswords: { admin: adminPw, public: publicPw },
|
|
105
|
+
rolePasswords: { admin: adminPw, public: publicPw, publicStaging: publicStagingPw },
|
|
82
106
|
caeloSecretKek: kek,
|
|
83
107
|
anthropicApiKey: process.env.ANTHROPIC_API_KEY,
|
|
84
108
|
resendApiKey: process.env.RESEND_API_KEY,
|
|
85
109
|
diskSize: "20Gi",
|
|
86
110
|
...(adminMemory ? { adminMemory } : {}),
|
|
111
|
+
...(schedulerIntervalMinutes !== undefined ? { schedulerIntervalMinutes } : {}),
|
|
87
112
|
images: {
|
|
88
113
|
mode: "release",
|
|
89
114
|
admin: adminImage,
|
|
@@ -144,7 +169,7 @@ const composeUp = new local.Command(
|
|
|
144
169
|
// install's admin image, then everything else.
|
|
145
170
|
create: pulumi.interpolate`set -e
|
|
146
171
|
docker compose -f ${composePath} up -d --wait postgres
|
|
147
|
-
for target in
|
|
172
|
+
for target in ${MIGRATION_TARGETS.join(" ")}; do
|
|
148
173
|
docker compose -f ${composePath} run --rm --no-deps -T caelo-admin bun --bun /app/packages/migrations/src/migrate.ts "$target"
|
|
149
174
|
done
|
|
150
175
|
docker compose -f ${composePath} up -d --remove-orphans`,
|