rightsize 0.1.2 → 0.3.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.
Files changed (131) hide show
  1. package/README.md +36 -4
  2. package/dist/backend-docker/backend.d.ts +76 -1
  3. package/dist/backend-docker/backend.d.ts.map +1 -1
  4. package/dist/backend-docker/backend.js +156 -13
  5. package/dist/backend-docker/backend.js.map +1 -1
  6. package/dist/backend-docker/cli.d.ts +25 -0
  7. package/dist/backend-docker/cli.d.ts.map +1 -0
  8. package/dist/backend-docker/cli.js +64 -0
  9. package/dist/backend-docker/cli.js.map +1 -0
  10. package/dist/backend-docker/labels.d.ts +27 -5
  11. package/dist/backend-docker/labels.d.ts.map +1 -1
  12. package/dist/backend-docker/labels.js +33 -5
  13. package/dist/backend-docker/labels.js.map +1 -1
  14. package/dist/backend-msb/backend.d.ts +89 -6
  15. package/dist/backend-msb/backend.d.ts.map +1 -1
  16. package/dist/backend-msb/backend.js +179 -14
  17. package/dist/backend-msb/backend.js.map +1 -1
  18. package/dist/backend-msb/commands.d.ts +10 -0
  19. package/dist/backend-msb/commands.d.ts.map +1 -1
  20. package/dist/backend-msb/commands.js +29 -1
  21. package/dist/backend-msb/commands.js.map +1 -1
  22. package/dist/backend-msb/provider.d.ts.map +1 -1
  23. package/dist/backend-msb/provider.js +7 -11
  24. package/dist/backend-msb/provider.js.map +1 -1
  25. package/dist/backend-msb/provisioner.d.ts.map +1 -1
  26. package/dist/backend-msb/provisioner.js +1 -20
  27. package/dist/backend-msb/provisioner.js.map +1 -1
  28. package/dist/backend-msb/snapshot-not-found.d.ts +25 -0
  29. package/dist/backend-msb/snapshot-not-found.d.ts.map +1 -0
  30. package/dist/backend-msb/snapshot-not-found.js +27 -0
  31. package/dist/backend-msb/snapshot-not-found.js.map +1 -0
  32. package/dist/core/backend.d.ts +124 -0
  33. package/dist/core/backend.d.ts.map +1 -1
  34. package/dist/core/backends.d.ts +16 -2
  35. package/dist/core/backends.d.ts.map +1 -1
  36. package/dist/core/backends.js +39 -5
  37. package/dist/core/backends.js.map +1 -1
  38. package/dist/core/cache-dir.d.ts +17 -0
  39. package/dist/core/cache-dir.d.ts.map +1 -0
  40. package/dist/core/cache-dir.js +29 -0
  41. package/dist/core/cache-dir.js.map +1 -0
  42. package/dist/core/checkpoint/api.d.ts +80 -0
  43. package/dist/core/checkpoint/api.d.ts.map +1 -0
  44. package/dist/core/checkpoint/api.js +138 -0
  45. package/dist/core/checkpoint/api.js.map +1 -0
  46. package/dist/core/checkpoint/name.d.ts +12 -0
  47. package/dist/core/checkpoint/name.d.ts.map +1 -0
  48. package/dist/core/checkpoint/name.js +17 -0
  49. package/dist/core/checkpoint/name.js.map +1 -0
  50. package/dist/core/checkpoint/ref.d.ts +12 -0
  51. package/dist/core/checkpoint/ref.d.ts.map +1 -0
  52. package/dist/core/checkpoint/ref.js +16 -0
  53. package/dist/core/checkpoint/ref.js.map +1 -0
  54. package/dist/core/checkpoint/registry.d.ts +107 -0
  55. package/dist/core/checkpoint/registry.d.ts.map +1 -0
  56. package/dist/core/checkpoint/registry.js +180 -0
  57. package/dist/core/checkpoint/registry.js.map +1 -0
  58. package/dist/core/cleanup.d.ts +19 -4
  59. package/dist/core/cleanup.d.ts.map +1 -1
  60. package/dist/core/cleanup.js +14 -27
  61. package/dist/core/cleanup.js.map +1 -1
  62. package/dist/core/diagnostics.d.ts +33 -0
  63. package/dist/core/diagnostics.d.ts.map +1 -0
  64. package/dist/core/diagnostics.js +76 -0
  65. package/dist/core/diagnostics.js.map +1 -0
  66. package/dist/core/errors.d.ts +97 -0
  67. package/dist/core/errors.d.ts.map +1 -1
  68. package/dist/core/errors.js +129 -0
  69. package/dist/core/errors.js.map +1 -1
  70. package/dist/core/generic-container.d.ts +176 -1
  71. package/dist/core/generic-container.d.ts.map +1 -1
  72. package/dist/core/generic-container.js +566 -3
  73. package/dist/core/generic-container.js.map +1 -1
  74. package/dist/core/model.d.ts +39 -0
  75. package/dist/core/model.d.ts.map +1 -1
  76. package/dist/core/network.d.ts.map +1 -1
  77. package/dist/core/network.js +2 -0
  78. package/dist/core/network.js.map +1 -1
  79. package/dist/core/reaper/env.d.ts +14 -0
  80. package/dist/core/reaper/env.d.ts.map +1 -0
  81. package/dist/core/reaper/env.js +22 -0
  82. package/dist/core/reaper/env.js.map +1 -0
  83. package/dist/core/reaper/init.d.ts +39 -0
  84. package/dist/core/reaper/init.d.ts.map +1 -0
  85. package/dist/core/reaper/init.js +140 -0
  86. package/dist/core/reaper/init.js.map +1 -0
  87. package/dist/core/reaper/ledger.d.ts +32 -0
  88. package/dist/core/reaper/ledger.d.ts.map +1 -0
  89. package/dist/core/reaper/ledger.js +160 -0
  90. package/dist/core/reaper/ledger.js.map +1 -0
  91. package/dist/core/reaper/process-liveness.d.ts +39 -0
  92. package/dist/core/reaper/process-liveness.d.ts.map +1 -0
  93. package/dist/core/reaper/process-liveness.js +117 -0
  94. package/dist/core/reaper/process-liveness.js.map +1 -0
  95. package/dist/core/reaper/run-record.d.ts +48 -0
  96. package/dist/core/reaper/run-record.d.ts.map +1 -0
  97. package/dist/core/reaper/run-record.js +58 -0
  98. package/dist/core/reaper/run-record.js.map +1 -0
  99. package/dist/core/reaper/sweep.d.ts +23 -0
  100. package/dist/core/reaper/sweep.d.ts.map +1 -0
  101. package/dist/core/reaper/sweep.js +76 -0
  102. package/dist/core/reaper/sweep.js.map +1 -0
  103. package/dist/core/reaper/watchdog.d.ts +100 -0
  104. package/dist/core/reaper/watchdog.d.ts.map +1 -0
  105. package/dist/core/reaper/watchdog.js +412 -0
  106. package/dist/core/reaper/watchdog.js.map +1 -0
  107. package/dist/core/reuse/env.d.ts +12 -0
  108. package/dist/core/reuse/env.d.ts.map +1 -0
  109. package/dist/core/reuse/env.js +15 -0
  110. package/dist/core/reuse/env.js.map +1 -0
  111. package/dist/core/reuse/hash.d.ts +34 -0
  112. package/dist/core/reuse/hash.d.ts.map +1 -0
  113. package/dist/core/reuse/hash.js +52 -0
  114. package/dist/core/reuse/hash.js.map +1 -0
  115. package/dist/core/reuse/registry.d.ts +50 -0
  116. package/dist/core/reuse/registry.d.ts.map +1 -0
  117. package/dist/core/reuse/registry.js +75 -0
  118. package/dist/core/reuse/registry.js.map +1 -0
  119. package/dist/index.d.ts +8 -4
  120. package/dist/index.d.ts.map +1 -1
  121. package/dist/index.js +5 -2
  122. package/dist/index.js.map +1 -1
  123. package/dist/modules/keycloak.js +1 -1
  124. package/dist/modules/mysql.d.ts.map +1 -1
  125. package/dist/modules/mysql.js +4 -3
  126. package/dist/modules/mysql.js.map +1 -1
  127. package/package.json +1 -1
  128. package/dist/backend-msb/reaper.d.ts +0 -10
  129. package/dist/backend-msb/reaper.d.ts.map +0 -1
  130. package/dist/backend-msb/reaper.js +0 -73
  131. package/dist/backend-msb/reaper.js.map +0 -1
