rightsize 0.3.0 → 0.4.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/README.md +27 -25
- package/dist/backend-docker/backend.d.ts +14 -0
- package/dist/backend-docker/backend.d.ts.map +1 -1
- package/dist/backend-docker/backend.js +28 -0
- package/dist/backend-docker/backend.js.map +1 -1
- package/dist/backend-docker/cli.d.ts +4 -0
- package/dist/backend-docker/cli.d.ts.map +1 -1
- package/dist/backend-docker/cli.js +8 -0
- package/dist/backend-docker/cli.js.map +1 -1
- package/dist/backend-msb/backend.d.ts +30 -0
- package/dist/backend-msb/backend.d.ts.map +1 -1
- package/dist/backend-msb/backend.js +64 -0
- package/dist/backend-msb/backend.js.map +1 -1
- package/dist/backend-msb/commands.d.ts +6 -0
- package/dist/backend-msb/commands.d.ts.map +1 -1
- package/dist/backend-msb/commands.js +12 -0
- package/dist/backend-msb/commands.js.map +1 -1
- package/dist/backend-msb/snapshot-import.d.ts +33 -0
- package/dist/backend-msb/snapshot-import.d.ts.map +1 -0
- package/dist/backend-msb/snapshot-import.js +48 -0
- package/dist/backend-msb/snapshot-import.js.map +1 -0
- package/dist/backend-msb/snapshot-list.d.ts +43 -0
- package/dist/backend-msb/snapshot-list.d.ts.map +1 -0
- package/dist/backend-msb/snapshot-list.js +53 -0
- package/dist/backend-msb/snapshot-list.js.map +1 -0
- package/dist/core/backend.d.ts +29 -0
- package/dist/core/backend.d.ts.map +1 -1
- package/dist/core/checkpoint/api.d.ts +49 -0
- package/dist/core/checkpoint/api.d.ts.map +1 -1
- package/dist/core/checkpoint/api.js +124 -1
- package/dist/core/checkpoint/api.js.map +1 -1
- package/dist/core/checkpoint/archive.d.ts +52 -0
- package/dist/core/checkpoint/archive.d.ts.map +1 -0
- package/dist/core/checkpoint/archive.js +134 -0
- package/dist/core/checkpoint/archive.js.map +1 -0
- package/dist/core/checkpoint/registry.d.ts +2 -0
- package/dist/core/checkpoint/registry.d.ts.map +1 -1
- package/dist/core/checkpoint/registry.js +2 -1
- package/dist/core/checkpoint/registry.js.map +1 -1
- package/dist/core/checkpoint/tar-cli.d.ts +45 -0
- package/dist/core/checkpoint/tar-cli.d.ts.map +1 -0
- package/dist/core/checkpoint/tar-cli.js +86 -0
- package/dist/core/checkpoint/tar-cli.js.map +1 -0
- package/dist/core/errors.d.ts +37 -0
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +44 -0
- package/dist/core/errors.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -14,6 +14,12 @@ export declare const MsbCommands: {
|
|
|
14
14
|
snapshotRemove(name: string): string[];
|
|
15
15
|
/** `msb snapshot inspect <name>` — exit 0 means the snapshot exists, non-zero means it doesn't; `hasCheckpoint`'s backend call. */
|
|
16
16
|
snapshotInspect(name: string): string[];
|
|
17
|
+
/** `msb snapshot export <ref> <dest>` — writes a `.tar.zst` artifact archive; deliberately never `--with-image` (its import fails an integrity check in 0.6.6, see the checkpoints guide). `exportCheckpoint`'s backend call. */
|
|
18
|
+
snapshotExport(ref: string, dest: string): string[];
|
|
19
|
+
/** `msb snapshot import <archive>` — unpacks into a digest-derived directory under `~/.microsandbox/snapshots/`, never the original name; `importCheckpoint`'s backend call. */
|
|
20
|
+
snapshotImport(archive: string): string[];
|
|
21
|
+
/** `msb snapshot list --format json` — full `digest`/`name`/`artifact_path`/`image_ref` entries, used to CONFIRM an imported snapshot's digest-dir basename is present (the basename itself, not the `digest` field, is the effective ref — the full digest does not resolve as a snapshot ref). */
|
|
22
|
+
snapshotList(): string[];
|
|
17
23
|
/** `msb copy -q <hostPath> <name>:<containerPath>` — host-to-guest transfer, `cp -r`-style destination naming for a directory source. */
|
|
18
24
|
copyIn(hostPath: string, name: string, containerPath: string): string[];
|
|
19
25
|
/** `msb copy -q <name>:<containerPath> <hostPath>` — the reverse direction of `copyIn`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/backend-msb/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD;;;;;;GAMG;AACH,eAAO,MAAM,WAAW;cACZ,aAAa,GAAG,MAAM,EAAE;IAgClC,0JAA0J;4BAClI,MAAM,QAAQ,MAAM,GAAG,MAAM,EAAE;IAIvD,yGAAyG;yBACpF,MAAM,GAAG,MAAM,EAAE;IAItC,mIAAmI;0BAC7G,MAAM,GAAG,MAAM,EAAE;IAIvC,yIAAyI;qBACxH,MAAM,QAAQ,MAAM,iBAAiB,MAAM,GAAG,MAAM,EAAE;IAIvE,2FAA2F;kBAC7E,MAAM,iBAAiB,MAAM,YAAY,MAAM,GAAG,MAAM,EAAE;eAI7D,MAAM,OAAO,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE;qBAInC,MAAM,OAAO,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE;eAI/C,MAAM,GAAG,MAAM,EAAE;qBAIX,MAAM,GAAG,MAAM,EAAE;eAIvB,MAAM,GAAG,MAAM,EAAE;aAInB,MAAM,GAAG,MAAM,EAAE;UAIpB,MAAM,EAAE;IAKd;;;;;;;OAOG;2BACoB,MAAM,GAAG,MAAM,EAAE;CAGzC,CAAC"}
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/backend-msb/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD;;;;;;GAMG;AACH,eAAO,MAAM,WAAW;cACZ,aAAa,GAAG,MAAM,EAAE;IAgClC,0JAA0J;4BAClI,MAAM,QAAQ,MAAM,GAAG,MAAM,EAAE;IAIvD,yGAAyG;yBACpF,MAAM,GAAG,MAAM,EAAE;IAItC,mIAAmI;0BAC7G,MAAM,GAAG,MAAM,EAAE;IAIvC,iOAAiO;wBAC7M,MAAM,QAAQ,MAAM,GAAG,MAAM,EAAE;IAInD,gLAAgL;4BACxJ,MAAM,GAAG,MAAM,EAAE;IAIzC,oSAAoS;oBACpR,MAAM,EAAE;IAIxB,yIAAyI;qBACxH,MAAM,QAAQ,MAAM,iBAAiB,MAAM,GAAG,MAAM,EAAE;IAIvE,2FAA2F;kBAC7E,MAAM,iBAAiB,MAAM,YAAY,MAAM,GAAG,MAAM,EAAE;eAI7D,MAAM,OAAO,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE;qBAInC,MAAM,OAAO,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE;eAI/C,MAAM,GAAG,MAAM,EAAE;qBAIX,MAAM,GAAG,MAAM,EAAE;eAIvB,MAAM,GAAG,MAAM,EAAE;aAInB,MAAM,GAAG,MAAM,EAAE;UAIpB,MAAM,EAAE;IAKd;;;;;;;OAOG;2BACoB,MAAM,GAAG,MAAM,EAAE;CAGzC,CAAC"}
|
|
@@ -50,6 +50,18 @@ export const MsbCommands = {
|
|
|
50
50
|
snapshotInspect(name) {
|
|
51
51
|
return ["snapshot", "inspect", name];
|
|
52
52
|
},
|
|
53
|
+
/** `msb snapshot export <ref> <dest>` — writes a `.tar.zst` artifact archive; deliberately never `--with-image` (its import fails an integrity check in 0.6.6, see the checkpoints guide). `exportCheckpoint`'s backend call. */
|
|
54
|
+
snapshotExport(ref, dest) {
|
|
55
|
+
return ["snapshot", "export", ref, dest];
|
|
56
|
+
},
|
|
57
|
+
/** `msb snapshot import <archive>` — unpacks into a digest-derived directory under `~/.microsandbox/snapshots/`, never the original name; `importCheckpoint`'s backend call. */
|
|
58
|
+
snapshotImport(archive) {
|
|
59
|
+
return ["snapshot", "import", archive];
|
|
60
|
+
},
|
|
61
|
+
/** `msb snapshot list --format json` — full `digest`/`name`/`artifact_path`/`image_ref` entries, used to CONFIRM an imported snapshot's digest-dir basename is present (the basename itself, not the `digest` field, is the effective ref — the full digest does not resolve as a snapshot ref). */
|
|
62
|
+
snapshotList() {
|
|
63
|
+
return ["snapshot", "list", "--format", "json"];
|
|
64
|
+
},
|
|
53
65
|
/** `msb copy -q <hostPath> <name>:<containerPath>` — host-to-guest transfer, `cp -r`-style destination naming for a directory source. */
|
|
54
66
|
copyIn(hostPath, name, containerPath) {
|
|
55
67
|
return ["copy", "-q", hostPath, `${name}:${containerPath}`];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/backend-msb/commands.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/backend-msb/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* True if `stderr` (an `msb snapshot import` non-zero exit) names msb's own
|
|
3
|
+
* "this digest is already imported" signal, as opposed to some other import
|
|
4
|
+
* failure. Observed verbatim against the real msb 0.6.6 binary:
|
|
5
|
+
*
|
|
6
|
+
* ```
|
|
7
|
+
* error: snapshot already exists: <path>
|
|
8
|
+
* ```
|
|
9
|
+
*
|
|
10
|
+
* For a content-addressed archive this IS success — the artifact is already
|
|
11
|
+
* present under that digest either way — so `importCheckpoint` treats it as
|
|
12
|
+
* one rather than surfacing it. Deliberately a substring match on the stable
|
|
13
|
+
* prefix, the same reasoning `isSnapshotNotFoundError` applies to its own
|
|
14
|
+
* wording: the trailing path varies per host and msb has no structured/typed
|
|
15
|
+
* error for this.
|
|
16
|
+
*/
|
|
17
|
+
export declare function isSnapshotAlreadyExistsError(stderr: string): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Extracts the digest-dir basename from one `msb snapshot import`
|
|
20
|
+
* invocation's output. Verified against the real msb 0.6.6 binary: on both a
|
|
21
|
+
* success (the printed stdout line) and an already-exists failure (the
|
|
22
|
+
* `error: snapshot already exists: <path>` stderr line), the relevant line
|
|
23
|
+
* ENDS with the artifact path under `~/.microsandbox/snapshots/`, whose
|
|
24
|
+
* basename is the digest-derived directory name (e.g.
|
|
25
|
+
* `sha256-b9c0448ee9d54e33`) — never the original archive's own recorded
|
|
26
|
+
* ref. Callers pass whichever stream actually carries the signal (stdout on
|
|
27
|
+
* success, stderr on an already-exists failure). `undefined` means the
|
|
28
|
+
* output carried no recognizable trailing path — a shape this backend
|
|
29
|
+
* doesn't understand, which the caller turns into its own actionable error
|
|
30
|
+
* rather than guessing.
|
|
31
|
+
*/
|
|
32
|
+
export declare function parseImportedDigestDirName(output: string): string | undefined;
|
|
33
|
+
//# sourceMappingURL=snapshot-import.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-import.d.ts","sourceRoot":"","sources":["../../src/backend-msb/snapshot-import.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEpE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAY7E"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
/**
|
|
3
|
+
* True if `stderr` (an `msb snapshot import` non-zero exit) names msb's own
|
|
4
|
+
* "this digest is already imported" signal, as opposed to some other import
|
|
5
|
+
* failure. Observed verbatim against the real msb 0.6.6 binary:
|
|
6
|
+
*
|
|
7
|
+
* ```
|
|
8
|
+
* error: snapshot already exists: <path>
|
|
9
|
+
* ```
|
|
10
|
+
*
|
|
11
|
+
* For a content-addressed archive this IS success — the artifact is already
|
|
12
|
+
* present under that digest either way — so `importCheckpoint` treats it as
|
|
13
|
+
* one rather than surfacing it. Deliberately a substring match on the stable
|
|
14
|
+
* prefix, the same reasoning `isSnapshotNotFoundError` applies to its own
|
|
15
|
+
* wording: the trailing path varies per host and msb has no structured/typed
|
|
16
|
+
* error for this.
|
|
17
|
+
*/
|
|
18
|
+
export function isSnapshotAlreadyExistsError(stderr) {
|
|
19
|
+
return stderr.includes("snapshot already exists");
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Extracts the digest-dir basename from one `msb snapshot import`
|
|
23
|
+
* invocation's output. Verified against the real msb 0.6.6 binary: on both a
|
|
24
|
+
* success (the printed stdout line) and an already-exists failure (the
|
|
25
|
+
* `error: snapshot already exists: <path>` stderr line), the relevant line
|
|
26
|
+
* ENDS with the artifact path under `~/.microsandbox/snapshots/`, whose
|
|
27
|
+
* basename is the digest-derived directory name (e.g.
|
|
28
|
+
* `sha256-b9c0448ee9d54e33`) — never the original archive's own recorded
|
|
29
|
+
* ref. Callers pass whichever stream actually carries the signal (stdout on
|
|
30
|
+
* success, stderr on an already-exists failure). `undefined` means the
|
|
31
|
+
* output carried no recognizable trailing path — a shape this backend
|
|
32
|
+
* doesn't understand, which the caller turns into its own actionable error
|
|
33
|
+
* rather than guessing.
|
|
34
|
+
*/
|
|
35
|
+
export function parseImportedDigestDirName(output) {
|
|
36
|
+
const lines = output
|
|
37
|
+
.split("\n")
|
|
38
|
+
.map((line) => line.trim())
|
|
39
|
+
.filter((line) => line.length > 0);
|
|
40
|
+
const lastLine = lines.at(-1);
|
|
41
|
+
if (lastLine === undefined) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
const match = /(\S+)\s*$/.exec(lastLine);
|
|
45
|
+
const artifactPath = match?.[1];
|
|
46
|
+
return artifactPath === undefined ? undefined : path.basename(artifactPath);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=snapshot-import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-import.js","sourceRoot":"","sources":["../../src/backend-msb/snapshot-import.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,4BAA4B,CAAC,MAAc;IACzD,OAAO,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,0BAA0B,CAAC,MAAc;IACvD,MAAM,KAAK,GAAG,MAAM;SACjB,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzC,MAAM,YAAY,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IAChC,OAAO,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;AAC9E,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One `msb snapshot list --format json` entry, the fields
|
|
3
|
+
* `importCheckpoint`'s presence check actually reads. The current msb
|
|
4
|
+
* release's shape carries more fields than this (created/size/...); only
|
|
5
|
+
* `digest`, `name`, and `artifact_path` (snake_case on the wire) matter
|
|
6
|
+
* here, so everything else is ignored rather than modeled. `digest` itself
|
|
7
|
+
* is never returned as an effective ref (see `confirmDigestDirNamePresent`)
|
|
8
|
+
* — it is read only to skip a malformed/empty entry.
|
|
9
|
+
*/
|
|
10
|
+
export interface SnapshotListEntry {
|
|
11
|
+
readonly digest: string | undefined;
|
|
12
|
+
readonly name: string | undefined;
|
|
13
|
+
readonly artifactPath: string | undefined;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Parses `msb snapshot list --format json`'s array-of-objects output.
|
|
17
|
+
* Malformed/non-array JSON resolves to an empty list rather than throwing —
|
|
18
|
+
* the caller (`importCheckpoint`) already turns "digest not found" into its
|
|
19
|
+
* own actionable `BackendError`, so a parse failure here degrading to "found
|
|
20
|
+
* nothing" produces the same class of error rather than a confusing crash
|
|
21
|
+
* one level removed from the actual msb output.
|
|
22
|
+
*/
|
|
23
|
+
export declare function parseSnapshotList(json: string): SnapshotListEntry[];
|
|
24
|
+
/**
|
|
25
|
+
* Confirms an imported snapshot's digest-dir basename (e.g.
|
|
26
|
+
* `sha256-b9c0448ee9d54e33`, parsed from `msb snapshot import`'s own
|
|
27
|
+
* output — see `snapshot-import.ts`) actually appears in `msb snapshot
|
|
28
|
+
* list`: an entry whose `name` equals `digestDirName` outright, or whose
|
|
29
|
+
* `artifact_path`'s basename does (`msb snapshot list` was verified to
|
|
30
|
+
* report both shapes depending on how the snapshot was created).
|
|
31
|
+
*
|
|
32
|
+
* Returns `digestDirName` itself once confirmed present — NOT the entry's
|
|
33
|
+
* `digest` field. Live-verified against msb 0.6.6: the full
|
|
34
|
+
* `sha256:<64hex>` digest does not resolve as a snapshot ref at all (`msb
|
|
35
|
+
* snapshot inspect sha256:<full>` fails "snapshot not found" — msb treats
|
|
36
|
+
* it as a literal path). Only the digest-dir name resolves for
|
|
37
|
+
* `inspect`/`rm`/`run --snapshot`, so it — not the `digest` field — is the
|
|
38
|
+
* effective ref `importCheckpoint` must hand back. `undefined` means no
|
|
39
|
+
* entry matched — the caller throws rather than returning an unconfirmed
|
|
40
|
+
* ref.
|
|
41
|
+
*/
|
|
42
|
+
export declare function confirmDigestDirNamePresent(entries: readonly SnapshotListEntry[], digestDirName: string): string | undefined;
|
|
43
|
+
//# sourceMappingURL=snapshot-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-list.d.ts","sourceRoot":"","sources":["../../src/backend-msb/snapshot-list.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3C;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAkBnE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAO5H"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
/**
|
|
3
|
+
* Parses `msb snapshot list --format json`'s array-of-objects output.
|
|
4
|
+
* Malformed/non-array JSON resolves to an empty list rather than throwing —
|
|
5
|
+
* the caller (`importCheckpoint`) already turns "digest not found" into its
|
|
6
|
+
* own actionable `BackendError`, so a parse failure here degrading to "found
|
|
7
|
+
* nothing" produces the same class of error rather than a confusing crash
|
|
8
|
+
* one level removed from the actual msb output.
|
|
9
|
+
*/
|
|
10
|
+
export function parseSnapshotList(json) {
|
|
11
|
+
let parsed;
|
|
12
|
+
try {
|
|
13
|
+
parsed = JSON.parse(json);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
if (!Array.isArray(parsed)) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
return parsed.map((raw) => {
|
|
22
|
+
const rec = (typeof raw === "object" && raw !== null ? raw : {});
|
|
23
|
+
return {
|
|
24
|
+
digest: typeof rec["digest"] === "string" ? rec["digest"] : undefined,
|
|
25
|
+
name: typeof rec["name"] === "string" ? rec["name"] : undefined,
|
|
26
|
+
artifactPath: typeof rec["artifact_path"] === "string" ? rec["artifact_path"] : undefined,
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Confirms an imported snapshot's digest-dir basename (e.g.
|
|
32
|
+
* `sha256-b9c0448ee9d54e33`, parsed from `msb snapshot import`'s own
|
|
33
|
+
* output — see `snapshot-import.ts`) actually appears in `msb snapshot
|
|
34
|
+
* list`: an entry whose `name` equals `digestDirName` outright, or whose
|
|
35
|
+
* `artifact_path`'s basename does (`msb snapshot list` was verified to
|
|
36
|
+
* report both shapes depending on how the snapshot was created).
|
|
37
|
+
*
|
|
38
|
+
* Returns `digestDirName` itself once confirmed present — NOT the entry's
|
|
39
|
+
* `digest` field. Live-verified against msb 0.6.6: the full
|
|
40
|
+
* `sha256:<64hex>` digest does not resolve as a snapshot ref at all (`msb
|
|
41
|
+
* snapshot inspect sha256:<full>` fails "snapshot not found" — msb treats
|
|
42
|
+
* it as a literal path). Only the digest-dir name resolves for
|
|
43
|
+
* `inspect`/`rm`/`run --snapshot`, so it — not the `digest` field — is the
|
|
44
|
+
* effective ref `importCheckpoint` must hand back. `undefined` means no
|
|
45
|
+
* entry matched — the caller throws rather than returning an unconfirmed
|
|
46
|
+
* ref.
|
|
47
|
+
*/
|
|
48
|
+
export function confirmDigestDirNamePresent(entries, digestDirName) {
|
|
49
|
+
const present = entries.some((entry) => entry.digest !== undefined &&
|
|
50
|
+
(entry.name === digestDirName || (entry.artifactPath !== undefined && path.basename(entry.artifactPath) === digestDirName)));
|
|
51
|
+
return present ? digestDirName : undefined;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=snapshot-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-list.js","sourceRoot":"","sources":["../../src/backend-msb/snapshot-list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAiBlC;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAqB,EAAE;QAC3C,MAAM,GAAG,GAAG,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAA4B,CAAC;QAC5F,OAAO;YACL,MAAM,EAAE,OAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS;YACrE,IAAI,EAAE,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;YAC/D,YAAY,EAAE,OAAO,GAAG,CAAC,eAAe,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS;SAC1F,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,2BAA2B,CAAC,OAAqC,EAAE,aAAqB;IACtG,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAC1B,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,CAAC,MAAM,KAAK,SAAS;QAC1B,CAAC,KAAK,CAAC,IAAI,KAAK,aAAa,IAAI,CAAC,KAAK,CAAC,YAAY,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,aAAa,CAAC,CAAC,CAC9H,CAAC;IACF,OAAO,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7C,CAAC"}
|
package/dist/core/backend.d.ts
CHANGED
|
@@ -135,6 +135,35 @@ export interface SandboxBackend {
|
|
|
135
135
|
* not allowed.
|
|
136
136
|
*/
|
|
137
137
|
hasCheckpoint(ref: string): Promise<boolean>;
|
|
138
|
+
/**
|
|
139
|
+
* Writes this checkpoint's backend payload to `destFile` — the artifact
|
|
140
|
+
* step of `Checkpoints.exportTo`, byte-for-byte what the backend's own CLI
|
|
141
|
+
* produces (docker: `docker save -o <destFile> <ref>`; microsandbox:
|
|
142
|
+
* `msb snapshot export <ref> <destFile>`, never `--with-image` — see the
|
|
143
|
+
* checkpoints guide for why). Only ever called once the generic layer has
|
|
144
|
+
* already confirmed `ref` belongs to the ACTIVE backend and probed it
|
|
145
|
+
* exists via `hasCheckpoint`; a failure surfaces the underlying tool's
|
|
146
|
+
* stderr in a `BackendError`, the same convention `copyToContainer` uses.
|
|
147
|
+
*/
|
|
148
|
+
exportCheckpoint(ref: string, destFile: string): Promise<void>;
|
|
149
|
+
/**
|
|
150
|
+
* Materializes an exported archive's backend payload from `srcFile` and
|
|
151
|
+
* returns the EFFECTIVE ref to use from here on — not necessarily `ref`
|
|
152
|
+
* itself. docker preserves the original tag on `docker load`, so its
|
|
153
|
+
* effective ref IS `ref`; microsandbox's `snapshot import` writes under a
|
|
154
|
+
* digest-derived DIRECTORY NAME (e.g. `sha256-b9c0448ee9d54e33`) it never
|
|
155
|
+
* lets the caller choose, so its effective ref is that directory name,
|
|
156
|
+
* confirmed present via `snapshot list --format json` — never the full
|
|
157
|
+
* `sha256:<64hex>` digest, which does not resolve as a snapshot ref at
|
|
158
|
+
* all. An already-exists failure for a content-addressed archive is
|
|
159
|
+
* treated as success. `ref` is the archive's own recorded ref (from
|
|
160
|
+
* `checkpoint.json`), passed through for backends (docker) that have no
|
|
161
|
+
* new ref to derive. Only ever called once the generic layer has already
|
|
162
|
+
* validated the archive's `checkpoint.json` (version, name, backend)
|
|
163
|
+
* against the active backend; any failure other than "already imported"
|
|
164
|
+
* surfaces the underlying tool's stderr in a `BackendError`.
|
|
165
|
+
*/
|
|
166
|
+
importCheckpoint(srcFile: string, ref: string): Promise<string>;
|
|
138
167
|
/**
|
|
139
168
|
* Best-effort stop+remove of a sandbox identified by NAME rather than a
|
|
140
169
|
* `SandboxHandle` — the reaping ledger only ever stores names (it must be
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/core/backend.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/core/backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE5D;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,wCAAwC;IACxC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,sEAAsE;IACtE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;CAC9B;AAED,2FAA2F;AAC3F,MAAM,WAAW,YAAY;IAC3B,+HAA+H;IAC/H,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAiB;IAChC,0HAA0H;IAC1H,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACrC,oDAAoD;IACpD,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACvC,kJAAkJ;IAClJ,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAC/C;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B;;;;;;;;OAQG;IACH,QAAQ,CAAC,0BAA0B,EAAE,OAAO,CAAC;CAC9C;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0HAA0H;IAC1H,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAC;IACzC,wFAAwF;IACxF,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;IAC3C,8GAA8G;IAC9G,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACpD,iKAAiK;IACjK,KAAK,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,kEAAkE;IAClE,IAAI,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,oGAAoG;IACpG,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE;;;;;;OAMG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C;;;;;;;;;;;;;OAaG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C;;;;;;;;;OASG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D;;;;;;;;;;;;;;;;OAgBG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChE;;;;;;;OAOG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C;;;;;;;;;OASG;IACH,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;IACrE,gGAAgG;IAChG,iBAAiB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAChD,iFAAiF;IACjF,IAAI,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7E,0EAA0E;IAC1E,IAAI,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7C;;;;;OAKG;IACH,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC3F,yDAAyD;IACzD,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,mEAAmE;IACnE,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,+FAA+F;IAC/F,mBAAmB,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7F;;;;;;;;;;OAUG;IACH,eAAe,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/F,qJAAqJ;IACrJ,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjG,kFAAkF;IAClF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,2FAA2F;IAC3F,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,2HAA2H;IAC3H,WAAW,IAAI,OAAO,CAAC;IACvB,8GAA8G;IAC9G,iBAAiB,IAAI,MAAM,CAAC;IAC5B,8EAA8E;IAC9E,MAAM,IAAI,cAAc,CAAC;CAC1B"}
|
|
@@ -62,6 +62,51 @@ export declare function list(): Promise<Checkpoint[]>;
|
|
|
62
62
|
* throws `InvalidCheckpointNameError` and touches no file.
|
|
63
63
|
*/
|
|
64
64
|
export declare function remove(name: string): Promise<boolean>;
|
|
65
|
+
/**
|
|
66
|
+
* Bundles `cp` into a self-describing archive at `destPath`: `checkpoint.json`
|
|
67
|
+
* (the pinned metadata — format version, this checkpoint's name if it was
|
|
68
|
+
* ever registered under one, ref, backend, creation time, and spec) plus an
|
|
69
|
+
* `artifact` member holding the backend's own payload, byte-for-byte what
|
|
70
|
+
* `SandboxBackend.exportCheckpoint` produces. See the
|
|
71
|
+
* [checkpoints guide](/guide/checkpoints#moving-checkpoints-between-machines)
|
|
72
|
+
* for the full CI-cache pattern this exists for.
|
|
73
|
+
*
|
|
74
|
+
* Requires the ACTIVE backend to equal `cp.backend` — the same
|
|
75
|
+
* `CheckpointBackendMismatchError` `fromCheckpoint(cp).start()` throws —
|
|
76
|
+
* before any backend or filesystem work. Then probes the artifact still
|
|
77
|
+
* exists via `hasCheckpoint`: exporting a stale checkpoint throws
|
|
78
|
+
* `CheckpointArtifactMissingError` rather than producing a broken archive.
|
|
79
|
+
* Only once both checks pass does this stage the export in a fresh unique
|
|
80
|
+
* temp directory (removed in a `finally` regardless of outcome) and tar it
|
|
81
|
+
* into `destPath` (parent directories created; a pre-existing file there is
|
|
82
|
+
* overwritten). Works on an ephemeral (unnamed) checkpoint too — the
|
|
83
|
+
* resulting archive just carries `name: null`.
|
|
84
|
+
*/
|
|
85
|
+
export declare function exportTo(cp: Checkpoint, destPath: string): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* The inverse of `exportTo`: extracts `srcPath`, validates its
|
|
88
|
+
* `checkpoint.json` (format version, `name` against
|
|
89
|
+
* `CHECKPOINT_NAME_PATTERN` when non-null, backend against the ACTIVE
|
|
90
|
+
* backend — a `MalformedCheckpointArchiveError` or `CheckpointBackendMismatchError`
|
|
91
|
+
* either way, before any backend call or registry write), then hands the
|
|
92
|
+
* extracted `artifact` to `SandboxBackend.importCheckpoint`, which
|
|
93
|
+
* materializes it and returns the EFFECTIVE ref (docker: the same `ref` the
|
|
94
|
+
* archive recorded; microsandbox: the digest `snapshot import` actually
|
|
95
|
+
* assigned it — never necessarily the archive's own `ref`).
|
|
96
|
+
*
|
|
97
|
+
* A NAMED archive (`name` non-null) gets replace semantics matching
|
|
98
|
+
* `checkpoint(name)`: if a registry entry already exists for that name under
|
|
99
|
+
* a DIFFERENT ref and its recorded backend matches the active one, its old
|
|
100
|
+
* artifact is best-effort removed first (never a foreign-backend
|
|
101
|
+
* `removeCheckpoint` call — the same gate `remove()` applies); the registry
|
|
102
|
+
* entry is then written (or overwritten) with the effective ref. A NAMELESS
|
|
103
|
+
* archive writes no registry entry at all — the returned `Checkpoint` is
|
|
104
|
+
* purely ephemeral, the same as an unnamed `checkpoint()` call's result.
|
|
105
|
+
* Either way, the returned `Checkpoint` restores via the existing
|
|
106
|
+
* `fromCheckpoint()` path with zero changes — refs are opaque throughout
|
|
107
|
+
* this library.
|
|
108
|
+
*/
|
|
109
|
+
export declare function importFrom(srcPath: string): Promise<Checkpoint>;
|
|
65
110
|
/**
|
|
66
111
|
* The library's entry point for rediscovering NAMED checkpoints across
|
|
67
112
|
* processes — see the [checkpoints guide](/guide/checkpoints#reusing-checkpoints-across-runs)
|
|
@@ -76,5 +121,9 @@ export declare const Checkpoints: {
|
|
|
76
121
|
list: typeof list;
|
|
77
122
|
/** Deletes a named checkpoint — see `remove` above. */
|
|
78
123
|
remove: typeof remove;
|
|
124
|
+
/** Bundles a checkpoint into a portable archive — see `exportTo` above. */
|
|
125
|
+
exportTo: typeof exportTo;
|
|
126
|
+
/** Materializes a portable archive on this machine — see `importFrom` above. */
|
|
127
|
+
importFrom: typeof importFrom;
|
|
79
128
|
};
|
|
80
129
|
//# sourceMappingURL=api.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/core/checkpoint/api.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/core/checkpoint/api.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAoB9C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAwBxE;AAED;;;;;;;GAOG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAWlD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAmB3D;AAqBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,QAAQ,CAAC,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsB9E;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAqCrE;AAED;;;;;;GAMG;AACH,eAAO,MAAM,WAAW;IACtB,yDAAyD;;IAEzD,2EAA2E;;IAE3E,uDAAuD;;IAEvD,2EAA2E;;IAE3E,gFAAgF;;CAEjF,CAAC"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { cacheDir } from "../cache-dir.js";
|
|
2
2
|
import { Backends } from "../backends.js";
|
|
3
|
+
import { CheckpointArtifactMissingError, CheckpointBackendMismatchError } from "../errors.js";
|
|
3
4
|
import { requireValidCheckpointName } from "./name.js";
|
|
4
|
-
import { readCheckpointRegistry, removeCheckpointRegistryFile, listCheckpointNames, fromCheckpointRegistryEntry, } from "./registry.js";
|
|
5
|
+
import { readCheckpointRegistry, removeCheckpointRegistryFile, writeCheckpointRegistryAtomic, listCheckpointNames, fromCheckpointRegistryEntry, toCheckpointRegistrySpec, } from "./registry.js";
|
|
6
|
+
import { writeCheckpointArchive, readCheckpointArchive, CHECKPOINT_ARCHIVE_VERSION } from "./archive.js";
|
|
5
7
|
/** Every field of a `Checkpoint` comes straight from the registry entry except `spec`, which is reconstructed via `fromCheckpointRegistryEntry` — see that function's own doc for what is and isn't meaningful in the result. */
|
|
6
8
|
function toCheckpoint(entry) {
|
|
7
9
|
return { ref: entry.ref, backend: entry.backend, spec: fromCheckpointRegistryEntry(entry) };
|
|
@@ -120,6 +122,123 @@ export async function remove(name) {
|
|
|
120
122
|
await removeCheckpointRegistryFile(dir, name);
|
|
121
123
|
return true;
|
|
122
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* Reverse lookup: the registry entry (if any) whose `ref`/`backend` match a
|
|
127
|
+
* `Checkpoint`'s own — `exportTo`'s only way to learn whether the checkpoint
|
|
128
|
+
* it's given was ever named, and under what name, since a `Checkpoint`
|
|
129
|
+
* object itself never carries one (see `toCheckpoint` above). Scans every
|
|
130
|
+
* registered name the same way `list()` does; a corrupt entry is silently
|
|
131
|
+
* skipped, matching `list()`'s own tolerance.
|
|
132
|
+
*/
|
|
133
|
+
async function findRegistryEntryByRef(dir, ref, backend) {
|
|
134
|
+
const names = await listCheckpointNames(dir);
|
|
135
|
+
for (const name of names) {
|
|
136
|
+
const read = await readCheckpointRegistry(dir, name);
|
|
137
|
+
if (read.kind === "found" && read.entry.ref === ref && read.entry.backend === backend) {
|
|
138
|
+
return read.entry;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Bundles `cp` into a self-describing archive at `destPath`: `checkpoint.json`
|
|
145
|
+
* (the pinned metadata — format version, this checkpoint's name if it was
|
|
146
|
+
* ever registered under one, ref, backend, creation time, and spec) plus an
|
|
147
|
+
* `artifact` member holding the backend's own payload, byte-for-byte what
|
|
148
|
+
* `SandboxBackend.exportCheckpoint` produces. See the
|
|
149
|
+
* [checkpoints guide](/guide/checkpoints#moving-checkpoints-between-machines)
|
|
150
|
+
* for the full CI-cache pattern this exists for.
|
|
151
|
+
*
|
|
152
|
+
* Requires the ACTIVE backend to equal `cp.backend` — the same
|
|
153
|
+
* `CheckpointBackendMismatchError` `fromCheckpoint(cp).start()` throws —
|
|
154
|
+
* before any backend or filesystem work. Then probes the artifact still
|
|
155
|
+
* exists via `hasCheckpoint`: exporting a stale checkpoint throws
|
|
156
|
+
* `CheckpointArtifactMissingError` rather than producing a broken archive.
|
|
157
|
+
* Only once both checks pass does this stage the export in a fresh unique
|
|
158
|
+
* temp directory (removed in a `finally` regardless of outcome) and tar it
|
|
159
|
+
* into `destPath` (parent directories created; a pre-existing file there is
|
|
160
|
+
* overwritten). Works on an ephemeral (unnamed) checkpoint too — the
|
|
161
|
+
* resulting archive just carries `name: null`.
|
|
162
|
+
*/
|
|
163
|
+
export async function exportTo(cp, destPath) {
|
|
164
|
+
const active = Backends.active();
|
|
165
|
+
if (cp.backend !== active.name) {
|
|
166
|
+
throw new CheckpointBackendMismatchError(cp.backend, active.name);
|
|
167
|
+
}
|
|
168
|
+
const exists = await active.hasCheckpoint(cp.ref);
|
|
169
|
+
if (!exists) {
|
|
170
|
+
throw new CheckpointArtifactMissingError(cp.ref, cp.backend);
|
|
171
|
+
}
|
|
172
|
+
const dir = cacheDir();
|
|
173
|
+
const registryEntry = await findRegistryEntryByRef(dir, cp.ref, cp.backend);
|
|
174
|
+
const metadata = {
|
|
175
|
+
rightsizeArchive: CHECKPOINT_ARCHIVE_VERSION,
|
|
176
|
+
name: registryEntry?.name ?? null,
|
|
177
|
+
ref: cp.ref,
|
|
178
|
+
backend: cp.backend,
|
|
179
|
+
createdIso: registryEntry?.createdIso ?? new Date().toISOString(),
|
|
180
|
+
spec: toCheckpointRegistrySpec(cp.spec),
|
|
181
|
+
};
|
|
182
|
+
await writeCheckpointArchive(destPath, metadata, (artifactPath) => active.exportCheckpoint(cp.ref, artifactPath));
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* The inverse of `exportTo`: extracts `srcPath`, validates its
|
|
186
|
+
* `checkpoint.json` (format version, `name` against
|
|
187
|
+
* `CHECKPOINT_NAME_PATTERN` when non-null, backend against the ACTIVE
|
|
188
|
+
* backend — a `MalformedCheckpointArchiveError` or `CheckpointBackendMismatchError`
|
|
189
|
+
* either way, before any backend call or registry write), then hands the
|
|
190
|
+
* extracted `artifact` to `SandboxBackend.importCheckpoint`, which
|
|
191
|
+
* materializes it and returns the EFFECTIVE ref (docker: the same `ref` the
|
|
192
|
+
* archive recorded; microsandbox: the digest `snapshot import` actually
|
|
193
|
+
* assigned it — never necessarily the archive's own `ref`).
|
|
194
|
+
*
|
|
195
|
+
* A NAMED archive (`name` non-null) gets replace semantics matching
|
|
196
|
+
* `checkpoint(name)`: if a registry entry already exists for that name under
|
|
197
|
+
* a DIFFERENT ref and its recorded backend matches the active one, its old
|
|
198
|
+
* artifact is best-effort removed first (never a foreign-backend
|
|
199
|
+
* `removeCheckpoint` call — the same gate `remove()` applies); the registry
|
|
200
|
+
* entry is then written (or overwritten) with the effective ref. A NAMELESS
|
|
201
|
+
* archive writes no registry entry at all — the returned `Checkpoint` is
|
|
202
|
+
* purely ephemeral, the same as an unnamed `checkpoint()` call's result.
|
|
203
|
+
* Either way, the returned `Checkpoint` restores via the existing
|
|
204
|
+
* `fromCheckpoint()` path with zero changes — refs are opaque throughout
|
|
205
|
+
* this library.
|
|
206
|
+
*/
|
|
207
|
+
export async function importFrom(srcPath) {
|
|
208
|
+
const active = Backends.active();
|
|
209
|
+
return readCheckpointArchive(srcPath, async (metadata, artifactPath) => {
|
|
210
|
+
if (metadata.name !== null) {
|
|
211
|
+
requireValidCheckpointName(metadata.name);
|
|
212
|
+
}
|
|
213
|
+
if (metadata.backend !== active.name) {
|
|
214
|
+
throw new CheckpointBackendMismatchError(metadata.backend, active.name);
|
|
215
|
+
}
|
|
216
|
+
const effectiveRef = await active.importCheckpoint(artifactPath, metadata.ref);
|
|
217
|
+
const spec = fromCheckpointRegistryEntry({
|
|
218
|
+
name: metadata.name ?? "",
|
|
219
|
+
ref: effectiveRef,
|
|
220
|
+
backend: active.name,
|
|
221
|
+
createdIso: metadata.createdIso,
|
|
222
|
+
spec: metadata.spec,
|
|
223
|
+
});
|
|
224
|
+
if (metadata.name !== null) {
|
|
225
|
+
const dir = cacheDir();
|
|
226
|
+
const existing = await readCheckpointRegistry(dir, metadata.name);
|
|
227
|
+
if (existing.kind === "found" && existing.entry.ref !== effectiveRef && existing.entry.backend === active.name) {
|
|
228
|
+
await active.removeCheckpoint(existing.entry.ref).catch(() => { });
|
|
229
|
+
}
|
|
230
|
+
const entry = {
|
|
231
|
+
name: metadata.name,
|
|
232
|
+
ref: effectiveRef,
|
|
233
|
+
backend: active.name,
|
|
234
|
+
createdIso: metadata.createdIso,
|
|
235
|
+
spec: metadata.spec,
|
|
236
|
+
};
|
|
237
|
+
await writeCheckpointRegistryAtomic(dir, metadata.name, entry);
|
|
238
|
+
}
|
|
239
|
+
return { ref: effectiveRef, backend: active.name, spec };
|
|
240
|
+
});
|
|
241
|
+
}
|
|
123
242
|
/**
|
|
124
243
|
* The library's entry point for rediscovering NAMED checkpoints across
|
|
125
244
|
* processes — see the [checkpoints guide](/guide/checkpoints#reusing-checkpoints-across-runs)
|
|
@@ -134,5 +253,9 @@ export const Checkpoints = {
|
|
|
134
253
|
list,
|
|
135
254
|
/** Deletes a named checkpoint — see `remove` above. */
|
|
136
255
|
remove,
|
|
256
|
+
/** Bundles a checkpoint into a portable archive — see `exportTo` above. */
|
|
257
|
+
exportTo,
|
|
258
|
+
/** Materializes a portable archive on this machine — see `importFrom` above. */
|
|
259
|
+
importFrom,
|
|
137
260
|
};
|
|
138
261
|
//# sourceMappingURL=api.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/core/checkpoint/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EACL,sBAAsB,EACtB,4BAA4B,EAC5B,mBAAmB,EACnB,2BAA2B,
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/core/checkpoint/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { CheckpointRegistrySpec } from "./registry.js";
|
|
2
|
+
/** The one archive format version this library understands — pinned identically across every rightsize language implementation. */
|
|
3
|
+
export declare const CHECKPOINT_ARCHIVE_VERSION = 1;
|
|
4
|
+
/**
|
|
5
|
+
* `checkpoint.json`'s exact shape — pinned identically in every rightsize
|
|
6
|
+
* language implementation. `name` is `null` for an archive built from an
|
|
7
|
+
* unnamed (ephemeral) checkpoint; every other field mirrors
|
|
8
|
+
* `CheckpointRegistryEntry` plus the format version.
|
|
9
|
+
*/
|
|
10
|
+
export interface CheckpointArchiveMetadata {
|
|
11
|
+
readonly rightsizeArchive: 1;
|
|
12
|
+
readonly name: string | null;
|
|
13
|
+
readonly ref: string;
|
|
14
|
+
readonly backend: string;
|
|
15
|
+
readonly createdIso: string;
|
|
16
|
+
readonly spec: CheckpointRegistrySpec;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parses and validates `text` (the extracted archive's `checkpoint.json`
|
|
20
|
+
* content) into a `CheckpointArchiveMetadata`. Every failure — invalid JSON,
|
|
21
|
+
* a `rightsizeArchive` value other than `CHECKPOINT_ARCHIVE_VERSION` (named
|
|
22
|
+
* in the thrown error, per the pinned format's own contract), a malformed
|
|
23
|
+
* `name`/`ref`/`backend`/`createdIso`/`spec` — throws
|
|
24
|
+
* `MalformedCheckpointArchiveError` naming `archivePath` (the ORIGINAL
|
|
25
|
+
* archive the caller passed to `importFrom`, not the temp-extracted json
|
|
26
|
+
* path, so the error is actionable). Never touches a backend or the
|
|
27
|
+
* registry — pure parsing.
|
|
28
|
+
*/
|
|
29
|
+
export declare function parseCheckpointArchiveMetadata(text: string, archivePath: string): CheckpointArchiveMetadata;
|
|
30
|
+
/**
|
|
31
|
+
* Builds a checkpoint archive at `destPath`: stages `checkpoint.json` and an
|
|
32
|
+
* `artifact` file (written by `exportArtifact`, the backend's own
|
|
33
|
+
* `exportCheckpoint` call) in a fresh temp directory, then tars exactly
|
|
34
|
+
* those two members at the archive's root — never nested under the temp
|
|
35
|
+
* dir's own path. `destPath`'s parent directories are created first; a
|
|
36
|
+
* pre-existing file at `destPath` is overwritten (tar's own default
|
|
37
|
+
* behavior). The temp directory is removed in a `finally`, on success and on
|
|
38
|
+
* failure alike.
|
|
39
|
+
*/
|
|
40
|
+
export declare function writeCheckpointArchive(destPath: string, metadata: CheckpointArchiveMetadata, exportArtifact: (artifactPath: string) => Promise<void>): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Extracts `srcPath` into a fresh temp directory, parses and validates
|
|
43
|
+
* `checkpoint.json` (see `parseCheckpointArchiveMetadata`), confirms the
|
|
44
|
+
* `artifact` member is present, then hands both to `importArtifact` — the
|
|
45
|
+
* caller's own backend/registry validation and `importCheckpoint` call —
|
|
46
|
+
* before the temp directory is removed in a `finally`. `srcPath` not
|
|
47
|
+
* existing, or not being a valid tar, or missing its `checkpoint.json`
|
|
48
|
+
* member each throw `MalformedCheckpointArchiveError` naming `srcPath`
|
|
49
|
+
* itself, before any backend call.
|
|
50
|
+
*/
|
|
51
|
+
export declare function readCheckpointArchive<T>(srcPath: string, importArtifact: (metadata: CheckpointArchiveMetadata, artifactPath: string) => Promise<T>): Promise<T>;
|
|
52
|
+
//# sourceMappingURL=archive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../../src/core/checkpoint/archive.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAG5D,mIAAmI;AACnI,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAU5C;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAC;CACvC;AAWD;;;;;;;;;;GAUG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,yBAAyB,CAwC3G;AAED;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,yBAAyB,EACnC,cAAc,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GACtD,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,EAC3C,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,CAAC,QAAQ,EAAE,yBAAyB,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GACxF,OAAO,CAAC,CAAC,CAAC,CAsCZ"}
|