@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.
- package/dist/adc-impersonation.d.ts +28 -0
- package/dist/adc-impersonation.d.ts.map +1 -0
- package/dist/adc-impersonation.js +148 -0
- package/dist/adc-impersonation.js.map +1 -0
- package/dist/checkpoint-secrets.d.ts.map +1 -1
- package/dist/checkpoint-secrets.js +2 -1
- package/dist/checkpoint-secrets.js.map +1 -1
- package/dist/cli.js +202 -33
- package/dist/cli.js.map +1 -1
- package/dist/compose.d.ts +45 -0
- package/dist/compose.d.ts.map +1 -1
- package/dist/compose.js +112 -29
- package/dist/compose.js.map +1 -1
- package/dist/gcloud-retry.d.ts +5 -1
- package/dist/gcloud-retry.d.ts.map +1 -1
- package/dist/gcloud-retry.js.map +1 -1
- package/dist/gcloud.d.ts +2 -1
- package/dist/gcloud.d.ts.map +1 -1
- package/dist/gcloud.js +11 -13
- package/dist/gcloud.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/infra-contract.d.ts +24 -0
- package/dist/infra-contract.d.ts.map +1 -0
- package/dist/infra-contract.js +25 -0
- package/dist/infra-contract.js.map +1 -0
- package/dist/install-state.d.ts +66 -2
- package/dist/install-state.d.ts.map +1 -1
- package/dist/install-state.js +162 -22
- package/dist/install-state.js.map +1 -1
- package/dist/lifecycle.d.ts +6 -0
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/lifecycle.js +189 -819
- package/dist/lifecycle.js.map +1 -1
- package/dist/migration-runner.d.ts +3 -0
- package/dist/migration-runner.d.ts.map +1 -1
- package/dist/migration-runner.js +7 -5
- package/dist/migration-runner.js.map +1 -1
- package/dist/ops-backend.d.ts +46 -0
- package/dist/ops-backend.d.ts.map +1 -0
- package/dist/ops-backend.js +370 -0
- package/dist/ops-backend.js.map +1 -0
- package/dist/provisioner-identity.d.ts +103 -0
- package/dist/provisioner-identity.d.ts.map +1 -0
- package/dist/provisioner-identity.js +323 -0
- package/dist/provisioner-identity.js.map +1 -0
- package/dist/regions.d.ts.map +1 -1
- package/dist/regions.js +2 -1
- package/dist/regions.js.map +1 -1
- package/dist/release-contract.d.ts +37 -0
- package/dist/release-contract.d.ts.map +1 -0
- package/dist/release-contract.js +55 -0
- package/dist/release-contract.js.map +1 -0
- package/dist/release-manifest.d.ts +140 -0
- package/dist/release-manifest.d.ts.map +1 -0
- package/dist/release-manifest.js +319 -0
- package/dist/release-manifest.js.map +1 -0
- package/dist/self-command.d.ts +16 -0
- package/dist/self-command.d.ts.map +1 -0
- package/dist/self-command.js +20 -0
- package/dist/self-command.js.map +1 -0
- package/dist/self-hosted-release.d.ts +81 -0
- package/dist/self-hosted-release.d.ts.map +1 -0
- package/dist/self-hosted-release.js +148 -0
- package/dist/self-hosted-release.js.map +1 -0
- package/dist/self-hosted-upgrade.d.ts +91 -0
- package/dist/self-hosted-upgrade.d.ts.map +1 -0
- package/dist/self-hosted-upgrade.js +355 -0
- package/dist/self-hosted-upgrade.js.map +1 -0
- package/dist/stack-converge.d.ts.map +1 -1
- package/dist/stack-converge.js +2 -1
- package/dist/stack-converge.js.map +1 -1
- package/dist/state-attach.d.ts +23 -0
- package/dist/state-attach.d.ts.map +1 -0
- package/dist/state-attach.js +112 -0
- package/dist/state-attach.js.map +1 -0
- package/dist/state-backend.d.ts +114 -0
- package/dist/state-backend.d.ts.map +1 -0
- package/dist/state-backend.js +200 -0
- package/dist/state-backend.js.map +1 -0
- package/dist/state-command.d.ts +20 -0
- package/dist/state-command.d.ts.map +1 -0
- package/dist/state-command.js +237 -0
- package/dist/state-command.js.map +1 -0
- package/dist/state-migrate.d.ts +121 -0
- package/dist/state-migrate.d.ts.map +1 -0
- package/dist/state-migrate.js +290 -0
- package/dist/state-migrate.js.map +1 -0
- package/dist/state-pulumi.d.ts +17 -0
- package/dist/state-pulumi.d.ts.map +1 -0
- package/dist/state-pulumi.js +218 -0
- package/dist/state-pulumi.js.map +1 -0
- package/dist/state-store.d.ts +82 -0
- package/dist/state-store.d.ts.map +1 -0
- package/dist/state-store.js +205 -0
- package/dist/state-store.js.map +1 -0
- package/dist/upgrade/app-roll.d.ts +164 -0
- package/dist/upgrade/app-roll.d.ts.map +1 -0
- package/dist/upgrade/app-roll.js +270 -0
- package/dist/upgrade/app-roll.js.map +1 -0
- package/dist/upgrade/backup.d.ts +48 -0
- package/dist/upgrade/backup.d.ts.map +1 -0
- package/dist/upgrade/backup.js +71 -0
- package/dist/upgrade/backup.js.map +1 -0
- package/dist/upgrade/converge.d.ts +45 -0
- package/dist/upgrade/converge.d.ts.map +1 -0
- package/dist/upgrade/converge.js +287 -0
- package/dist/upgrade/converge.js.map +1 -0
- package/dist/upgrade/gcp-lookup.d.ts +23 -0
- package/dist/upgrade/gcp-lookup.d.ts.map +1 -0
- package/dist/upgrade/gcp-lookup.js +95 -0
- package/dist/upgrade/gcp-lookup.js.map +1 -0
- package/dist/upgrade/health.d.ts +99 -0
- package/dist/upgrade/health.d.ts.map +1 -0
- package/dist/upgrade/health.js +214 -0
- package/dist/upgrade/health.js.map +1 -0
- package/dist/upgrade/release-images.d.ts +125 -0
- package/dist/upgrade/release-images.d.ts.map +1 -0
- package/dist/upgrade/release-images.js +315 -0
- package/dist/upgrade/release-images.js.map +1 -0
- package/dist/upgrade/reporter.d.ts +17 -0
- package/dist/upgrade/reporter.d.ts.map +1 -0
- package/dist/upgrade/reporter.js +28 -0
- package/dist/upgrade/reporter.js.map +1 -0
- package/dist/upgrade/upgrade.d.ts +79 -0
- package/dist/upgrade/upgrade.d.ts.map +1 -0
- package/dist/upgrade/upgrade.js +105 -0
- package/dist/upgrade/upgrade.js.map +1 -0
- package/dist/wizard.d.ts.map +1 -1
- package/dist/wizard.js +7 -3
- package/dist/wizard.js.map +1 -1
- package/dist/wizards/gcp-cost.d.ts.map +1 -1
- package/dist/wizards/gcp-cost.js +7 -1
- package/dist/wizards/gcp-cost.js.map +1 -1
- package/dist/wizards/gcp-pulumi.d.ts +104 -8
- package/dist/wizards/gcp-pulumi.d.ts.map +1 -1
- package/dist/wizards/gcp-pulumi.js +159 -50
- package/dist/wizards/gcp-pulumi.js.map +1 -1
- package/dist/wizards/gcp.d.ts.map +1 -1
- package/dist/wizards/gcp.js +246 -78
- package/dist/wizards/gcp.js.map +1 -1
- package/package.json +4 -3
- package/stacks/self-hosted/README.md +4 -0
- 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":"
|
|
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) =>
|
|
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":"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"}
|
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,
|
|
9
|
-
*
|
|
10
|
-
* the
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(`
|
|
241
|
-
console.log("
|
|
242
|
-
console.log(
|
|
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);
|