@@ -0,0 +1,75 @@
1
+ import * as fsp from "node:fs/promises";
2
+ import * as path from "node:path";
3
+ /** `<cacheDir>/reuse` — the directory every reuse registry file lives under. */
4
+ export function reuseDir(cacheDir) {
5
+ return path.join(cacheDir, "reuse");
6
+ }
7
+ /** `reuse/<hash>.json`. */
8
+ export function reusePath(cacheDir, hash) {
9
+ return path.join(reuseDir(cacheDir), `${hash}.json`);
10
+ }
11
+ function isRegistryEntry(value) {
12
+ if (typeof value !== "object" || value === null) {
13
+ return false;
14
+ }
15
+ const rec = value;
16
+ if (typeof rec["name"] !== "string" ||
17
+ typeof rec["image"] !== "string" ||
18
+ typeof rec["createdIso"] !== "string" ||
19
+ typeof rec["backend"] !== "string") {
20
+ return false;
21
+ }
22
+ const ports = rec["ports"];
23
+ if (typeof ports !== "object" || ports === null || Array.isArray(ports)) {
24
+ return false;
25
+ }
26
+ return Object.values(ports).every((v) => typeof v === "number");
27
+ }
28
+ /**
29
+ * Reads and parses `reuse/<hash>.json`. `"missing"` means the file does not
30
+ * exist at all (the common "never created yet" case); `"corrupt"` means it
31
+ * exists but isn't a well-shaped `ReuseRegistryEntry` — malformed JSON or a
32
+ * missing/mistyped required field — distinct from `"missing"` because the
33
+ * adopt path's fallback behavior differs (see `hash.ts`'s sibling module doc
34
+ * and the reuse spec).
35
+ */
36
+ export async function readRegistry(cacheDir, hash) {
37
+ let text;
38
+ try {
39
+ text = await fsp.readFile(reusePath(cacheDir, hash), "utf8");
40
+ }
41
+ catch {
42
+ return { kind: "missing" };
43
+ }
44
+ let parsed;
45
+ try {
46
+ parsed = JSON.parse(text);
47
+ }
48
+ catch {
49
+ return { kind: "corrupt" };
50
+ }
51
+ if (!isRegistryEntry(parsed)) {
52
+ return { kind: "corrupt" };
53
+ }
54
+ return { kind: "found", entry: parsed };
55
+ }
56
+ /**
57
+ * Atomically writes `reuse/<hash>.json` (tmp file + rename, same protocol as
58
+ * the reaping ledger's `writeRunRecord`) — called once, after a fresh reuse
59
+ * container's wait strategy has confirmed readiness. A concurrent reader
60
+ * only ever observes either the previous complete file or this one, never a
61
+ * partial write.
62
+ */
63
+ export async function writeRegistryAtomic(cacheDir, hash, entry) {
64
+ const dir = reuseDir(cacheDir);
65
+ await fsp.mkdir(dir, { recursive: true });
66
+ const target = reusePath(cacheDir, hash);
67
+ const tmp = path.join(dir, `.${hash}.json.tmp-${process.pid}-${Date.now()}`);
68
+ await fsp.writeFile(tmp, JSON.stringify(entry));
69
+ await fsp.rename(tmp, target);
70
+ }
71
+ /** Best-effort delete of `reuse/<hash>.json`. A file already gone is not an error. */
72
+ export async function removeRegistry(cacheDir, hash) {
73
+ await fsp.unlink(reusePath(cacheDir, hash)).catch(() => { });
74
+ }
75
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/core/reuse/registry.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * Owns the public API surface every consumer builds on: `GenericContainer`
5
5
  * (the builder + async-dispose lifecycle guard), `Network`, the `Wait`
