@substrat-run/control-plane-api 0.146.0 → 0.148.0
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/api.d.ts +69 -1
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +986 -383
- package/dist/api.js.map +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js.map +1 -1
- package/dist/deploy.d.ts +46 -0
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +53 -1
- package/dist/deploy.js.map +1 -1
- package/dist/errors.d.ts +19 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +18 -4
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/lake-gateway.d.ts +54 -0
- package/dist/lake-gateway.d.ts.map +1 -0
- package/dist/lake-gateway.js +158 -0
- package/dist/lake-gateway.js.map +1 -0
- package/dist/platform-entry.d.ts +23 -1
- package/dist/platform-entry.d.ts.map +1 -1
- package/dist/platform-entry.generated.d.ts +9 -1
- package/dist/platform-entry.generated.d.ts.map +1 -1
- package/dist/platform-entry.generated.js +10 -2
- package/dist/platform-entry.generated.js.map +1 -1
- package/dist/platform-entry.js +31 -1
- package/dist/platform-entry.js.map +1 -1
- package/dist/platform-scope-stores.d.ts +151 -0
- package/dist/platform-scope-stores.d.ts.map +1 -0
- package/dist/platform-scope-stores.js +241 -0
- package/dist/platform-scope-stores.js.map +1 -0
- package/dist/r2-sql-engine.d.ts +50 -0
- package/dist/r2-sql-engine.d.ts.map +1 -0
- package/dist/r2-sql-engine.js +126 -0
- package/dist/r2-sql-engine.js.map +1 -0
- package/dist/scope-copy-cleanup.d.ts +12 -0
- package/dist/scope-copy-cleanup.d.ts.map +1 -1
- package/dist/scope-copy-cleanup.js +14 -3
- package/dist/scope-copy-cleanup.js.map +1 -1
- package/dist/staff-client.d.ts +9 -1
- package/dist/staff-client.d.ts.map +1 -1
- package/dist/staff-client.js.map +1 -1
- package/dist/store-entry.d.ts +90 -0
- package/dist/store-entry.d.ts.map +1 -0
- package/dist/store-entry.generated.d.ts +60 -0
- package/dist/store-entry.generated.d.ts.map +1 -0
- package/dist/store-entry.generated.js +62 -0
- package/dist/store-entry.generated.js.map +1 -0
- package/dist/store-entry.js +178 -0
- package/dist/store-entry.js.map +1 -0
- package/dist/store-releases.d.ts +147 -0
- package/dist/store-releases.d.ts.map +1 -0
- package/dist/store-releases.js +298 -0
- package/dist/store-releases.js.map +1 -0
- package/dist/store-script.d.ts +80 -0
- package/dist/store-script.d.ts.map +1 -0
- package/dist/store-script.js +173 -0
- package/dist/store-script.js.map +1 -0
- package/dist/vertical-client.d.ts +19 -2
- package/dist/vertical-client.d.ts.map +1 -1
- package/dist/vertical-client.js +10 -1
- package/dist/vertical-client.js.map +1 -1
- package/dist/wfp.js +1 -1
- package/dist/wfp.js.map +1 -1
- package/package.json +7 -6
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A store kind's releases: stored, canaried, rolled out and rolled back (D-63, #2300).
|
|
3
|
+
*
|
|
4
|
+
* The bytes live outside the directory, content-addressed under `<kind>/<sha256>`, where the
|
|
5
|
+
* sha256 is `storeKindReleaseDigest` of the bundle, computed here when it arrives and again by
|
|
6
|
+
* the ensurer before every upload of it, restore and rollback included. The directory holds who
|
|
7
|
+
* uploaded which release from which commit, every rollout, and the current good release
|
|
8
|
+
* (`store-kind-releases.ts` in the kernel).
|
|
9
|
+
*
|
|
10
|
+
* A rollout is one request across a fleet. It holds the kind exclusively for its whole length,
|
|
11
|
+
* renewing the hold before every upload, so no push or serve rebuilds a script between the
|
|
12
|
+
* rollout's read and its upload, and two rollouts never interleave. It canaries the release on the
|
|
13
|
+
* platform's own object first, and no vertical's script moves unless every reserved operation
|
|
14
|
+
* answered there. Then it moves each vertical that ever declared the kind, at most
|
|
15
|
+
* {@link ROLLOUT_VERTICALS_PER_REQUEST} uploads per request. A bigger fleet ends the request
|
|
16
|
+
* `paused`, and posting the same rollout (or rollback) again continues it, walking past the scripts
|
|
17
|
+
* already there. A request that stops on a failure ends `failed` or `diverged`. One request walks at
|
|
18
|
+
* most {@link ROLLOUT_FLEET_MAX} verticals, a rollback included, until #2312.
|
|
19
|
+
*/
|
|
20
|
+
import { type PlatformActorId, type ReservedStoreOperation, type ScopeStoreNeed, type StoreKindRegistration } from '@substrat-run/contracts';
|
|
21
|
+
import { type HostAdmin, type StoreKindRolloutAction, type StoreKindRolloutRecord } from '@substrat-run/kernel';
|
|
22
|
+
import type { ScopeStoreEnsurerOptions, StoreKindReleaseArtifact } from './store-script.js';
|
|
23
|
+
/** Where a release's bytes are kept: an object store keyed by kind and sha256. */
|
|
24
|
+
export interface StoreReleaseBytes {
|
|
25
|
+
get(key: string): Promise<Uint8Array | undefined>;
|
|
26
|
+
put(key: string, bytes: Uint8Array): Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
/** The key a release's bytes are stored under. */
|
|
29
|
+
export declare const storeReleaseKey: (kind: string, sha256: string) => string;
|
|
30
|
+
/** How long a rollout's exclusive hold lives between renewals. */
|
|
31
|
+
export declare const ROLLOUT_HOLD_TTL_MS: number;
|
|
32
|
+
/**
|
|
33
|
+
* How long a push's or a serve's shared hold lives. It is renewed before each kind's upload; one
|
|
34
|
+
* kind's upload (a settings read and at most one upload per script) must fit inside it, or a
|
|
35
|
+
* rollout could take the kind before that upload lands. The same lease as a rollout's.
|
|
36
|
+
*/
|
|
37
|
+
export declare const PUSH_HOLD_TTL_MS: number;
|
|
38
|
+
/**
|
|
39
|
+
* The verticals one rollout request moves. Each costs a settings read and at most one upload,
|
|
40
|
+
* plus a hold renewal, so a request stays well inside a Worker invocation's subrequest budget.
|
|
41
|
+
* A fleet bigger than this is moved over several requests (the rollout answers `complete: false`).
|
|
42
|
+
*/
|
|
43
|
+
export declare const ROLLOUT_VERTICALS_PER_REQUEST = 100;
|
|
44
|
+
/**
|
|
45
|
+
* The most verticals one rollout walks. Every one costs a settings read and a hold renewal even
|
|
46
|
+
* when it is already at the release, so a bigger fleet would outrun one invocation; it is refused
|
|
47
|
+
* (409) rather than left unable to converge, and that blocks a rollback too. Raising it needs a
|
|
48
|
+
* cursor on the rollout row: #2312.
|
|
49
|
+
*/
|
|
50
|
+
export declare const ROLLOUT_FLEET_MAX = 300;
|
|
51
|
+
type LoadRelease = ScopeStoreEnsurerOptions['loadRelease'];
|
|
52
|
+
/**
|
|
53
|
+
* A release bundle as uploaded or as stored, decoded and judged: the upload body's shape, the
|
|
54
|
+
* decoded size cap, and the Python kind's module rule. Refusals are 422 (413 for the size).
|
|
55
|
+
*/
|
|
56
|
+
export declare function decodeStoreKindRelease(raw: unknown): Omit<StoreKindReleaseArtifact, 'sha256'>;
|
|
57
|
+
/**
|
|
58
|
+
* Store a release's bytes and record them (D-63: bytes may be published before the pin lands).
|
|
59
|
+
* The bytes go first, so a recorded release always has bytes; a retry of the same bundle writes
|
|
60
|
+
* the same key and records nothing new.
|
|
61
|
+
*/
|
|
62
|
+
export declare function storeKindRelease(input: {
|
|
63
|
+
admin: HostAdmin;
|
|
64
|
+
actor: PlatformActorId;
|
|
65
|
+
bytes: StoreReleaseBytes;
|
|
66
|
+
kind: string;
|
|
67
|
+
body: unknown;
|
|
68
|
+
}): Promise<import("@substrat-run/kernel").StoreKindReleaseRecord>;
|
|
69
|
+
/**
|
|
70
|
+
* The ensurer's loader over the stored bytes: a named release, or the kind's current good one.
|
|
71
|
+
* Each answer carries the sha256 it was read as, which the ensurer holds the bytes to.
|
|
72
|
+
*/
|
|
73
|
+
export declare function storedReleaseLoader(input: {
|
|
74
|
+
admin: HostAdmin;
|
|
75
|
+
actor: PlatformActorId;
|
|
76
|
+
bytes: StoreReleaseBytes;
|
|
77
|
+
}): LoadRelease;
|
|
78
|
+
/** The reserved calls a canary makes, at the canary script. */
|
|
79
|
+
export type CanaryCall = (target: {
|
|
80
|
+
scriptName: string;
|
|
81
|
+
objectName: string;
|
|
82
|
+
}, operation: ReservedStoreOperation, input?: unknown) => Promise<unknown>;
|
|
83
|
+
/**
|
|
84
|
+
* A canary object's name. Each id comes from a mint of its own, so its 80 random bits are fresh
|
|
85
|
+
* from `crypto.getRandomValues`: the shared mint would make the second id the first plus one
|
|
86
|
+
* within a millisecond, and either id would then give the other away.
|
|
87
|
+
*/
|
|
88
|
+
export declare const canaryObjectName: (binding: string) => string;
|
|
89
|
+
/**
|
|
90
|
+
* Every reserved operation, on a fresh object of the platform's own (D-63): its tenant and scope
|
|
91
|
+
* ids are new ulids, from the runtime's CSPRNG, never in the directory, and its vertical segment
|
|
92
|
+
* is no vertical's. Each answer is parsed by the call and asserted here; the first that is not
|
|
93
|
+
* what an object holding no data answers fails the canary. The object is wiped at the end.
|
|
94
|
+
*/
|
|
95
|
+
export declare function canaryStoreRelease(input: {
|
|
96
|
+
call: CanaryCall;
|
|
97
|
+
scriptName: string;
|
|
98
|
+
binding?: string;
|
|
99
|
+
}): Promise<void>;
|
|
100
|
+
export interface StoreKindRolloutDeps {
|
|
101
|
+
admin: HostAdmin;
|
|
102
|
+
actor: PlatformActorId;
|
|
103
|
+
registration: StoreKindRegistration;
|
|
104
|
+
sha256: string;
|
|
105
|
+
action: StoreKindRolloutAction;
|
|
106
|
+
/**
|
|
107
|
+
* Move one vertical's scripts of the kind to `to` (the push's ensurer, with `to`). Answers
|
|
108
|
+
* whether anything was uploaded: false for a script already there, built the same way.
|
|
109
|
+
*/
|
|
110
|
+
ensure: (input: {
|
|
111
|
+
vertical: string;
|
|
112
|
+
stores: readonly ScopeStoreNeed[];
|
|
113
|
+
to: string;
|
|
114
|
+
}) => Promise<boolean>;
|
|
115
|
+
/** Put `to` in the kind's canary script; answers its name. */
|
|
116
|
+
ensureCanary: (to: string) => Promise<{
|
|
117
|
+
scriptName: string;
|
|
118
|
+
}>;
|
|
119
|
+
callCanary: CanaryCall;
|
|
120
|
+
/** For a test: a smaller batch than {@link ROLLOUT_VERTICALS_PER_REQUEST}. */
|
|
121
|
+
perRequest?: number;
|
|
122
|
+
}
|
|
123
|
+
export interface StoreKindRolloutResult {
|
|
124
|
+
rollout: StoreKindRolloutRecord;
|
|
125
|
+
/** The verticals whose scripts this request uploaded. */
|
|
126
|
+
moved: string[];
|
|
127
|
+
/** False when verticals remain: post the same rollout again. */
|
|
128
|
+
complete: boolean;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Move every script of a kind to a stored, pinned release (D-63): hold, canary, then each
|
|
132
|
+
* vertical. A failure after a vertical moved returns every vertical it reached to the release
|
|
133
|
+
* the rollout started from, rehashing those bytes as it uploads them, and ends `failed`. It ends
|
|
134
|
+
* `diverged` instead, naming what is where, when there is nothing to return to (a kind's first
|
|
135
|
+
* rollout), when returning would lower the stored schema, or when a return fails: the next
|
|
136
|
+
* rollout or rollback converges every script. The hold is renewed before every upload, the
|
|
137
|
+
* returns included, and a hold that cannot be renewed stops everything at once: another holder
|
|
138
|
+
* may be moving the same scripts, so nothing is returned either. The hold is released however it
|
|
139
|
+
* ends.
|
|
140
|
+
*
|
|
141
|
+
* Each request uploads at most `perRequest` scripts. A vertical already at the release is
|
|
142
|
+
* walked past without counting, so posting the same rollout again continues where the last
|
|
143
|
+
* request stopped, and a fleet of any size within {@link ROLLOUT_FLEET_MAX} converges.
|
|
144
|
+
*/
|
|
145
|
+
export declare function runStoreKindRollout(deps: StoreKindRolloutDeps): Promise<StoreKindRolloutResult>;
|
|
146
|
+
export {};
|
|
147
|
+
//# sourceMappingURL=store-releases.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store-releases.d.ts","sourceRoot":"","sources":["../src/store-releases.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A store kind's releases: stored, canaried, rolled out and rolled back (D-63, #2300).
|
|
3
|
+
*
|
|
4
|
+
* The bytes live outside the directory, content-addressed under `<kind>/<sha256>`, where the
|
|
5
|
+
* sha256 is `storeKindReleaseDigest` of the bundle, computed here when it arrives and again by
|
|
6
|
+
* the ensurer before every upload of it, restore and rollback included. The directory holds who
|
|
7
|
+
* uploaded which release from which commit, every rollout, and the current good release
|
|
8
|
+
* (`store-kind-releases.ts` in the kernel).
|
|
9
|
+
*
|
|
10
|
+
* A rollout is one request across a fleet. It holds the kind exclusively for its whole length,
|
|
11
|
+
* renewing the hold before every upload, so no push or serve rebuilds a script between the
|
|
12
|
+
* rollout's read and its upload, and two rollouts never interleave. It canaries the release on the
|
|
13
|
+
* platform's own object first, and no vertical's script moves unless every reserved operation
|
|
14
|
+
* answered there. Then it moves each vertical that ever declared the kind, at most
|
|
15
|
+
* {@link ROLLOUT_VERTICALS_PER_REQUEST} uploads per request. A bigger fleet ends the request
|
|
16
|
+
* `paused`, and posting the same rollout (or rollback) again continues it, walking past the scripts
|
|
17
|
+
* already there. A request that stops on a failure ends `failed` or `diverged`. One request walks at
|
|
18
|
+
* most {@link ROLLOUT_FLEET_MAX} verticals, a rollback included, until #2312.
|
|
19
|
+
*/
|
|
20
|
+
import { STORE_RELEASE_MAX_BYTES, scopeStoreCanaryObjectName, storeKindReleaseDigest, storeKindReleaseUpload, } from '@substrat-run/contracts';
|
|
21
|
+
import { ControlPlaneError } from '@substrat-run/control-plane-client';
|
|
22
|
+
import { createUlid, ulid } from '@substrat-run/kernel';
|
|
23
|
+
import { assertPythonKindModules } from './store-entry.js';
|
|
24
|
+
/** The key a release's bytes are stored under. */
|
|
25
|
+
export const storeReleaseKey = (kind, sha256) => `${kind}/${sha256}`;
|
|
26
|
+
/** How long a rollout's exclusive hold lives between renewals. */
|
|
27
|
+
export const ROLLOUT_HOLD_TTL_MS = 10 * 60_000;
|
|
28
|
+
/**
|
|
29
|
+
* How long a push's or a serve's shared hold lives. It is renewed before each kind's upload; one
|
|
30
|
+
* kind's upload (a settings read and at most one upload per script) must fit inside it, or a
|
|
31
|
+
* rollout could take the kind before that upload lands. The same lease as a rollout's.
|
|
32
|
+
*/
|
|
33
|
+
export const PUSH_HOLD_TTL_MS = 10 * 60_000;
|
|
34
|
+
/**
|
|
35
|
+
* The verticals one rollout request moves. Each costs a settings read and at most one upload,
|
|
36
|
+
* plus a hold renewal, so a request stays well inside a Worker invocation's subrequest budget.
|
|
37
|
+
* A fleet bigger than this is moved over several requests (the rollout answers `complete: false`).
|
|
38
|
+
*/
|
|
39
|
+
export const ROLLOUT_VERTICALS_PER_REQUEST = 100;
|
|
40
|
+
/**
|
|
41
|
+
* The most verticals one rollout walks. Every one costs a settings read and a hold renewal even
|
|
42
|
+
* when it is already at the release, so a bigger fleet would outrun one invocation; it is refused
|
|
43
|
+
* (409) rather than left unable to converge, and that blocks a rollback too. Raising it needs a
|
|
44
|
+
* cursor on the rollout row: #2312.
|
|
45
|
+
*/
|
|
46
|
+
export const ROLLOUT_FLEET_MAX = 300;
|
|
47
|
+
const decodeBase64 = (text) => {
|
|
48
|
+
let binary;
|
|
49
|
+
try {
|
|
50
|
+
binary = atob(text);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
throw new ControlPlaneError(422, 'a release module is not base64');
|
|
54
|
+
}
|
|
55
|
+
return Uint8Array.from(binary, (ch) => ch.charCodeAt(0));
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* A release bundle as uploaded or as stored, decoded and judged: the upload body's shape, the
|
|
59
|
+
* decoded size cap, and the Python kind's module rule. Refusals are 422 (413 for the size).
|
|
60
|
+
*/
|
|
61
|
+
export function decodeStoreKindRelease(raw) {
|
|
62
|
+
const parsed = storeKindReleaseUpload.safeParse(raw);
|
|
63
|
+
if (!parsed.success) {
|
|
64
|
+
throw new ControlPlaneError(422, `not a store kind release: ${parsed.error.issues.map((i) => i.message).join('; ')}`);
|
|
65
|
+
}
|
|
66
|
+
let total = 0;
|
|
67
|
+
const modules = parsed.data.modules.map((module) => {
|
|
68
|
+
const content = decodeBase64(module.contentBase64);
|
|
69
|
+
total += content.byteLength;
|
|
70
|
+
if (total > STORE_RELEASE_MAX_BYTES) {
|
|
71
|
+
throw new ControlPlaneError(413, `a store kind release carries at most ${STORE_RELEASE_MAX_BYTES} module bytes`);
|
|
72
|
+
}
|
|
73
|
+
return { name: module.name, content };
|
|
74
|
+
});
|
|
75
|
+
const release = { sourceCommit: parsed.data.sourceCommit, entry: parsed.data.entry, modules };
|
|
76
|
+
try {
|
|
77
|
+
assertPythonKindModules(release);
|
|
78
|
+
}
|
|
79
|
+
catch (e) {
|
|
80
|
+
throw new ControlPlaneError(422, e instanceof Error ? e.message : String(e));
|
|
81
|
+
}
|
|
82
|
+
return release;
|
|
83
|
+
}
|
|
84
|
+
/** The stored form: the upload body again, so one decoder reads both. */
|
|
85
|
+
function encodeStoreKindRelease(release) {
|
|
86
|
+
const base64 = (bytes) => {
|
|
87
|
+
let text = '';
|
|
88
|
+
for (let i = 0; i < bytes.length; i += 0x8000)
|
|
89
|
+
text += String.fromCharCode(...bytes.subarray(i, i + 0x8000));
|
|
90
|
+
return btoa(text);
|
|
91
|
+
};
|
|
92
|
+
return new TextEncoder().encode(JSON.stringify({
|
|
93
|
+
sourceCommit: release.sourceCommit,
|
|
94
|
+
entry: release.entry,
|
|
95
|
+
modules: release.modules.map((m) => ({ name: m.name, contentBase64: base64(m.content) })),
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Store a release's bytes and record them (D-63: bytes may be published before the pin lands).
|
|
100
|
+
* The bytes go first, so a recorded release always has bytes; a retry of the same bundle writes
|
|
101
|
+
* the same key and records nothing new.
|
|
102
|
+
*/
|
|
103
|
+
export async function storeKindRelease(input) {
|
|
104
|
+
const release = decodeStoreKindRelease(input.body);
|
|
105
|
+
const sha256 = await storeKindReleaseDigest(release).catch((e) => {
|
|
106
|
+
throw new ControlPlaneError(422, e instanceof Error ? e.message : String(e));
|
|
107
|
+
});
|
|
108
|
+
const held = await input.admin.getStoreKindRelease(input.actor, input.kind, sha256);
|
|
109
|
+
if (held && held.sourceCommit !== release.sourceCommit) {
|
|
110
|
+
throw new ControlPlaneError(409, `release ${sha256} of '${input.kind}' is stored as built from ${held.sourceCommit}`);
|
|
111
|
+
}
|
|
112
|
+
if (!held)
|
|
113
|
+
await input.bytes.put(storeReleaseKey(input.kind, sha256), encodeStoreKindRelease(release));
|
|
114
|
+
return input.admin.recordStoreKindRelease(input.actor, { kind: input.kind, sha256, sourceCommit: release.sourceCommit });
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* The ensurer's loader over the stored bytes: a named release, or the kind's current good one.
|
|
118
|
+
* Each answer carries the sha256 it was read as, which the ensurer holds the bytes to.
|
|
119
|
+
*/
|
|
120
|
+
export function storedReleaseLoader(input) {
|
|
121
|
+
return async ({ kind, sha256 }) => {
|
|
122
|
+
const wanted = sha256 ?? (await input.admin.storeKindState(input.actor, kind)).current?.sha256;
|
|
123
|
+
if (!wanted)
|
|
124
|
+
return undefined;
|
|
125
|
+
const raw = await input.bytes.get(storeReleaseKey(kind, wanted));
|
|
126
|
+
if (!raw)
|
|
127
|
+
return undefined;
|
|
128
|
+
let json;
|
|
129
|
+
try {
|
|
130
|
+
json = JSON.parse(new TextDecoder().decode(raw));
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
throw new ControlPlaneError(422, `kind '${kind}' release ${wanted} is stored as something other than a release`);
|
|
134
|
+
}
|
|
135
|
+
return { ...decodeStoreKindRelease(json), sha256: wanted };
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* A canary object's name. Each id comes from a mint of its own, so its 80 random bits are fresh
|
|
140
|
+
* from `crypto.getRandomValues`: the shared mint would make the second id the first plus one
|
|
141
|
+
* within a millisecond, and either id would then give the other away.
|
|
142
|
+
*/
|
|
143
|
+
export const canaryObjectName = (binding) => scopeStoreCanaryObjectName(createUlid()(), createUlid()(), binding);
|
|
144
|
+
const tablesOf = (answer) => answer.tables;
|
|
145
|
+
/**
|
|
146
|
+
* Every reserved operation, on a fresh object of the platform's own (D-63): its tenant and scope
|
|
147
|
+
* ids are new ulids, from the runtime's CSPRNG, never in the directory, and its vertical segment
|
|
148
|
+
* is no vertical's. Each answer is parsed by the call and asserted here; the first that is not
|
|
149
|
+
* what an object holding no data answers fails the canary. The object is wiped at the end.
|
|
150
|
+
*/
|
|
151
|
+
export async function canaryStoreRelease(input) {
|
|
152
|
+
const target = { scriptName: input.scriptName, objectName: canaryObjectName(input.binding ?? 'CANARY') };
|
|
153
|
+
const step = async (operation, check, body) => {
|
|
154
|
+
let answer;
|
|
155
|
+
try {
|
|
156
|
+
answer = await input.call(target, operation, body);
|
|
157
|
+
}
|
|
158
|
+
catch (e) {
|
|
159
|
+
throw new ControlPlaneError(502, `canary refused: ${operation} failed (${e instanceof Error ? e.message : String(e)})`);
|
|
160
|
+
}
|
|
161
|
+
const wrong = check(answer);
|
|
162
|
+
if (wrong)
|
|
163
|
+
throw new ControlPlaneError(502, `canary refused: ${operation} ${wrong}`);
|
|
164
|
+
return answer;
|
|
165
|
+
};
|
|
166
|
+
const ok = () => null;
|
|
167
|
+
await step('substrat.size', ok);
|
|
168
|
+
const exported = tablesOf(await step('substrat.export', (a) => (tablesOf(a).some((t) => t.rows.length > 0) ? 'exported rows from an object holding none' : null)));
|
|
169
|
+
await step('substrat.import', (a) => (a.tables === exported.length ? null : `imported ${a.tables} of ${exported.length} tables`), { tables: exported });
|
|
170
|
+
await step('substrat.export', (a) => (JSON.stringify(tablesOf(a)) === JSON.stringify(exported) ? null : 'did not export what it imported'));
|
|
171
|
+
await step('substrat.erase', (a) => (a.erased === 0 ? null : 'erased rows of a subject the object never held'), { subjectId: ulid() });
|
|
172
|
+
await step('substrat.wipe', ok);
|
|
173
|
+
await step('substrat.export', (a) => (tablesOf(a).some((t) => t.rows.length > 0) ? 'still holds rows after its wipe' : null));
|
|
174
|
+
}
|
|
175
|
+
const message = (e) => (e instanceof Error ? e.message : String(e));
|
|
176
|
+
const schemaOf = (registration, sha256) => sha256 === null ? undefined : registration.releases.find((pin) => pin.sha256 === sha256)?.schema;
|
|
177
|
+
/** The hold lapsed, or another holder ended the rollout: nothing more may be moved under it. */
|
|
178
|
+
class HoldLost extends ControlPlaneError {
|
|
179
|
+
constructor(kind) {
|
|
180
|
+
super(409, `the hold on kind '${kind}' lapsed or its rollout was ended by another; post the rollout again to converge it`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Move every script of a kind to a stored, pinned release (D-63): hold, canary, then each
|
|
185
|
+
* vertical. A failure after a vertical moved returns every vertical it reached to the release
|
|
186
|
+
* the rollout started from, rehashing those bytes as it uploads them, and ends `failed`. It ends
|
|
187
|
+
* `diverged` instead, naming what is where, when there is nothing to return to (a kind's first
|
|
188
|
+
* rollout), when returning would lower the stored schema, or when a return fails: the next
|
|
189
|
+
* rollout or rollback converges every script. The hold is renewed before every upload, the
|
|
190
|
+
* returns included, and a hold that cannot be renewed stops everything at once: another holder
|
|
191
|
+
* may be moving the same scripts, so nothing is returned either. The hold is released however it
|
|
192
|
+
* ends.
|
|
193
|
+
*
|
|
194
|
+
* Each request uploads at most `perRequest` scripts. A vertical already at the release is
|
|
195
|
+
* walked past without counting, so posting the same rollout again continues where the last
|
|
196
|
+
* request stopped, and a fleet of any size within {@link ROLLOUT_FLEET_MAX} converges.
|
|
197
|
+
*/
|
|
198
|
+
export async function runStoreKindRollout(deps) {
|
|
199
|
+
const { admin, actor, registration, sha256 } = deps;
|
|
200
|
+
const kind = registration.kind;
|
|
201
|
+
const holder = ulid();
|
|
202
|
+
if (!(await admin.holdStoreKind(actor, { kind, holder, mode: 'exclusive', ttlMs: ROLLOUT_HOLD_TTL_MS }))) {
|
|
203
|
+
throw new ControlPlaneError(409, `kind '${kind}' is being rolled out or a vertical declaring it is being pushed; try again shortly`);
|
|
204
|
+
}
|
|
205
|
+
try {
|
|
206
|
+
const declared = await admin.storeKindDeclarations(actor, kind);
|
|
207
|
+
if (declared.unreadable.length > 0) {
|
|
208
|
+
throw new ControlPlaneError(409, `kind '${kind}' cannot be rolled out: ${declared.unreadable.join(', ')} ha${declared.unreadable.length === 1 ? 's a version' : 've versions'} whose stores cannot be named`);
|
|
209
|
+
}
|
|
210
|
+
if (declared.verticals.length > ROLLOUT_FLEET_MAX) {
|
|
211
|
+
throw new ControlPlaneError(409, `kind '${kind}' is declared by ${declared.verticals.length} verticals; a ${deps.action} walks at most ${ROLLOUT_FLEET_MAX}, so neither a rollout nor a rollback can run until rollouts page with a cursor (#2312)`);
|
|
212
|
+
}
|
|
213
|
+
const row = await admin.beginStoreKindRollout(actor, { kind, sha256, action: deps.action, holder });
|
|
214
|
+
const end = (state, detail) => admin.finishStoreKindRollout(actor, { kind, seq: row.seq, holder, state, detail });
|
|
215
|
+
const renew = async () => {
|
|
216
|
+
const held = await admin.holdStoreKind(actor, { kind, holder, mode: 'exclusive', ttlMs: ROLLOUT_HOLD_TTL_MS, renew: true, rolloutSeq: row.seq });
|
|
217
|
+
if (!held)
|
|
218
|
+
throw new HoldLost(kind);
|
|
219
|
+
};
|
|
220
|
+
try {
|
|
221
|
+
await deps.ensureCanary(sha256).then(({ scriptName }) => canaryStoreRelease({ call: deps.callCanary, scriptName }));
|
|
222
|
+
}
|
|
223
|
+
catch (e) {
|
|
224
|
+
// No vertical's script moved; the current release stays. A row the end cannot write (the
|
|
225
|
+
// hold lapsed) reads as diverged, which is what it then is.
|
|
226
|
+
await end('failed', message(e)).catch(() => undefined);
|
|
227
|
+
throw e;
|
|
228
|
+
}
|
|
229
|
+
const targets = declared.verticals.map((v) => ({ vertical: v.vertical, stores: v.stores.map((s) => ({ binding: s.binding, kind })) }));
|
|
230
|
+
const budget = deps.perRequest ?? ROLLOUT_VERTICALS_PER_REQUEST;
|
|
231
|
+
// Every vertical walked: the ones moved now, and the ones an earlier request moved.
|
|
232
|
+
const reached = [];
|
|
233
|
+
const moved = [];
|
|
234
|
+
for (const target of targets) {
|
|
235
|
+
if (moved.length >= budget) {
|
|
236
|
+
const rest = targets.length - reached.length;
|
|
237
|
+
const rollout = await end('paused', `this request moved ${moved.length}; ${rest} vertical(s) not walked yet: post the same ${deps.action} again`);
|
|
238
|
+
return { rollout, moved, complete: false };
|
|
239
|
+
}
|
|
240
|
+
try {
|
|
241
|
+
await renew();
|
|
242
|
+
reached.push(target.vertical);
|
|
243
|
+
if (await deps.ensure({ vertical: target.vertical, stores: target.stores, to: sha256 }))
|
|
244
|
+
moved.push(target.vertical);
|
|
245
|
+
}
|
|
246
|
+
catch (e) {
|
|
247
|
+
const detail = e instanceof HoldLost
|
|
248
|
+
? { state: 'diverged', text: `Nothing was returned: ${reached.join(', ') || 'no vertical'} may run ${sha256}.` }
|
|
249
|
+
: await restore(deps, row.fromSha256, reached, targets, renew);
|
|
250
|
+
await end(detail.state, `${target.vertical}: ${message(e)}. ${detail.text}`).catch(() => undefined);
|
|
251
|
+
throw new ControlPlaneError(e instanceof ControlPlaneError ? e.status : 502, `rollout of '${kind}' to ${sha256} stopped at ${target.vertical} (${message(e)}). ${detail.text}`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return { rollout: await end('good', null), moved, complete: true };
|
|
255
|
+
}
|
|
256
|
+
finally {
|
|
257
|
+
await admin.releaseStoreKindHold(actor, { kind, holder }).catch(() => undefined);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Return every vertical a failed rollout reached to the release it started from, where that is
|
|
262
|
+
* allowed, renewing the hold before each upload. A hold that cannot be renewed stops the return.
|
|
263
|
+
*/
|
|
264
|
+
async function restore(deps, from, reached, verticals, renew) {
|
|
265
|
+
if (reached.length === 0)
|
|
266
|
+
return { state: 'failed', text: 'No vertical moved.' };
|
|
267
|
+
if (from === null) {
|
|
268
|
+
return { state: 'diverged', text: `There is no earlier release to return to; ${reached.join(', ')} may run ${deps.sha256}.` };
|
|
269
|
+
}
|
|
270
|
+
const leaving = schemaOf(deps.registration, deps.sha256);
|
|
271
|
+
const returning = schemaOf(deps.registration, from);
|
|
272
|
+
if (leaving === undefined || returning === undefined || returning < leaving) {
|
|
273
|
+
return {
|
|
274
|
+
state: 'diverged',
|
|
275
|
+
text: `Returning to ${from} would lower the stored schema (${leaving} to ${returning}), so ${reached.join(', ')} may run ${deps.sha256}.`,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
const stuck = [];
|
|
279
|
+
for (const [i, vertical] of reached.entries()) {
|
|
280
|
+
try {
|
|
281
|
+
await renew();
|
|
282
|
+
}
|
|
283
|
+
catch {
|
|
284
|
+
return { state: 'diverged', text: `The hold was lost while returning; ${reached.slice(i).join(', ')} may run ${deps.sha256}.` };
|
|
285
|
+
}
|
|
286
|
+
const target = verticals.find((v) => v.vertical === vertical);
|
|
287
|
+
try {
|
|
288
|
+
await deps.ensure({ vertical, stores: target.stores, to: from });
|
|
289
|
+
}
|
|
290
|
+
catch (e) {
|
|
291
|
+
stuck.push(`${vertical} (${message(e)})`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return stuck.length === 0
|
|
295
|
+
? { state: 'failed', text: `${reached.join(', ')} returned to ${from}.` }
|
|
296
|
+
: { state: 'diverged', text: `Could not return ${stuck.join(', ')} to ${from}.` };
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=store-releases.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store-releases.js","sourceRoot":"","sources":["../src/store-releases.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { type ScopeStoreNeed, type StoreKindRegistration } from '@substrat-run/contracts';
|
|
2
|
+
import { type PythonStoreKindRelease } from './store-entry.js';
|
|
3
|
+
/**
|
|
4
|
+
* The binding that records which pinned release a store script runs: the release bundle's
|
|
5
|
+
* sha256 (D-63). In the entry's reserved prefix, so the kind's env never carries it.
|
|
6
|
+
*/
|
|
7
|
+
export declare const STORE_RELEASE_VAR = "SUBSTRAT_STORE_RELEASE";
|
|
8
|
+
/**
|
|
9
|
+
* The binding that records what else the script was built from: a digest over every module the
|
|
10
|
+
* upload sent and its configuration. A changed entry, verifier, key list or flag changes it.
|
|
11
|
+
*/
|
|
12
|
+
export declare const STORE_BUILD_VAR = "SUBSTRAT_STORE_BUILD";
|
|
13
|
+
/** One release of a kind's code, as the publish flow stores it (#2297). */
|
|
14
|
+
export interface StoreKindReleaseArtifact extends PythonStoreKindRelease {
|
|
15
|
+
/** The commit the bundle was built from. A reviewer reads it; the upload checks the sha256. */
|
|
16
|
+
readonly sourceCommit: string;
|
|
17
|
+
/**
|
|
18
|
+
* The sha256 the loader read these bytes as (its storage key). When present, the bytes must
|
|
19
|
+
* hash to it, so a store that answers other bytes under a key is refused, not uploaded.
|
|
20
|
+
*/
|
|
21
|
+
readonly sha256?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface ScopeStoreEnsurerOptions {
|
|
24
|
+
accountId: string;
|
|
25
|
+
namespace: string;
|
|
26
|
+
apiToken: string;
|
|
27
|
+
/** The `caller` audience's public keys, raw Ed25519, base64url. A list, so a key can rotate. */
|
|
28
|
+
callerPublicKeys: readonly string[];
|
|
29
|
+
/** The `platform` audience's public keys, in the same form. Never one of the caller's. */
|
|
30
|
+
platformPublicKeys: readonly string[];
|
|
31
|
+
kinds?: readonly StoreKindRegistration[];
|
|
32
|
+
/**
|
|
33
|
+
* A release's bytes. With `sha256`, that release: the one the script runs, or the one a
|
|
34
|
+
* rollout moves it to. Without it, the kind's current good release (#2300). Undefined when
|
|
35
|
+
* there is none.
|
|
36
|
+
*/
|
|
37
|
+
loadRelease: (input: {
|
|
38
|
+
readonly kind: string;
|
|
39
|
+
readonly vertical: string;
|
|
40
|
+
readonly sha256?: string;
|
|
41
|
+
}) => Promise<StoreKindReleaseArtifact | undefined>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Put every (kind, vertical) store script a vertical's stores need in place, before the
|
|
45
|
+
* vertical's own upload (#2210, D-63). A push or a serve never moves a script to another
|
|
46
|
+
* release: only a rollout or a rollback does (#2300), and it says so with `to`.
|
|
47
|
+
*
|
|
48
|
+
* - No `to`, no script yet: it is uploaded at the kind's current good release.
|
|
49
|
+
* - No `to`, a script: it is rebuilt at the release it already runs, and uploaded again only when
|
|
50
|
+
* what it was built from changed (the platform's entry, the verifier, a key list, a flag), so a
|
|
51
|
+
* fix or a key rotation reaches it without a release moving.
|
|
52
|
+
* - `to`: the script is moved to that release, or left alone when it already runs it, built the
|
|
53
|
+
* same way. Re-running a rollout therefore converges and uploads nothing twice.
|
|
54
|
+
*
|
|
55
|
+
* Every upload hashes the module bytes it is about to send and refuses (422) bytes whose
|
|
56
|
+
* sha256 the kind's registration does not pin, or that are not the release asked for. A kind
|
|
57
|
+
* with no release to run is refused (409). A script is never moved to a release whose pinned
|
|
58
|
+
* `schema` is lower than that of the release it runs (409): its objects may have migrated. The
|
|
59
|
+
* runtime's own failures are 502. Answers how many scripts were uploaded.
|
|
60
|
+
*/
|
|
61
|
+
export declare function createScopeStoreEnsurer(opts: ScopeStoreEnsurerOptions): (input: {
|
|
62
|
+
vertical: string;
|
|
63
|
+
stores: readonly ScopeStoreNeed[];
|
|
64
|
+
to?: string;
|
|
65
|
+
}) => Promise<{
|
|
66
|
+
uploaded: number;
|
|
67
|
+
}>;
|
|
68
|
+
/**
|
|
69
|
+
* Put a kind's release in the platform's canary script (D-63, #2300), where it is canaried
|
|
70
|
+
* before any vertical's script moves: `scopeStoreCanaryScriptName(kind)`, built and checked as a
|
|
71
|
+
* vertical's script is, except that it may move to a lower `schema`: every canary object is fresh
|
|
72
|
+
* and wiped, so none holds migrated data. Answers the script's name.
|
|
73
|
+
*/
|
|
74
|
+
export declare function createStoreCanaryEnsurer(opts: ScopeStoreEnsurerOptions): (input: {
|
|
75
|
+
kind: string;
|
|
76
|
+
to: string;
|
|
77
|
+
}) => Promise<{
|
|
78
|
+
scriptName: string;
|
|
79
|
+
}>;
|
|
80
|
+
//# sourceMappingURL=store-script.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store-script.d.ts","sourceRoot":"","sources":["../src/store-script.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAE3B,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EAAwB,KAAK,sBAAsB,EAA0B,MAAM,kBAAkB,CAAC;AAE7G;;;GAGG;AACH,eAAO,MAAM,iBAAiB,2BAA6C,CAAC;AAE5E;;;GAGG;AACH,eAAO,MAAM,eAAe,yBAA2C,CAAC;AAExE,2EAA2E;AAC3E,MAAM,WAAW,wBAAyB,SAAQ,sBAAsB;IACtE,+FAA+F;IAC/F,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,gGAAgG;IAChG,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,0FAA0F;IAC1F,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,KAAK,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACzC;;;;OAIG;IACH,WAAW,EAAE,CAAC,KAAK,EAAE;QACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;KAC1B,KAAK,OAAO,CAAC,wBAAwB,GAAG,SAAS,CAAC,CAAC;CACrD;AAYD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,wBAAwB,WAE/C;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,KAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAM1H;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,wBAAwB,WAEhD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,KAAG,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAWpF"}
|