@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,140 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { RELEASE_OIDC_ISSUER } from "./upgrade/release-images.js";
|
|
3
|
+
/** Release channels. Pre-release versions name theirs (`0.11.0-rc.1` → `rc`). */
|
|
4
|
+
export declare const RELEASE_CHANNELS: readonly ["stable", "rc", "beta", "alpha"];
|
|
5
|
+
export type ReleaseChannel = (typeof RELEASE_CHANNELS)[number];
|
|
6
|
+
/** The services a release ships images for. */
|
|
7
|
+
export declare const RELEASE_IMAGES: readonly ["admin", "gateway", "ops"];
|
|
8
|
+
export type ReleaseImage = (typeof RELEASE_IMAGES)[number];
|
|
9
|
+
/** Zod schema of `release-manifest.json` (manifestVersion 1). */
|
|
10
|
+
export declare const ReleaseManifestSchema: z.ZodObject<{
|
|
11
|
+
manifestVersion: z.ZodLiteral<1>;
|
|
12
|
+
version: z.ZodString;
|
|
13
|
+
channel: z.ZodEnum<{
|
|
14
|
+
beta: "beta";
|
|
15
|
+
stable: "stable";
|
|
16
|
+
rc: "rc";
|
|
17
|
+
alpha: "alpha";
|
|
18
|
+
}>;
|
|
19
|
+
digests: z.ZodObject<{
|
|
20
|
+
admin: z.ZodString;
|
|
21
|
+
gateway: z.ZodString;
|
|
22
|
+
ops: z.ZodString;
|
|
23
|
+
}, z.core.$strip>;
|
|
24
|
+
minFromVersion: z.ZodString;
|
|
25
|
+
infraContractVersion: z.ZodNumber;
|
|
26
|
+
migrations: z.ZodObject<{
|
|
27
|
+
contract: z.ZodBoolean;
|
|
28
|
+
lastContractVersion: z.ZodNullable<z.ZodString>;
|
|
29
|
+
head: z.ZodString;
|
|
30
|
+
}, z.core.$strip>;
|
|
31
|
+
security: z.ZodBoolean;
|
|
32
|
+
advisories: z.ZodArray<z.ZodString>;
|
|
33
|
+
}, z.core.$strip>;
|
|
34
|
+
export type ReleaseManifest = z.infer<typeof ReleaseManifestSchema>;
|
|
35
|
+
/** Registry the upgrader reads manifests from — the public AR mirror Cloud Run pulls from. */
|
|
36
|
+
export declare const RELEASE_MANIFEST_REGISTRY = "europe-west1-docker.pkg.dev";
|
|
37
|
+
/** Repository path of the manifest artifact inside {@link RELEASE_MANIFEST_REGISTRY}. */
|
|
38
|
+
export declare const RELEASE_MANIFEST_REPOSITORY = "caelo-website/caelo-cms-images/release-manifest";
|
|
39
|
+
/** OCI artifact type + layer media types of the pushed manifest. */
|
|
40
|
+
export declare const RELEASE_MANIFEST_ARTIFACT_TYPE = "application/vnd.caelo.release-manifest.v1";
|
|
41
|
+
export declare const RELEASE_MANIFEST_MEDIA_TYPE = "application/vnd.caelo.release-manifest.v1+json";
|
|
42
|
+
export declare const SIGSTORE_BUNDLE_MEDIA_TYPE = "application/vnd.dev.sigstore.bundle.v0.3+json";
|
|
43
|
+
export { RELEASE_OIDC_ISSUER };
|
|
44
|
+
/**
|
|
45
|
+
* The only identity allowed to sign the manifest of `version`: release.yml
|
|
46
|
+
* of caelo-cms/caelo-cms running on that exact tag. Exact, not a regex —
|
|
47
|
+
* a manifest signed on another ref (a branch, another tag) is refused.
|
|
48
|
+
*/
|
|
49
|
+
export declare function releaseManifestSignerIdentity(version: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Compare two SemVer strings: negative when `a < b`, 0 when equal,
|
|
52
|
+
* positive when `a > b`. A pre-release sorts below its release; two
|
|
53
|
+
* pre-release tags compare by SemVer identifier rules.
|
|
54
|
+
*
|
|
55
|
+
* @throws Error when either argument is not SemVer.
|
|
56
|
+
*/
|
|
57
|
+
export declare function compareSemver(a: string, b: string): number;
|
|
58
|
+
/**
|
|
59
|
+
* The channel a version ships on.
|
|
60
|
+
*
|
|
61
|
+
* @returns null for a pre-release whose identifier names no known channel.
|
|
62
|
+
*/
|
|
63
|
+
export declare function channelForVersion(version: string): ReleaseChannel | null;
|
|
64
|
+
/** Why fetching or verifying a manifest failed. */
|
|
65
|
+
export type ReleaseManifestErrorCode = "registry" | "artifact-shape" | "blob-digest" | "signature" | "schema" | "version-mismatch";
|
|
66
|
+
export interface ReleaseManifestError {
|
|
67
|
+
readonly code: ReleaseManifestErrorCode;
|
|
68
|
+
readonly message: string;
|
|
69
|
+
}
|
|
70
|
+
export type ReleaseManifestResult = {
|
|
71
|
+
readonly ok: true;
|
|
72
|
+
readonly manifest: ReleaseManifest;
|
|
73
|
+
} | {
|
|
74
|
+
readonly ok: false;
|
|
75
|
+
readonly error: ReleaseManifestError;
|
|
76
|
+
};
|
|
77
|
+
/** Side effects of {@link fetchVerifiedReleaseManifest}, injectable for tests. */
|
|
78
|
+
export interface ReleaseManifestDeps {
|
|
79
|
+
readonly fetch: (url: string, init?: RequestInit) => Promise<Response>;
|
|
80
|
+
/** Runs `cosign` with `args`; resolves with its exit code + stderr. */
|
|
81
|
+
readonly cosign: (args: readonly string[]) => Promise<{
|
|
82
|
+
exitCode: number;
|
|
83
|
+
stderr: string;
|
|
84
|
+
}>;
|
|
85
|
+
/** Registry host + repository; defaults to the fixed public mirror. */
|
|
86
|
+
readonly registry?: string;
|
|
87
|
+
readonly repository?: string;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Fetch the manifest of `version` from the fixed registry, verify its
|
|
91
|
+
* Sigstore bundle against the release workflow identity for that exact
|
|
92
|
+
* tag, schema-validate it, and check it describes `version`.
|
|
93
|
+
*
|
|
94
|
+
* @param version - SemVer without a leading `v`.
|
|
95
|
+
* @param deps - injected fetch + cosign runner (tests); defaults to the real ones.
|
|
96
|
+
*/
|
|
97
|
+
export declare function fetchVerifiedReleaseManifest(version: string, deps?: ReleaseManifestDeps): Promise<ReleaseManifestResult>;
|
|
98
|
+
/** One image whose resolved digest differs from the manifest's. */
|
|
99
|
+
export interface DigestMismatch {
|
|
100
|
+
readonly image: ReleaseImage;
|
|
101
|
+
readonly expected: string;
|
|
102
|
+
readonly actual: string | null;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Compare the digests a registry resolved for the release's tags with the
|
|
106
|
+
* signed manifest. Only images present in `resolved` are compared, except
|
|
107
|
+
* that an explicitly `null` entry (tag did not resolve) is a mismatch.
|
|
108
|
+
*
|
|
109
|
+
* @returns every mismatch; empty means the registry serves the signed images.
|
|
110
|
+
*/
|
|
111
|
+
export declare function compareImageDigests(manifest: ReleaseManifest, resolved: Partial<Record<ReleaseImage, string | null>>): DigestMismatch[];
|
|
112
|
+
/** What the installed system looks like, for {@link assessAutoInstall}. */
|
|
113
|
+
export interface InstalledRelease {
|
|
114
|
+
readonly version: string;
|
|
115
|
+
readonly infraContractVersion: number;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* How an upgrader may treat a release:
|
|
119
|
+
* - `auto` — may install unattended (if the Owner's policy allows the kind).
|
|
120
|
+
* - `manual` — installable only with the operator's own identity
|
|
121
|
+
* ("Run in Cloud Shell"); never unattended.
|
|
122
|
+
* - `refused` — not installable onto this install at all.
|
|
123
|
+
*/
|
|
124
|
+
export type InstallMode = "auto" | "manual" | "refused";
|
|
125
|
+
export interface InstallAssessment {
|
|
126
|
+
readonly mode: InstallMode;
|
|
127
|
+
/** `security` only when the manifest says so AND the release is otherwise auto-installable. */
|
|
128
|
+
readonly kind: "security" | "normal";
|
|
129
|
+
readonly reasons: readonly string[];
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Decide whether `manifest` can be installed on `installed`, and how.
|
|
133
|
+
*
|
|
134
|
+
* A security release is NOT exempt: if it carries contract migrations
|
|
135
|
+
* (or skips a release that did) or raises the infra contract, it is `manual` like any other release — the
|
|
136
|
+
* manifest still says `security`, but `kind` drops to `normal` so an
|
|
137
|
+
* "auto-install security fixes" policy never applies it unattended.
|
|
138
|
+
*/
|
|
139
|
+
export declare function assessAutoInstall(manifest: ReleaseManifest, installed: InstalledRelease): InstallAssessment;
|
|
140
|
+
//# sourceMappingURL=release-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release-manifest.d.ts","sourceRoot":"","sources":["../src/release-manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
+
/**
|
|
3
|
+
* The signed release manifest (epic #696): one JSON document per release
|
|
4
|
+
* that names the exact image digests plus the facts an upgrader needs to
|
|
5
|
+
* decide whether it may install the release on its own.
|
|
6
|
+
*
|
|
7
|
+
* Trust model. `release.yml` generates the manifest on the release tag,
|
|
8
|
+
* signs it with `cosign sign-blob` (keyless, the workflow's GitHub OIDC
|
|
9
|
+
* identity) and pushes it as an OCI artifact holding two layers — the
|
|
10
|
+
* manifest and its Sigstore bundle. Verification pins the signer to
|
|
11
|
+
* `release.yml` running on the tag `v<version>` of caelo-cms/caelo-cms,
|
|
12
|
+
* so neither a compromised admin nor a registry mirror can mint, alter or
|
|
13
|
+
* replay a manifest: changing a digest, flipping `security`, or serving
|
|
14
|
+
* v0.9's manifest as v0.10's all fail the signature or the version check.
|
|
15
|
+
* The signature rides inside the artifact (not as an OCI referrer), so
|
|
16
|
+
* any plain registry copy keeps it — the failure mode that left mirrored
|
|
17
|
+
* images unsigned (see release-images.yml, "oras copy -r") cannot apply.
|
|
18
|
+
*
|
|
19
|
+
* Errors are values: every failure carries a code plus a message that
|
|
20
|
+
* says what to check next.
|
|
21
|
+
*/
|
|
22
|
+
import { createHash } from "node:crypto";
|
|
23
|
+
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
24
|
+
import { tmpdir } from "node:os";
|
|
25
|
+
import { join } from "node:path";
|
|
26
|
+
import { z } from "zod";
|
|
27
|
+
import { IMAGE_DIGEST, RELEASE_OIDC_ISSUER, RELEASE_WORKFLOWS_URL, } from "./upgrade/release-images.js";
|
|
28
|
+
/** Release channels. Pre-release versions name theirs (`0.11.0-rc.1` → `rc`). */
|
|
29
|
+
export const RELEASE_CHANNELS = ["stable", "rc", "beta", "alpha"];
|
|
30
|
+
const SEMVER = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/;
|
|
31
|
+
const GHSA_ID = /^GHSA(-[23456789cfghjmpqrvwx]{4}){3}$/;
|
|
32
|
+
/** The services a release ships images for. */
|
|
33
|
+
export const RELEASE_IMAGES = ["admin", "gateway", "ops"];
|
|
34
|
+
const digest = z.string().regex(IMAGE_DIGEST, "expected sha256:<64 hex>");
|
|
35
|
+
/** Zod schema of `release-manifest.json` (manifestVersion 1). */
|
|
36
|
+
export const ReleaseManifestSchema = z.object({
|
|
37
|
+
manifestVersion: z.literal(1),
|
|
38
|
+
version: z.string().regex(SEMVER, "expected a SemVer version without a leading v"),
|
|
39
|
+
channel: z.enum(RELEASE_CHANNELS),
|
|
40
|
+
digests: z.object({ admin: digest, gateway: digest, ops: digest }),
|
|
41
|
+
minFromVersion: z.string().regex(SEMVER),
|
|
42
|
+
infraContractVersion: z.number().int().positive(),
|
|
43
|
+
migrations: z.object({
|
|
44
|
+
/** True when the release carries destructive (contract) migrations. */
|
|
45
|
+
contract: z.boolean(),
|
|
46
|
+
/**
|
|
47
|
+
* Newest release up to and including this one that carried contract
|
|
48
|
+
* migrations (null: none known). An install below it that jumps
|
|
49
|
+
* straight here would run those destructive steps while its old image
|
|
50
|
+
* still serves — so it is manual too, even when `contract` is false.
|
|
51
|
+
*/
|
|
52
|
+
lastContractVersion: z.string().regex(SEMVER).nullable(),
|
|
53
|
+
/** Newest cms_admin migration in the release, e.g. `0262_tool_approval_branch`. */
|
|
54
|
+
head: z.string().min(1),
|
|
55
|
+
}),
|
|
56
|
+
/** Set only via the release-cut input, backed by published GitHub Security Advisories. */
|
|
57
|
+
security: z.boolean(),
|
|
58
|
+
advisories: z.array(z.string().regex(GHSA_ID, "expected a GHSA id")),
|
|
59
|
+
});
|
|
60
|
+
/** Registry the upgrader reads manifests from — the public AR mirror Cloud Run pulls from. */
|
|
61
|
+
export const RELEASE_MANIFEST_REGISTRY = "europe-west1-docker.pkg.dev";
|
|
62
|
+
/** Repository path of the manifest artifact inside {@link RELEASE_MANIFEST_REGISTRY}. */
|
|
63
|
+
export const RELEASE_MANIFEST_REPOSITORY = "caelo-website/caelo-cms-images/release-manifest";
|
|
64
|
+
/** OCI artifact type + layer media types of the pushed manifest. */
|
|
65
|
+
export const RELEASE_MANIFEST_ARTIFACT_TYPE = "application/vnd.caelo.release-manifest.v1";
|
|
66
|
+
export const RELEASE_MANIFEST_MEDIA_TYPE = "application/vnd.caelo.release-manifest.v1+json";
|
|
67
|
+
export const SIGSTORE_BUNDLE_MEDIA_TYPE = "application/vnd.dev.sigstore.bundle.v0.3+json";
|
|
68
|
+
// The signer constants are shared with the image verification (one source).
|
|
69
|
+
export { RELEASE_OIDC_ISSUER };
|
|
70
|
+
/**
|
|
71
|
+
* The only identity allowed to sign the manifest of `version`: release.yml
|
|
72
|
+
* of caelo-cms/caelo-cms running on that exact tag. Exact, not a regex —
|
|
73
|
+
* a manifest signed on another ref (a branch, another tag) is refused.
|
|
74
|
+
*/
|
|
75
|
+
export function releaseManifestSignerIdentity(version) {
|
|
76
|
+
return `${RELEASE_WORKFLOWS_URL}/release.yml@refs/tags/v${version}`;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Compare two SemVer strings: negative when `a < b`, 0 when equal,
|
|
80
|
+
* positive when `a > b`. A pre-release sorts below its release; two
|
|
81
|
+
* pre-release tags compare by SemVer identifier rules.
|
|
82
|
+
*
|
|
83
|
+
* @throws Error when either argument is not SemVer.
|
|
84
|
+
*/
|
|
85
|
+
export function compareSemver(a, b) {
|
|
86
|
+
const ma = SEMVER.exec(a);
|
|
87
|
+
const mb = SEMVER.exec(b);
|
|
88
|
+
if (!ma || !mb)
|
|
89
|
+
throw new Error(`not a SemVer version: ${ma ? b : a}`);
|
|
90
|
+
for (let i = 1; i <= 3; i++) {
|
|
91
|
+
const d = Number(ma[i]) - Number(mb[i]);
|
|
92
|
+
if (d !== 0)
|
|
93
|
+
return d;
|
|
94
|
+
}
|
|
95
|
+
const pa = ma[4];
|
|
96
|
+
const pb = mb[4];
|
|
97
|
+
if (pa === undefined || pb === undefined) {
|
|
98
|
+
return pa === pb ? 0 : pa === undefined ? 1 : -1;
|
|
99
|
+
}
|
|
100
|
+
const ia = pa.split(".");
|
|
101
|
+
const ib = pb.split(".");
|
|
102
|
+
for (let i = 0; i < Math.max(ia.length, ib.length); i++) {
|
|
103
|
+
const x = ia[i];
|
|
104
|
+
const y = ib[i];
|
|
105
|
+
if (x === undefined)
|
|
106
|
+
return -1;
|
|
107
|
+
if (y === undefined)
|
|
108
|
+
return 1;
|
|
109
|
+
const xn = /^\d+$/.test(x);
|
|
110
|
+
const yn = /^\d+$/.test(y);
|
|
111
|
+
if (xn && yn && Number(x) !== Number(y))
|
|
112
|
+
return Number(x) - Number(y);
|
|
113
|
+
if (xn !== yn)
|
|
114
|
+
return xn ? -1 : 1;
|
|
115
|
+
if (x !== y)
|
|
116
|
+
return x < y ? -1 : 1;
|
|
117
|
+
}
|
|
118
|
+
return 0;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* The channel a version ships on.
|
|
122
|
+
*
|
|
123
|
+
* @returns null for a pre-release whose identifier names no known channel.
|
|
124
|
+
*/
|
|
125
|
+
export function channelForVersion(version) {
|
|
126
|
+
const m = SEMVER.exec(version);
|
|
127
|
+
if (!m)
|
|
128
|
+
return null;
|
|
129
|
+
if (m[4] === undefined)
|
|
130
|
+
return "stable";
|
|
131
|
+
const id = m[4].split(".")[0];
|
|
132
|
+
return RELEASE_CHANNELS.includes(id ?? "") ? id : null;
|
|
133
|
+
}
|
|
134
|
+
/** `cosign` from PATH. Missing binary → exit code 127 with a hint. */
|
|
135
|
+
async function runCosign(args) {
|
|
136
|
+
try {
|
|
137
|
+
const proc = Bun.spawn(["cosign", ...args], { stdout: "ignore", stderr: "pipe" });
|
|
138
|
+
const stderr = await new Response(proc.stderr).text();
|
|
139
|
+
return { exitCode: await proc.exited, stderr };
|
|
140
|
+
}
|
|
141
|
+
catch (e) {
|
|
142
|
+
return {
|
|
143
|
+
exitCode: 127,
|
|
144
|
+
stderr: `cosign could not be started (${e instanceof Error ? e.message : String(e)}) — install cosign (it ships in the caelo-ops image)`,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const defaultDeps = {
|
|
149
|
+
fetch: (url, init) => fetch(url, init),
|
|
150
|
+
cosign: runCosign,
|
|
151
|
+
};
|
|
152
|
+
const OciManifestSchema = z.object({
|
|
153
|
+
artifactType: z.string().optional(),
|
|
154
|
+
layers: z.array(z.object({ mediaType: z.string(), digest: z.string().regex(IMAGE_DIGEST) })),
|
|
155
|
+
});
|
|
156
|
+
function fail(code, message) {
|
|
157
|
+
return { ok: false, error: { code, message } };
|
|
158
|
+
}
|
|
159
|
+
async function fetchBlob(deps, base, layer) {
|
|
160
|
+
const res = await deps.fetch(`${base}/blobs/${layer.digest}`);
|
|
161
|
+
if (!res.ok) {
|
|
162
|
+
return { code: "registry", message: `blob ${layer.digest}: HTTP ${res.status}` };
|
|
163
|
+
}
|
|
164
|
+
const bytes = new Uint8Array(await res.arrayBuffer());
|
|
165
|
+
const actual = `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
|
|
166
|
+
if (actual !== layer.digest) {
|
|
167
|
+
return {
|
|
168
|
+
code: "blob-digest",
|
|
169
|
+
message: `blob content does not match its digest (${layer.digest} expected, ${actual} served) — the registry or a proxy altered it`,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
return bytes;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Fetch the manifest of `version` from the fixed registry, verify its
|
|
176
|
+
* Sigstore bundle against the release workflow identity for that exact
|
|
177
|
+
* tag, schema-validate it, and check it describes `version`.
|
|
178
|
+
*
|
|
179
|
+
* @param version - SemVer without a leading `v`.
|
|
180
|
+
* @param deps - injected fetch + cosign runner (tests); defaults to the real ones.
|
|
181
|
+
*/
|
|
182
|
+
export async function fetchVerifiedReleaseManifest(version, deps = defaultDeps) {
|
|
183
|
+
if (!SEMVER.test(version))
|
|
184
|
+
return fail("schema", `"${version}" is not a SemVer version`);
|
|
185
|
+
const base = `https://${deps.registry ?? RELEASE_MANIFEST_REGISTRY}/v2/${deps.repository ?? RELEASE_MANIFEST_REPOSITORY}`;
|
|
186
|
+
let artifact;
|
|
187
|
+
try {
|
|
188
|
+
const res = await deps.fetch(`${base}/manifests/${version}`, {
|
|
189
|
+
headers: { Accept: "application/vnd.oci.image.manifest.v1+json" },
|
|
190
|
+
});
|
|
191
|
+
if (!res.ok) {
|
|
192
|
+
return fail("registry", `no release manifest for v${version} at ${base} (HTTP ${res.status}). Releases before the signed manifest (epic #696) have none; otherwise check the version exists.`);
|
|
193
|
+
}
|
|
194
|
+
const parsed = OciManifestSchema.safeParse(await res.json());
|
|
195
|
+
if (!parsed.success)
|
|
196
|
+
return fail("artifact-shape", `not an OCI manifest: ${parsed.error.message}`);
|
|
197
|
+
artifact = parsed.data;
|
|
198
|
+
}
|
|
199
|
+
catch (e) {
|
|
200
|
+
return fail("registry", `registry unreachable: ${e instanceof Error ? e.message : String(e)}`);
|
|
201
|
+
}
|
|
202
|
+
if (artifact.artifactType !== RELEASE_MANIFEST_ARTIFACT_TYPE) {
|
|
203
|
+
return fail("artifact-shape", `artifactType is ${artifact.artifactType ?? "(none)"}, expected ${RELEASE_MANIFEST_ARTIFACT_TYPE}`);
|
|
204
|
+
}
|
|
205
|
+
const manifestLayers = artifact.layers.filter((l) => l.mediaType === RELEASE_MANIFEST_MEDIA_TYPE);
|
|
206
|
+
const bundleLayers = artifact.layers.filter((l) => l.mediaType === SIGSTORE_BUNDLE_MEDIA_TYPE);
|
|
207
|
+
const [manifestLayer] = manifestLayers;
|
|
208
|
+
const [bundleLayer] = bundleLayers;
|
|
209
|
+
if (manifestLayers.length !== 1 || bundleLayers.length !== 1 || !manifestLayer || !bundleLayer) {
|
|
210
|
+
return fail("artifact-shape", "the artifact must hold exactly one release-manifest layer and one Sigstore bundle layer");
|
|
211
|
+
}
|
|
212
|
+
let manifestBytes;
|
|
213
|
+
let bundleBytes;
|
|
214
|
+
try {
|
|
215
|
+
const m = await fetchBlob(deps, base, manifestLayer);
|
|
216
|
+
if (!(m instanceof Uint8Array))
|
|
217
|
+
return { ok: false, error: m };
|
|
218
|
+
const b = await fetchBlob(deps, base, bundleLayer);
|
|
219
|
+
if (!(b instanceof Uint8Array))
|
|
220
|
+
return { ok: false, error: b };
|
|
221
|
+
manifestBytes = m;
|
|
222
|
+
bundleBytes = b;
|
|
223
|
+
}
|
|
224
|
+
catch (e) {
|
|
225
|
+
return fail("registry", `registry unreachable: ${e instanceof Error ? e.message : String(e)}`);
|
|
226
|
+
}
|
|
227
|
+
// cosign verifies files, so the exact bytes go to a private temp dir.
|
|
228
|
+
const dir = await mkdtemp(join(tmpdir(), "caelo-release-manifest-"));
|
|
229
|
+
try {
|
|
230
|
+
const manifestPath = join(dir, "release-manifest.json");
|
|
231
|
+
const bundlePath = join(dir, "release-manifest.json.sigstore.json");
|
|
232
|
+
await writeFile(manifestPath, manifestBytes, { mode: 0o600 });
|
|
233
|
+
await writeFile(bundlePath, bundleBytes, { mode: 0o600 });
|
|
234
|
+
const verify = await deps.cosign([
|
|
235
|
+
"verify-blob",
|
|
236
|
+
"--bundle",
|
|
237
|
+
bundlePath,
|
|
238
|
+
"--certificate-identity",
|
|
239
|
+
releaseManifestSignerIdentity(version),
|
|
240
|
+
"--certificate-oidc-issuer",
|
|
241
|
+
RELEASE_OIDC_ISSUER,
|
|
242
|
+
manifestPath,
|
|
243
|
+
]);
|
|
244
|
+
if (verify.exitCode !== 0) {
|
|
245
|
+
return fail("signature", `the manifest of v${version} is not signed by ${releaseManifestSignerIdentity(version)} — refuse to install. cosign: ${verify.stderr.trim().slice(0, 500)}`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
finally {
|
|
249
|
+
await rm(dir, { recursive: true, force: true });
|
|
250
|
+
}
|
|
251
|
+
let json;
|
|
252
|
+
try {
|
|
253
|
+
json = JSON.parse(new TextDecoder().decode(manifestBytes));
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
return fail("schema", "the signed manifest is not valid JSON");
|
|
257
|
+
}
|
|
258
|
+
const parsed = ReleaseManifestSchema.safeParse(json);
|
|
259
|
+
if (!parsed.success) {
|
|
260
|
+
return fail("schema", `the signed manifest does not match manifestVersion 1 — this CLI may be too old to read it: ${parsed.error.message}`);
|
|
261
|
+
}
|
|
262
|
+
if (parsed.data.version !== version) {
|
|
263
|
+
return fail("version-mismatch", `asked for v${version} but the signed manifest describes v${parsed.data.version}`);
|
|
264
|
+
}
|
|
265
|
+
return { ok: true, manifest: parsed.data };
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Compare the digests a registry resolved for the release's tags with the
|
|
269
|
+
* signed manifest. Only images present in `resolved` are compared, except
|
|
270
|
+
* that an explicitly `null` entry (tag did not resolve) is a mismatch.
|
|
271
|
+
*
|
|
272
|
+
* @returns every mismatch; empty means the registry serves the signed images.
|
|
273
|
+
*/
|
|
274
|
+
export function compareImageDigests(manifest, resolved) {
|
|
275
|
+
const out = [];
|
|
276
|
+
for (const image of RELEASE_IMAGES) {
|
|
277
|
+
if (!(image in resolved))
|
|
278
|
+
continue;
|
|
279
|
+
const actual = resolved[image] ?? null;
|
|
280
|
+
if (actual !== manifest.digests[image]) {
|
|
281
|
+
out.push({ image, expected: manifest.digests[image], actual });
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return out;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Decide whether `manifest` can be installed on `installed`, and how.
|
|
288
|
+
*
|
|
289
|
+
* A security release is NOT exempt: if it carries contract migrations
|
|
290
|
+
* (or skips a release that did) or raises the infra contract, it is `manual` like any other release — the
|
|
291
|
+
* manifest still says `security`, but `kind` drops to `normal` so an
|
|
292
|
+
* "auto-install security fixes" policy never applies it unattended.
|
|
293
|
+
*/
|
|
294
|
+
export function assessAutoInstall(manifest, installed) {
|
|
295
|
+
const refused = [];
|
|
296
|
+
if (compareSemver(manifest.version, installed.version) <= 0) {
|
|
297
|
+
refused.push(`v${manifest.version} is not newer than the installed v${installed.version}`);
|
|
298
|
+
}
|
|
299
|
+
if (compareSemver(installed.version, manifest.minFromVersion) < 0) {
|
|
300
|
+
refused.push(`v${manifest.version} needs at least v${manifest.minFromVersion} installed first (installed: v${installed.version})`);
|
|
301
|
+
}
|
|
302
|
+
if (refused.length > 0)
|
|
303
|
+
return { mode: "refused", kind: "normal", reasons: refused };
|
|
304
|
+
const manual = [];
|
|
305
|
+
if (manifest.infraContractVersion > installed.infraContractVersion) {
|
|
306
|
+
manual.push(`the release changes the infrastructure contract (${installed.infraContractVersion} → ${manifest.infraContractVersion}); it must run with the operator's own identity`);
|
|
307
|
+
}
|
|
308
|
+
const lastContract = manifest.migrations.lastContractVersion;
|
|
309
|
+
if (manifest.migrations.contract) {
|
|
310
|
+
manual.push("the release carries contract (destructive) migrations");
|
|
311
|
+
}
|
|
312
|
+
else if (lastContract !== null && compareSemver(installed.version, lastContract) < 0) {
|
|
313
|
+
manual.push(`the upgrade skips v${lastContract}, whose contract (destructive) migrations would run while v${installed.version}'s image still serves`);
|
|
314
|
+
}
|
|
315
|
+
if (manual.length > 0)
|
|
316
|
+
return { mode: "manual", kind: "normal", reasons: manual };
|
|
317
|
+
return { mode: "auto", kind: manifest.security ? "security" : "normal", reasons: [] };
|
|
318
|
+
}
|
|
319
|
+
//# sourceMappingURL=release-manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release-manifest.js","sourceRoot":"","sources":["../src/release-manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A command line for this CLI, pinned to the version that is running
|
|
3
|
+
* (#696): `bunx @caelo-cms/provisioning@<this version> <args>`. Hints the
|
|
4
|
+
* CLI prints — resume the wizard, rotate a secret, check status — then
|
|
5
|
+
* run the same release the operator is using now, instead of whatever
|
|
6
|
+
* copy `bunx` cached for the bare package name.
|
|
7
|
+
*
|
|
8
|
+
* Not for upgrades: an upgrade must run as the *target* release, so
|
|
9
|
+
* `status` and the admin's Settings → Updates page build that command
|
|
10
|
+
* with the target version (`provisioningUpgradeCommand` in @caelo-cms/shared).
|
|
11
|
+
*
|
|
12
|
+
* @example selfCommand("rotate-secret", "internal-secret")
|
|
13
|
+
* // → "bunx @caelo-cms/provisioning@0.10.43 rotate-secret internal-secret"
|
|
14
|
+
*/
|
|
15
|
+
export declare function selfCommand(...args: string[]): string;
|
|
16
|
+
//# sourceMappingURL=self-command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-command.d.ts","sourceRoot":"","sources":["../src/self-command.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAErD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
+
import { CAELO_VERSION, provisioningCommand } from "@caelo-cms/shared";
|
|
3
|
+
/**
|
|
4
|
+
* A command line for this CLI, pinned to the version that is running
|
|
5
|
+
* (#696): `bunx @caelo-cms/provisioning@<this version> <args>`. Hints the
|
|
6
|
+
* CLI prints — resume the wizard, rotate a secret, check status — then
|
|
7
|
+
* run the same release the operator is using now, instead of whatever
|
|
8
|
+
* copy `bunx` cached for the bare package name.
|
|
9
|
+
*
|
|
10
|
+
* Not for upgrades: an upgrade must run as the *target* release, so
|
|
11
|
+
* `status` and the admin's Settings → Updates page build that command
|
|
12
|
+
* with the target version (`provisioningUpgradeCommand` in @caelo-cms/shared).
|
|
13
|
+
*
|
|
14
|
+
* @example selfCommand("rotate-secret", "internal-secret")
|
|
15
|
+
* // → "bunx @caelo-cms/provisioning@0.10.43 rotate-secret internal-secret"
|
|
16
|
+
*/
|
|
17
|
+
export function selfCommand(...args) {
|
|
18
|
+
return provisioningCommand(CAELO_VERSION, args);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=self-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-command.js","sourceRoot":"","sources":["../src/self-command.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAEvE;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CAAC,GAAG,IAAc;IAC3C,OAAO,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { type ReleaseImages } from "./compose.js";
|
|
2
|
+
/** What a host command returned. */
|
|
3
|
+
export interface CommandResult {
|
|
4
|
+
readonly exitCode: number;
|
|
5
|
+
readonly stdout: string;
|
|
6
|
+
readonly stderr: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Runs `docker` / `cosign` on the install's host. A seam so the install and
|
|
10
|
+
* upgrade orchestration is unit-testable with a fake (no real containers).
|
|
11
|
+
*/
|
|
12
|
+
export interface HostRunner {
|
|
13
|
+
/**
|
|
14
|
+
* Run `argv` to completion. With `stdoutPath`, stdout streams into that
|
|
15
|
+
* file (mode 600) instead of being captured — used for database dumps.
|
|
16
|
+
*/
|
|
17
|
+
run(argv: readonly string[], opts?: {
|
|
18
|
+
readonly stdoutPath?: string;
|
|
19
|
+
}): Promise<CommandResult>;
|
|
20
|
+
}
|
|
21
|
+
/** The real runner: Bun.spawn; a missing binary is exit code 127, not a throw. */
|
|
22
|
+
export declare const bunHostRunner: HostRunner;
|
|
23
|
+
/** One install / upgrade / rollback of a self-hosted install. */
|
|
24
|
+
export interface ReleaseHistoryEntry {
|
|
25
|
+
readonly at: string;
|
|
26
|
+
readonly from: string | null;
|
|
27
|
+
readonly to: string;
|
|
28
|
+
readonly outcome: "installed" | "upgraded" | "rolled-back";
|
|
29
|
+
readonly detail?: string;
|
|
30
|
+
}
|
|
31
|
+
/** `.caelo/release.json`. */
|
|
32
|
+
export interface SelfHostedRelease {
|
|
33
|
+
/** The release tag the images were resolved from (e.g. `0.10.43`). */
|
|
34
|
+
readonly version: string;
|
|
35
|
+
readonly images: {
|
|
36
|
+
readonly admin: string;
|
|
37
|
+
readonly gateway: string;
|
|
38
|
+
};
|
|
39
|
+
readonly installedAt: string;
|
|
40
|
+
/** Newest last; capped at {@link HISTORY_LIMIT}. */
|
|
41
|
+
readonly history: readonly ReleaseHistoryEntry[];
|
|
42
|
+
}
|
|
43
|
+
export declare function releasePath(caeloDir: string): string;
|
|
44
|
+
/** The images of a recorded release, as the Compose generator takes them. */
|
|
45
|
+
export declare function releaseImages(release: SelfHostedRelease): ReleaseImages;
|
|
46
|
+
/**
|
|
47
|
+
* The install's recorded release, or null when none is recorded (a dev-mode
|
|
48
|
+
* install, or one created before #696 that still runs the repo bind mount).
|
|
49
|
+
* Throws on a malformed record rather than running a guessed image.
|
|
50
|
+
*/
|
|
51
|
+
export declare function readRelease(caeloDir: string): SelfHostedRelease | null;
|
|
52
|
+
/**
|
|
53
|
+
* Record that the install now runs `images` of `version` (or, for a
|
|
54
|
+
* rollback, keeps running the previous ones), appending to the history.
|
|
55
|
+
*/
|
|
56
|
+
export declare function recordRelease(caeloDir: string, next: {
|
|
57
|
+
version: string;
|
|
58
|
+
images: ReleaseImages;
|
|
59
|
+
}, entry: Omit<ReleaseHistoryEntry, "at">, now?: Date): SelfHostedRelease;
|
|
60
|
+
/** Record a failed-and-rolled-back upgrade without changing the running release. */
|
|
61
|
+
export declare function recordRollback(caeloDir: string, current: SelfHostedRelease, attempted: string, detail: string, now?: Date): void;
|
|
62
|
+
export type VerifiedRelease = {
|
|
63
|
+
readonly ok: true;
|
|
64
|
+
readonly images: ReleaseImages;
|
|
65
|
+
} | {
|
|
66
|
+
readonly ok: false;
|
|
67
|
+
readonly error: string;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Resolve the admin + gateway images of release `tag` in GHCR to digests,
|
|
71
|
+
* then cosign-verify each digest against the Caelo release workflow
|
|
72
|
+
* identity (unless `skipVerify`, the escape hatch for forks). The returned
|
|
73
|
+
* references are digest-pinned, so what was verified is exactly what runs.
|
|
74
|
+
*/
|
|
75
|
+
export declare function resolveVerifiedRelease(tag: string, deps: {
|
|
76
|
+
readonly runner: HostRunner;
|
|
77
|
+
readonly skipVerify?: boolean;
|
|
78
|
+
readonly fetchImpl?: typeof fetch;
|
|
79
|
+
readonly onProgress?: (message: string) => void;
|
|
80
|
+
}): Promise<VerifiedRelease>;
|
|
81
|
+
//# sourceMappingURL=self-hosted-release.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-hosted-release.d.ts","sourceRoot":"","sources":["../src/self-hosted-release.ts"],"names":[],"mappings":"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"}
|