6
- * strategies, `FreePorts`, `RunId`, the `SandboxBackend`/`BackendProvider`
6
+ * strategies, `FreePorts`, `RunId`, `Checkpoints` (rediscovering named
7
+ * checkpoints across processes), the `SandboxBackend`/`BackendProvider`
7
8
  * contracts plus the `registerBackend` registry, and the typed error
8
9
  * classes. This module depends on no backend — import `rightsize/backend-msb`
9
10
  * and/or `rightsize/backend-docker` to register one, or `rightsize/modules`
@@ -11,9 +12,9 @@
11
12
  *
12
13
  * @packageDocumentation
13
14
  */
14
- export { UnsupportedByBackendError, PortBindConflictError, ContainerLaunchError, BackendError, ProvisionError, } from "./core/errors.js";
15
- export type { PortBinding, FileMount, ExecResult, ContainerSpec } from "./core/model.js";
16
- export type { NetworkLink, SandboxHandle, FollowHandle, SandboxBackend, BackendProvider } from "./core/backend.js";
15
+ export { UnsupportedByBackendError, PortBindConflictError, ContainerLaunchError, BackendError, ProvisionError, ReuseWithNetworkError, IsolationRequiredError, CheckpointUnsupportedError, CheckpointBackendMismatchError, ReuseFromCheckpointError, RelativeContainerPathError, InvalidCheckpointNameError, } from "./core/errors.js";
16
+ export type { PortBinding, FileMount, ExecResult, ContainerSpec, Checkpoint } from "./core/model.js";
17
+ export type { NetworkLink, SandboxHandle, FollowHandle, SandboxBackend, BackendProvider, ReaperKillCommand, BackendCapabilities, } from "./core/backend.js";
17
18
  export { registerBackend, Backends } from "./core/backends.js";
18
19
  export { FreePorts } from "./core/free-ports.js";
19
20
  export { Wait, HttpWaitStrategy } from "./core/wait.js";
@@ -23,4 +24,7 @@ export { Network } from "./core/network.js";
23
24
  export type { NetworkMember } from "./core/network.js";
24
25
  export { MountableFile } from "./core/mountable-file.js";
25
26
  export { GenericContainer } from "./core/generic-container.js";
27
+ export { diagnostics, registerDiagnostics } from "./core/diagnostics.js";
28
+ export type { FailureHook } from "./core/diagnostics.js";
29
+ export { Checkpoints } from "./core/checkpoint/api.js";
26
30
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EACrB,oBAAoB,EACpB,YAAY,EACZ,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACzF,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACnH,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACxD,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EACrB,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,8BAA8B,EAC9B,wBAAwB,EACxB,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACrG,YAAY,EACV,WAAW,EACX,aAAa,EACb,YAAY,EACZ,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACxD,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACzE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC"}
package/dist/index.js CHANGED
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * Owns the public API surface every consumer builds on: `GenericContainer`
5
5
  * (the builder + async-dispose lifecycle guard), `Network`, the `Wait`
6
- * strategies, `FreePorts`, `RunId`, the `SandboxBackend`/`BackendProvider`
6
+ * strategies, `FreePorts`, `RunId`, `Checkpoints` (rediscovering named
7
+ * checkpoints across processes), the `SandboxBackend`/`BackendProvider`
7
8
  * contracts plus the `registerBackend` registry, and the typed error
8
9
  * classes. This module depends on no backend — import `rightsize/backend-msb`
9
10
  * and/or `rightsize/backend-docker` to register one, or `rightsize/modules`
@@ -11,7 +12,7 @@
11
12
  *
12
13
  * @packageDocumentation
13
14
  */
14
- export { UnsupportedByBackendError, PortBindConflictError, ContainerLaunchError, BackendError, ProvisionError, } from "./core/errors.js";
15
+ export { UnsupportedByBackendError, PortBindConflictError, ContainerLaunchError, BackendError, ProvisionError, ReuseWithNetworkError, IsolationRequiredError, CheckpointUnsupportedError, CheckpointBackendMismatchError, ReuseFromCheckpointError, RelativeContainerPathError, InvalidCheckpointNameError, } from "./core/errors.js";
15
16
  export { registerBackend, Backends } from "./core/backends.js";
16
17
  export { FreePorts } from "./core/free-ports.js";
17
18
  export { Wait, HttpWaitStrategy } from "./core/wait.js";
@@ -19,4 +20,6 @@ export { RunId } from "./core/run-id.js";
19
20
  export { Network } from "./core/network.js";
20
21
  export { MountableFile } from "./core/mountable-file.js";
21
22
  export { GenericContainer } from "./core/generic-container.js";
23
+ export { diagnostics, registerDiagnostics } from "./core/diagnostics.js";
24
+ export { Checkpoints } from "./core/checkpoint/api.js";
22
25
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EACrB,oBAAoB,EACpB,YAAY,EACZ,cAAc,GACf,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAExD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EACrB,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,8BAA8B,EAC9B,wBAAwB,EACxB,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,kBAAkB,CAAC;AAW1B,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAExD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEzE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC"}
@@ -2,7 +2,7 @@ import { GenericContainer } from "../core/generic-container.js";
2
2
  import { Wait } from "../core/wait.js";
3
3
  const HTTP_PORT = 8080;
4
4
  const MANAGEMENT_PORT = 9000;
5
- const STARTUP_TIMEOUT_MS = 120_000;
5
+ const STARTUP_TIMEOUT_MS = 180_000;
6
6
  /**
7
7
  * A single-node Keycloak container started with `start-dev` (an
8
8
  * in-memory/dev-mode boot — no external database wiring needed for tests).
@@ -1 +1 @@
1
- {"version":3,"file":"mysql.d.ts","sourceRoot":"","sources":["../../src/modules/mysql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAKhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,qBAAa,cAAe,SAAQ,gBAAgB;IAClD,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,aAAa,CAAU;gBAEnB,KAAK,SAAc;WAuBT,KAAK,CAAC,KAAK,SAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAIzE,+CAA+C;IAC/C,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKpC,mDAAmD;IACnD,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKpC,mDAAmD;IACnD,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKpC,qDAAqD;IACrD,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,yDAAyD;IACzD,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,qDAAqD;IACrD,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,iFAAiF;IACjF,IAAI,gBAAgB,IAAI,MAAM,CAE7B;CACF"}
1
+ {"version":3,"file":"mysql.d.ts","sourceRoot":"","sources":["../../src/modules/mysql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAKhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,qBAAa,cAAe,SAAQ,gBAAgB;IAClD,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,aAAa,CAAU;gBAEnB,KAAK,SAAc;WAwBT,KAAK,CAAC,KAAK,SAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAIzE,+CAA+C;IAC/C,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKpC,mDAAmD;IACnD,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKpC,mDAAmD;IACnD,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKpC,qDAAqD;IACrD,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,yDAAyD;IACzD,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,qDAAqD;IACrD,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,iFAAiF;IACjF,IAAI,gBAAgB,IAAI,MAAM,CAE7B;CACF"}
@@ -56,9 +56,10 @@ export class MySQLContainer extends GenericContainer {
56
56
  // First boot initializes the datafiles and boots mysqld twice (the
57
57
  // temp server for init scripts, then the real one). On a fast host
58
58
  // that finishes well under 60s, but a loaded Windows CI runner's
59
- // first boot overruns the 60s default120s absorbs the slow case
60
- // without masking a real hang.
61
- .waitingFor(Wait.forLogMessage(".*mysqld: ready for connections.*port: 3306($|[^0-9]).*", 1).withStartupTimeout(120_000));
59
+ // first boot overran even the 120s budget once (123s) 180s, the
60
+ // same budget ClickHouse's own two-pass startup carries, absorbs the
61
+ // slow case without masking a real hang.
62
+ .waitingFor(Wait.forLogMessage(".*mysqld: ready for connections.*port: 3306($|[^0-9]).*", 1).withStartupTimeout(180_000));
62
63
  // No withMemoryLimit override: unlike SpringCloudConfig's Paketo JVM
63
64
  // image, MySQL 8.4's InnoDB default footprint fits msb's default ~450M
64
65
  // microVM RAM, so no module-level memory floor is warranted here.
@@ -1 +1 @@
1
- {"version":3,"file":"mysql.js","sourceRoot":"","sources":["../../src/modules/mysql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEvC,MAAM,UAAU,GAAG,IAAI,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,OAAO,cAAe,SAAQ,gBAAgB;IAC1C,aAAa,GAAG,MAAM,CAAC;IACvB,aAAa,GAAG,MAAM,CAAC;IACvB,aAAa,GAAG,MAAM,CAAC;IAE/B,YAAY,KAAK,GAAG,WAAW;QAC7B,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC;aAC9B,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC;aACzC,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC,aAAa,CAAC;aAC7C,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC,aAAa,CAAC;aAC7C,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC;YACvC,gEAAgE;YAChE,qEAAqE;YACrE,iDAAiD;YACjD,mEAAmE;YACnE,mEAAmE;YACnE,iEAAiE;YACjE,mEAAmE;YACnE,+BAA+B;aAC9B,UAAU,CACT,IAAI,CAAC,aAAa,CAAC,yDAAyD,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAC7G,CAAC;QACJ,qEAAqE;QACrE,uEAAuE;QACvE,kEAAkE;IACpE,CAAC;IAED,MAAM,CAAU,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,WAAW;QAC7C,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAmB,CAAC;IACrE,CAAC;IAED,+CAA+C;IAC/C,YAAY,CAAC,QAAgB;QAC3B,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED,mDAAmD;IACnD,YAAY,CAAC,QAAgB;QAC3B,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;IAClD,CAAC;IAED,mDAAmD;IACnD,YAAY,CAAC,QAAgB;QAC3B,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;IAClD,CAAC;IAED,qDAAqD;IACrD,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,yDAAyD;IACzD,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,qDAAqD;IACrD,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,iFAAiF;IACjF,IAAI,gBAAgB;QAClB,OAAO,WAAW,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;IACpI,CAAC;CACF"}
1
+ {"version":3,"file":"mysql.js","sourceRoot":"","sources":["../../src/modules/mysql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEvC,MAAM,UAAU,GAAG,IAAI,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,OAAO,cAAe,SAAQ,gBAAgB;IAC1C,aAAa,GAAG,MAAM,CAAC;IACvB,aAAa,GAAG,MAAM,CAAC;IACvB,aAAa,GAAG,MAAM,CAAC;IAE/B,YAAY,KAAK,GAAG,WAAW;QAC7B,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC;aAC9B,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC;aACzC,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC,aAAa,CAAC;aAC7C,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC,aAAa,CAAC;aAC7C,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC;YACvC,gEAAgE;YAChE,qEAAqE;YACrE,iDAAiD;YACjD,mEAAmE;YACnE,mEAAmE;YACnE,iEAAiE;YACjE,kEAAkE;YAClE,qEAAqE;YACrE,yCAAyC;aACxC,UAAU,CACT,IAAI,CAAC,aAAa,CAAC,yDAAyD,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAC7G,CAAC;QACJ,qEAAqE;QACrE,uEAAuE;QACvE,kEAAkE;IACpE,CAAC;IAED,MAAM,CAAU,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,WAAW;QAC7C,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAmB,CAAC;IACrE,CAAC;IAED,+CAA+C;IAC/C,YAAY,CAAC,QAAgB;QAC3B,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED,mDAAmD;IACnD,YAAY,CAAC,QAAgB;QAC3B,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;IAClD,CAAC;IAED,mDAAmD;IACnD,YAAY,CAAC,QAAgB;QAC3B,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;IAClD,CAAC;IAED,qDAAqD;IACrD,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,yDAAyD;IACzD,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,qDAAqD;IACrD,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,iFAAiF;IACjF,IAAI,gBAAgB;QAClB,OAAO,WAAW,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;IACpI,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rightsize",
3
- "version": "0.1.2",
3
+ "version": "0.3.0",
4
4
  "description": "Testcontainers-style integration testing on microsandbox microVMs, with a Docker fallback and an await-using lifecycle. No Docker required.",
5
5
  "keywords": [
6
6
  "testcontainers",
@@ -1,10 +0,0 @@
1
- /**
2
- * Every `rz-<runid>-<seq>` name mentioned in `msb ls`'s output that does NOT
3
- * belong to `thisRunId` — leftovers from a run that crashed before its own
4
- * cleanup ran. Filtering happens against the SAME `RunId.value` core used to
5
- * name this run's own containers (imported from `rightsize`, never
6
- * recomputed here) — a backend-local run id would either reap this run's own
7
- * live sandboxes or fail to recognize a genuinely stale one.
8
- */
9
- export declare function orphanNames(lsOutput: string, thisRunId: string): string[];
10
- //# sourceMappingURL=reaper.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reaper.d.ts","sourceRoot":"","sources":["../../src/backend-msb/reaper.ts"],"names":[],"mappings":"AA0DA;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CASzE"}
@@ -1,73 +0,0 @@
1
- function isHexDigit(ch) {
2
- return ch !== undefined && /^[0-9a-f]$/i.test(ch);
3
- }
4
- function isDigit(ch) {
5
- return ch !== undefined && ch >= "0" && ch <= "9";
6
- }
7
- /** A character that continues an identifier token: alphanumeric, `-`, or `_`. */
8
- function isIdentContinue(ch) {
9
- return ch !== undefined && /^[A-Za-z0-9_-]$/.test(ch);
10
- }
11
- /**
12
- * Extracts every `rz-<8 hex>-<seq>`-shaped name appearing anywhere in `ls`
13
- * output — a manual character scan rather than
14
- * a `\b`-delimited regex. `\b` is a `\w` boundary and `\w` does not include
15
- * `-`, so a naive `/\brz-[0-9a-f]{8}-\d+\b/` would treat `rz-deadbeef-1` as a
16
- * complete match inside `rz-deadbeef-1-extra` (the `-` after the digits
17
- * counts as a boundary) even though that's a glued-on continuation of a
18
- * longer, different token — exactly the shape a second run's id could
19
- * produce as a prefix of a name it doesn't own. Requiring the character
20
- * immediately after the matched digits to NOT be an identifier-continue
21
- * character keeps this a whole-token match instead of a false-positive
22
- * prefix.
23
- */
24
- function orphanCandidateNames(lsOutput) {
25
- const names = [];
26
- let i = 0;
27
- const n = lsOutput.length;
28
- while (i < n) {
29
- if (lsOutput.startsWith("rz-", i)) {
30
- const start = i;
31
- let j = i + 3;
32
- let hexLen = 0;
33
- while (j < n && hexLen < 8 && isHexDigit(lsOutput[j])) {
34
- j++;
35
- hexLen++;
36
- }
37
- if (hexLen === 8 && lsOutput[j] === "-") {
38
- let k = j + 1;
39
- let digitLen = 0;
40
- while (k < n && isDigit(lsOutput[k])) {
41
- k++;
42
- digitLen++;
43
- }
44
- if (digitLen > 0 && (k >= n || !isIdentContinue(lsOutput[k]))) {
45
- names.push(lsOutput.slice(start, k));
46
- i = k;
47
- continue;
48
- }
49
- }
50
- }
51
- i++;
52
- }
53
- return names;
54
- }
55
- /**
56
- * Every `rz-<runid>-<seq>` name mentioned in `msb ls`'s output that does NOT
57
- * belong to `thisRunId` — leftovers from a run that crashed before its own
58
- * cleanup ran. Filtering happens against the SAME `RunId.value` core used to
59
- * name this run's own containers (imported from `rightsize`, never
60
- * recomputed here) — a backend-local run id would either reap this run's own
61
- * live sandboxes or fail to recognize a genuinely stale one.
62
- */
63
- export function orphanNames(lsOutput, thisRunId) {
64
- const mine = `rz-${thisRunId}-`;
65
- const seen = new Set();
66
- for (const name of orphanCandidateNames(lsOutput)) {
67
- if (!name.startsWith(mine)) {
68
- seen.add(name);
69
- }
70
- }
71
- return [...seen];
72
- }
73
- //# sourceMappingURL=reaper.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reaper.js","sourceRoot":"","sources":["../../src/backend-msb/reaper.ts"],"names":[],"mappings":"AAAA,SAAS,UAAU,CAAC,EAAsB;IACxC,OAAO,EAAE,KAAK,SAAS,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,OAAO,CAAC,EAAsB;IACrC,OAAO,EAAE,KAAK,SAAS,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,IAAI,GAAG,CAAC;AACpD,CAAC;AAED,iFAAiF;AACjF,SAAS,eAAe,CAAC,EAAsB;IAC7C,OAAO,EAAE,KAAK,SAAS,IAAI,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACxD,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAS,oBAAoB,CAAC,QAAgB;IAC5C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC1B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACb,IAAI,QAAQ,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,CAAC,CAAC;YAChB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,IAAI,MAAM,GAAG,CAAC,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACtD,CAAC,EAAE,CAAC;gBACJ,MAAM,EAAE,CAAC;YACX,CAAC;YACD,IAAI,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACxC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACd,IAAI,QAAQ,GAAG,CAAC,CAAC;gBACjB,OAAO,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBACrC,CAAC,EAAE,CAAC;oBACJ,QAAQ,EAAE,CAAC;gBACb,CAAC;gBACD,IAAI,QAAQ,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC9D,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;oBACrC,CAAC,GAAG,CAAC,CAAC;oBACN,SAAS;gBACX,CAAC;YACH,CAAC;QACH,CAAC;QACD,CAAC,EAAE,CAAC;IACN,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB,EAAE,SAAiB;IAC7D,MAAM,IAAI,GAAG,MAAM,SAAS,GAAG,CAAC;IAChC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,oBAAoB,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AACnB,CAAC"}