rightsize 0.1.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/LICENSE +202 -0
- package/NOTICE +4 -0
- package/README.md +255 -0
- package/dist/backend-docker/backend.d.ts +53 -0
- package/dist/backend-docker/backend.d.ts.map +1 -0
- package/dist/backend-docker/backend.js +336 -0
- package/dist/backend-docker/backend.js.map +1 -0
- package/dist/backend-docker/client.d.ts +82 -0
- package/dist/backend-docker/client.d.ts.map +1 -0
- package/dist/backend-docker/client.js +190 -0
- package/dist/backend-docker/client.js.map +1 -0
- package/dist/backend-docker/frames.d.ts +44 -0
- package/dist/backend-docker/frames.d.ts.map +1 -0
- package/dist/backend-docker/frames.js +105 -0
- package/dist/backend-docker/frames.js.map +1 -0
- package/dist/backend-docker/index.d.ts +5 -0
- package/dist/backend-docker/index.d.ts.map +1 -0
- package/dist/backend-docker/index.js +20 -0
- package/dist/backend-docker/index.js.map +1 -0
- package/dist/backend-docker/json.d.ts +13 -0
- package/dist/backend-docker/json.d.ts.map +1 -0
- package/dist/backend-docker/json.js +47 -0
- package/dist/backend-docker/json.js.map +1 -0
- package/dist/backend-docker/labels.d.ts +11 -0
- package/dist/backend-docker/labels.d.ts.map +1 -0
- package/dist/backend-docker/labels.js +13 -0
- package/dist/backend-docker/labels.js.map +1 -0
- package/dist/backend-docker/port-conflict.d.ts +9 -0
- package/dist/backend-docker/port-conflict.d.ts.map +1 -0
- package/dist/backend-docker/port-conflict.js +12 -0
- package/dist/backend-docker/port-conflict.js.map +1 -0
- package/dist/backend-docker/provider.d.ts +22 -0
- package/dist/backend-docker/provider.d.ts.map +1 -0
- package/dist/backend-docker/provider.js +36 -0
- package/dist/backend-docker/provider.js.map +1 -0
- package/dist/backend-msb/backend.d.ts +169 -0
- package/dist/backend-msb/backend.d.ts.map +1 -0
- package/dist/backend-msb/backend.js +664 -0
- package/dist/backend-msb/backend.js.map +1 -0
- package/dist/backend-msb/commands.d.ts +28 -0
- package/dist/backend-msb/commands.d.ts.map +1 -0
- package/dist/backend-msb/commands.js +67 -0
- package/dist/backend-msb/commands.js.map +1 -0
- package/dist/backend-msb/exec-tunnel.d.ts +33 -0
- package/dist/backend-msb/exec-tunnel.d.ts.map +1 -0
- package/dist/backend-msb/exec-tunnel.js +163 -0
- package/dist/backend-msb/exec-tunnel.js.map +1 -0
- package/dist/backend-msb/follow-replay.d.ts +14 -0
- package/dist/backend-msb/follow-replay.d.ts.map +1 -0
- package/dist/backend-msb/follow-replay.js +20 -0
- package/dist/backend-msb/follow-replay.js.map +1 -0
- package/dist/backend-msb/image-cache.d.ts +25 -0
- package/dist/backend-msb/image-cache.d.ts.map +1 -0
- package/dist/backend-msb/image-cache.js +27 -0
- package/dist/backend-msb/image-cache.js.map +1 -0
- package/dist/backend-msb/index.d.ts +6 -0
- package/dist/backend-msb/index.d.ts.map +1 -0
- package/dist/backend-msb/index.js +21 -0
- package/dist/backend-msb/index.js.map +1 -0
- package/dist/backend-msb/invoke.d.ts +24 -0
- package/dist/backend-msb/invoke.d.ts.map +1 -0
- package/dist/backend-msb/invoke.js +73 -0
- package/dist/backend-msb/invoke.js.map +1 -0
- package/dist/backend-msb/ls-json.d.ts +23 -0
- package/dist/backend-msb/ls-json.d.ts.map +1 -0
- package/dist/backend-msb/ls-json.js +113 -0
- package/dist/backend-msb/ls-json.js.map +1 -0
- package/dist/backend-msb/network-links.d.ts +7 -0
- package/dist/backend-msb/network-links.d.ts.map +1 -0
- package/dist/backend-msb/network-links.js +31 -0
- package/dist/backend-msb/network-links.js.map +1 -0
- package/dist/backend-msb/platform.d.ts +29 -0
- package/dist/backend-msb/platform.d.ts.map +1 -0
- package/dist/backend-msb/platform.js +128 -0
- package/dist/backend-msb/platform.js.map +1 -0
- package/dist/backend-msb/port-conflict.d.ts +10 -0
- package/dist/backend-msb/port-conflict.d.ts.map +1 -0
- package/dist/backend-msb/port-conflict.js +16 -0
- package/dist/backend-msb/port-conflict.js.map +1 -0
- package/dist/backend-msb/provider.d.ts +10 -0
- package/dist/backend-msb/provider.d.ts.map +1 -0
- package/dist/backend-msb/provider.js +40 -0
- package/dist/backend-msb/provider.js.map +1 -0
- package/dist/backend-msb/provisioner.d.ts +19 -0
- package/dist/backend-msb/provisioner.d.ts.map +1 -0
- package/dist/backend-msb/provisioner.js +332 -0
- package/dist/backend-msb/provisioner.js.map +1 -0
- package/dist/backend-msb/reaper.d.ts +10 -0
- package/dist/backend-msb/reaper.d.ts.map +1 -0
- package/dist/backend-msb/reaper.js +73 -0
- package/dist/backend-msb/reaper.js.map +1 -0
- package/dist/core/backend.d.ts +98 -0
- package/dist/core/backend.d.ts.map +1 -0
- package/dist/core/backend.js +2 -0
- package/dist/core/backend.js.map +1 -0
- package/dist/core/backends.d.ts +37 -0
- package/dist/core/backends.d.ts.map +1 -0
- package/dist/core/backends.js +127 -0
- package/dist/core/backends.js.map +1 -0
- package/dist/core/cleanup.d.ts +37 -0
- package/dist/core/cleanup.d.ts.map +1 -0
- package/dist/core/cleanup.js +86 -0
- package/dist/core/cleanup.js.map +1 -0
- package/dist/core/errors.d.ts +51 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +66 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/free-ports.d.ts +23 -0
- package/dist/core/free-ports.d.ts.map +1 -0
- package/dist/core/free-ports.js +63 -0
- package/dist/core/free-ports.js.map +1 -0
- package/dist/core/generic-container.d.ts +145 -0
- package/dist/core/generic-container.d.ts.map +1 -0
- package/dist/core/generic-container.js +385 -0
- package/dist/core/generic-container.js.map +1 -0
- package/dist/core/model.d.ts +60 -0
- package/dist/core/model.d.ts.map +1 -0
- package/dist/core/model.js +2 -0
- package/dist/core/model.js.map +1 -0
- package/dist/core/mountable-file.d.ts +25 -0
- package/dist/core/mountable-file.d.ts.map +1 -0
- package/dist/core/mountable-file.js +64 -0
- package/dist/core/mountable-file.js.map +1 -0
- package/dist/core/network.d.ts +58 -0
- package/dist/core/network.d.ts.map +1 -0
- package/dist/core/network.js +84 -0
- package/dist/core/network.js.map +1 -0
- package/dist/core/run-id.d.ts +18 -0
- package/dist/core/run-id.d.ts.map +1 -0
- package/dist/core/run-id.js +18 -0
- package/dist/core/run-id.js.map +1 -0
- package/dist/core/wait.d.ts +59 -0
- package/dist/core/wait.d.ts.map +1 -0
- package/dist/core/wait.js +239 -0
- package/dist/core/wait.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/arango.d.ts +14 -0
- package/dist/modules/arango.d.ts.map +1 -0
- package/dist/modules/arango.js +37 -0
- package/dist/modules/arango.js.map +1 -0
- package/dist/modules/clickhouse.d.ts +37 -0
- package/dist/modules/clickhouse.d.ts.map +1 -0
- package/dist/modules/clickhouse.js +69 -0
- package/dist/modules/clickhouse.js.map +1 -0
- package/dist/modules/flink.d.ts +65 -0
- package/dist/modules/flink.d.ts.map +1 -0
- package/dist/modules/flink.js +125 -0
- package/dist/modules/flink.js.map +1 -0
- package/dist/modules/floci.d.ts +46 -0
- package/dist/modules/floci.d.ts.map +1 -0
- package/dist/modules/floci.js +62 -0
- package/dist/modules/floci.js.map +1 -0
- package/dist/modules/index.d.ts +31 -0
- package/dist/modules/index.d.ts.map +1 -0
- package/dist/modules/index.js +31 -0
- package/dist/modules/index.js.map +1 -0
- package/dist/modules/kafka.d.ts +11 -0
- package/dist/modules/kafka.d.ts.map +1 -0
- package/dist/modules/kafka.js +41 -0
- package/dist/modules/kafka.js.map +1 -0
- package/dist/modules/keycloak.d.ts +40 -0
- package/dist/modules/keycloak.d.ts.map +1 -0
- package/dist/modules/keycloak.js +67 -0
- package/dist/modules/keycloak.js.map +1 -0
- package/dist/modules/mariadb.d.ts +56 -0
- package/dist/modules/mariadb.d.ts.map +1 -0
- package/dist/modules/mariadb.js +89 -0
- package/dist/modules/mariadb.js.map +1 -0
- package/dist/modules/memcached.d.ts +24 -0
- package/dist/modules/memcached.d.ts.map +1 -0
- package/dist/modules/memcached.js +105 -0
- package/dist/modules/memcached.js.map +1 -0
- package/dist/modules/mongodb.d.ts +19 -0
- package/dist/modules/mongodb.d.ts.map +1 -0
- package/dist/modules/mongodb.js +69 -0
- package/dist/modules/mongodb.js.map +1 -0
- package/dist/modules/mysql.d.ts +61 -0
- package/dist/modules/mysql.d.ts.map +1 -0
- package/dist/modules/mysql.js +101 -0
- package/dist/modules/mysql.js.map +1 -0
- package/dist/modules/neo4j.d.ts +60 -0
- package/dist/modules/neo4j.d.ts.map +1 -0
- package/dist/modules/neo4j.js +83 -0
- package/dist/modules/neo4j.js.map +1 -0
- package/dist/modules/pinot.d.ts +30 -0
- package/dist/modules/pinot.d.ts.map +1 -0
- package/dist/modules/pinot.js +49 -0
- package/dist/modules/pinot.js.map +1 -0
- package/dist/modules/postgres.d.ts +29 -0
- package/dist/modules/postgres.d.ts.map +1 -0
- package/dist/modules/postgres.js +73 -0
- package/dist/modules/postgres.js.map +1 -0
- package/dist/modules/rabbitmq.d.ts +46 -0
- package/dist/modules/rabbitmq.d.ts.map +1 -0
- package/dist/modules/rabbitmq.js +68 -0
- package/dist/modules/rabbitmq.js.map +1 -0
- package/dist/modules/redis.d.ts +15 -0
- package/dist/modules/redis.d.ts.map +1 -0
- package/dist/modules/redis.js +24 -0
- package/dist/modules/redis.js.map +1 -0
- package/dist/modules/redpanda.d.ts +27 -0
- package/dist/modules/redpanda.d.ts.map +1 -0
- package/dist/modules/redpanda.js +58 -0
- package/dist/modules/redpanda.js.map +1 -0
- package/dist/modules/spring-cloud-config.d.ts +18 -0
- package/dist/modules/spring-cloud-config.d.ts.map +1 -0
- package/dist/modules/spring-cloud-config.js +28 -0
- package/dist/modules/spring-cloud-config.js.map +1 -0
- package/dist/modules/wiremock.d.ts +21 -0
- package/dist/modules/wiremock.d.ts.map +1 -0
- package/dist/modules/wiremock.js +32 -0
- package/dist/modules/wiremock.js.map +1 -0
- package/package.json +104 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
/**
|
|
3
|
+
* Alias-based connectivity between containers, on both backends. Docker
|
|
4
|
+
* implements it with a native bridge network; msb — where each container is
|
|
5
|
+
* a fully isolated microVM — emulates it with an `/etc/hosts` alias plus a
|
|
6
|
+
* TCP relay over the sandbox's exec channel. `Network.resolve` returns the
|
|
7
|
+
* same `"alias:port"` string either way, so code written against it doesn't
|
|
8
|
+
* need to know which backend is active.
|
|
9
|
+
*
|
|
10
|
+
* Implements `Symbol.asyncDispose`, so `await using net = Network.newNetwork()`
|
|
11
|
+
* tears the network down at scope exit alongside its member containers.
|
|
12
|
+
*/
|
|
13
|
+
export class Network {
|
|
14
|
+
/** This network's process-unique id, `rz-net-<8hex>`. */
|
|
15
|
+
id;
|
|
16
|
+
aliasPorts = new Map();
|
|
17
|
+
members = [];
|
|
18
|
+
lastBackend;
|
|
19
|
+
constructor(id) {
|
|
20
|
+
this.id = id;
|
|
21
|
+
}
|
|
22
|
+
/** Creates a new network with a process-unique id (`rz-net-<8hex>`). Pass it to `withNetwork` on each member container. */
|
|
23
|
+
static newNetwork() {
|
|
24
|
+
return new Network(`rz-net-${randomBytes(4).toString("hex")}`);
|
|
25
|
+
}
|
|
26
|
+
/** "alias:guestPort" for a registered (alias, guestPort) pair; throws naming the alias otherwise. */
|
|
27
|
+
resolve(alias, guestPort) {
|
|
28
|
+
const ports = this.aliasPorts.get(alias);
|
|
29
|
+
if (ports === undefined || !ports.has(guestPort)) {
|
|
30
|
+
throw new Error(`no container registered on network '${this.id}' with alias '${alias}' exposing guest port ${guestPort}`);
|
|
31
|
+
}
|
|
32
|
+
return `${alias}:${guestPort}`;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Links a newly-starting container needs installed toward every ALREADY
|
|
36
|
+
* RUNNING sibling, computed before `register` runs — so a container can
|
|
37
|
+
* never end up linked to itself, and only genuinely-running siblings
|
|
38
|
+
* (never a half-started or already-stopped one) contribute links.
|
|
39
|
+
*/
|
|
40
|
+
linksForNewMember() {
|
|
41
|
+
const links = [];
|
|
42
|
+
for (const { member } of this.members) {
|
|
43
|
+
if (!member.isRunning) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
for (const alias of member.aliases) {
|
|
47
|
+
for (const guestPort of member.exposedGuestPorts) {
|
|
48
|
+
links.push({ alias, guestPort, targetHostPort: member.mappedPort(guestPort) });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return links;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Registers a container as a network member AFTER its links to existing
|
|
56
|
+
* siblings were computed and installed — never before, or the ordering
|
|
57
|
+
* that prevents self-links breaks.
|
|
58
|
+
*/
|
|
59
|
+
register(member, aliases, backend) {
|
|
60
|
+
this.lastBackend = backend;
|
|
61
|
+
this.members.push({ member });
|
|
62
|
+
for (const alias of aliases) {
|
|
63
|
+
let ports = this.aliasPorts.get(alias);
|
|
64
|
+
if (ports === undefined) {
|
|
65
|
+
ports = new Map();
|
|
66
|
+
this.aliasPorts.set(alias, ports);
|
|
67
|
+
}
|
|
68
|
+
for (const guestPort of member.exposedGuestPorts) {
|
|
69
|
+
ports.set(guestPort, member.mappedPort(guestPort));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** Removes the backend-native network. Best-effort: safe to call even if no member ever started. */
|
|
74
|
+
async close() {
|
|
75
|
+
if (this.lastBackend !== undefined) {
|
|
76
|
+
await this.lastBackend.removeNetwork(this.id);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/** `= close()`. What `await using net = Network.newNetwork()` calls at scope exit. */
|
|
80
|
+
async [Symbol.asyncDispose]() {
|
|
81
|
+
await this.close();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=network.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network.js","sourceRoot":"","sources":["../../src/core/network.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One value per process, computed once at module load and re-exported from
|
|
3
|
+
* `src/index.ts` so BOTH backend modules import the SAME value rather than
|
|
4
|
+
* each computing their own. This is a correctness requirement, not a style choice: the
|
|
5
|
+
* msb orphan reaper (`sweepOrphans`) and the docker label cleanup both
|
|
6
|
+
* filter container names/labels against `RunId.value` to distinguish "this
|
|
7
|
+
* run's own live containers" from "leftovers of a crashed prior run." If a
|
|
8
|
+
* backend computed its own run id instead of importing this one, the two
|
|
9
|
+
* values would differ and the reaper would either delete this run's own
|
|
10
|
+
* containers (treating them as someone else's orphan) or never clean up the
|
|
11
|
+
* other backend's leftovers at all — a silent correctness failure, not a
|
|
12
|
+
* compile error.
|
|
13
|
+
*/
|
|
14
|
+
export declare const RunId: {
|
|
15
|
+
/** 8 lowercase hex characters, stable for the lifetime of this process. */
|
|
16
|
+
readonly value: string;
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=run-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-id.d.ts","sourceRoot":"","sources":["../../src/core/run-id.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,KAAK,EAAE;IAClB,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CAGxB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
/**
|
|
3
|
+
* One value per process, computed once at module load and re-exported from
|
|
4
|
+
* `src/index.ts` so BOTH backend modules import the SAME value rather than
|
|
5
|
+
* each computing their own. This is a correctness requirement, not a style choice: the
|
|
6
|
+
* msb orphan reaper (`sweepOrphans`) and the docker label cleanup both
|
|
7
|
+
* filter container names/labels against `RunId.value` to distinguish "this
|
|
8
|
+
* run's own live containers" from "leftovers of a crashed prior run." If a
|
|
9
|
+
* backend computed its own run id instead of importing this one, the two
|
|
10
|
+
* values would differ and the reaper would either delete this run's own
|
|
11
|
+
* containers (treating them as someone else's orphan) or never clean up the
|
|
12
|
+
* other backend's leftovers at all — a silent correctness failure, not a
|
|
13
|
+
* compile error.
|
|
14
|
+
*/
|
|
15
|
+
export const RunId = {
|
|
16
|
+
value: randomBytes(4).toString("hex"),
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=run-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-id.js","sourceRoot":"","sources":["../../src/core/run-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,KAAK,GAGd;IACF,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;CACtC,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** The read-only view of a starting container a `WaitStrategy` probes against. `GenericContainer` implements this internally; modules never construct one. */
|
|
2
|
+
export interface WaitTarget {
|
|
3
|
+
/** The container's host, always `"127.0.0.1"`. */
|
|
4
|
+
readonly host: string;
|
|
5
|
+
/** The host port bound to `guestPort`. */
|
|
6
|
+
mappedPort(guestPort: number): number;
|
|
7
|
+
/** Every guest port this container published via `withExposedPorts`. */
|
|
8
|
+
readonly exposedGuestPorts: ReadonlyArray<number>;
|
|
9
|
+
/** The workload's logs so far. May throw or return an empty string before the workload has produced any output. */
|
|
10
|
+
currentLogs(): Promise<string>;
|
|
11
|
+
/** A short human-readable identifier for this container, used in timeout messages. */
|
|
12
|
+
describe(): string;
|
|
13
|
+
}
|
|
14
|
+
/** A pluggable readiness check passed to `GenericContainer.waitingFor`. Construct one via `Wait.*`, not directly. */
|
|
15
|
+
export interface WaitStrategy {
|
|
16
|
+
/** Poll until ready or throw `ContainerLaunchError` (with `describe()` and the last 50 log lines) at the deadline. */
|
|
17
|
+
waitUntilReady(target: WaitTarget): Promise<void>;
|
|
18
|
+
/** Override the default 60s deadline. Returns the same strategy for chaining. */
|
|
19
|
+
withStartupTimeout(ms: number): WaitStrategy;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Owns the deadline/poll-interval/log-tail plumbing shared by every wait
|
|
23
|
+
* strategy: probe once immediately (a sub-interval timeout must still get
|
|
24
|
+
* one chance to succeed — the off-by-one every naive port-wait gets wrong),
|
|
25
|
+
* then keep polling until either a probe reports ready or the deadline
|
|
26
|
+
* passes.
|
|
27
|
+
*/
|
|
28
|
+
declare abstract class AbstractWaitStrategy implements WaitStrategy {
|
|
29
|
+
/** The current startup deadline in milliseconds; defaults to 60s, overridden by `withStartupTimeout`. */
|
|
30
|
+
protected timeoutMs: number;
|
|
31
|
+
withStartupTimeout(ms: number): this;
|
|
32
|
+
/** One readiness check attempt; ready iff it resolves `true`. Implemented by each concrete strategy. */
|
|
33
|
+
protected abstract probe(target: WaitTarget): Promise<boolean>;
|
|
34
|
+
waitUntilReady(target: WaitTarget): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
/** Readiness = an HTTP GET against the container returning the expected status code (200 by default). Build via `Wait.forHttp`. */
|
|
37
|
+
export declare class HttpWaitStrategy extends AbstractWaitStrategy {
|
|
38
|
+
private path;
|
|
39
|
+
private port;
|
|
40
|
+
private expectedStatus;
|
|
41
|
+
constructor(path: string);
|
|
42
|
+
/** Probe this guest port instead of the first exposed one. */
|
|
43
|
+
forPort(port: number): this;
|
|
44
|
+
/** Expect this status code instead of 200. */
|
|
45
|
+
forStatusCode(status: number): this;
|
|
46
|
+
/** One HTTP GET attempt; ready iff the response status matches `forStatusCode` (default 200). Internal — called by the base class's poll loop. */
|
|
47
|
+
protected probe(target: WaitTarget): Promise<boolean>;
|
|
48
|
+
}
|
|
49
|
+
/** Factory namespace for the built-in wait strategies; pass the result to `GenericContainer.waitingFor`. */
|
|
50
|
+
export declare const Wait: {
|
|
51
|
+
/** Ready once every exposed port accepts a real peer (read-probed, not just connect — see `readProbe` above). The default strategy when none is set. */
|
|
52
|
+
forListeningPort(): WaitStrategy;
|
|
53
|
+
/** Ready once an HTTP GET to `path` returns the expected status. Chain `.forPort(n)` / `.forStatusCode(n)`. */
|
|
54
|
+
forHttp(path: string): HttpWaitStrategy;
|
|
55
|
+
/** Ready once `pattern` has matched at least `times` distinct log lines (default 1). `times=0` is ready immediately, without needing logs to be fetchable yet. */
|
|
56
|
+
forLogMessage(pattern: string, times?: number): WaitStrategy;
|
|
57
|
+
};
|
|
58
|
+
export {};
|
|
59
|
+
//# sourceMappingURL=wait.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wait.d.ts","sourceRoot":"","sources":["../../src/core/wait.ts"],"names":[],"mappings":"AAIA,8JAA8J;AAC9J,MAAM,WAAW,UAAU;IACzB,kDAAkD;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0CAA0C;IAC1C,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IACtC,wEAAwE;IACxE,QAAQ,CAAC,iBAAiB,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAClD,mHAAmH;IACnH,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/B,sFAAsF;IACtF,QAAQ,IAAI,MAAM,CAAC;CACpB;AAED,qHAAqH;AACrH,MAAM,WAAW,YAAY;IAC3B,sHAAsH;IACtH,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,CAAC;CAC9C;AAkCD;;;;;;GAMG;AACH,uBAAe,oBAAqB,YAAW,YAAY;IACzD,yGAAyG;IACzG,SAAS,CAAC,SAAS,SAAsB;IAEzC,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAKpC,wGAAwG;IACxG,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IAExD,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAexD;AA8ED,mIAAmI;AACnI,qBAAa,gBAAiB,SAAQ,oBAAoB;IACxD,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,cAAc,CAAO;gBAEjB,IAAI,EAAE,MAAM;IAKxB,8DAA8D;IAC9D,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK3B,8CAA8C;IAC9C,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAKnC,kJAAkJ;cAClI,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;CAsC5D;AAoCD,4GAA4G;AAC5G,eAAO,MAAM,IAAI;IACf,wJAAwJ;wBACpI,YAAY;IAGhC,+GAA+G;kBACjG,MAAM,GAAG,gBAAgB;IAGvC,kKAAkK;2BAC3I,MAAM,mBAAc,YAAY;CAGxD,CAAC"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import * as net from "node:net";
|
|
2
|
+
import * as http from "node:http";
|
|
3
|
+
import { ContainerLaunchError } from "./errors.js";
|
|
4
|
+
const DEFAULT_TIMEOUT_MS = 60_000;
|
|
5
|
+
const POLL_INTERVAL_MS = 250;
|
|
6
|
+
const LOG_TAIL_LINES = 50;
|
|
7
|
+
const READ_PROBE_TIMEOUT_MS = 200;
|
|
8
|
+
// Bounds the connect phase itself (before any byte has arrived), distinct
|
|
9
|
+
// from READ_PROBE_TIMEOUT_MS which bounds the post-connect idle read below.
|
|
10
|
+
// A short but non-trivial ceiling: a loopback connect to an already-bound
|
|
11
|
+
// port normally settles in well under a millisecond, so this is generous
|
|
12
|
+
// headroom for a slow host, not a tight budget.
|
|
13
|
+
const CONNECT_PROBE_TIMEOUT_MS = 2_000;
|
|
14
|
+
const HTTP_PROBE_TIMEOUT_MS = 1_000;
|
|
15
|
+
function sleep(ms) {
|
|
16
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
17
|
+
}
|
|
18
|
+
async function logTail(target) {
|
|
19
|
+
let logs;
|
|
20
|
+
try {
|
|
21
|
+
logs = await target.currentLogs();
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return "";
|
|
25
|
+
}
|
|
26
|
+
const lines = logs.split("\n");
|
|
27
|
+
return lines.slice(-LOG_TAIL_LINES).join("\n");
|
|
28
|
+
}
|
|
29
|
+
async function timeoutError(target) {
|
|
30
|
+
const tail = await logTail(target);
|
|
31
|
+
return new ContainerLaunchError(`Timed out waiting for ${target.describe()} to become ready.\n${tail}`);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Owns the deadline/poll-interval/log-tail plumbing shared by every wait
|
|
35
|
+
* strategy: probe once immediately (a sub-interval timeout must still get
|
|
36
|
+
* one chance to succeed — the off-by-one every naive port-wait gets wrong),
|
|
37
|
+
* then keep polling until either a probe reports ready or the deadline
|
|
38
|
+
* passes.
|
|
39
|
+
*/
|
|
40
|
+
class AbstractWaitStrategy {
|
|
41
|
+
/** The current startup deadline in milliseconds; defaults to 60s, overridden by `withStartupTimeout`. */
|
|
42
|
+
timeoutMs = DEFAULT_TIMEOUT_MS;
|
|
43
|
+
withStartupTimeout(ms) {
|
|
44
|
+
this.timeoutMs = ms;
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
async waitUntilReady(target) {
|
|
48
|
+
const deadline = Date.now() + this.timeoutMs;
|
|
49
|
+
// do-while: always probe at least once, even if the deadline has
|
|
50
|
+
// already passed by the time we get here (a 1ms timeout must still
|
|
51
|
+
// get its one shot).
|
|
52
|
+
for (;;) {
|
|
53
|
+
if (await this.probe(target)) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (Date.now() >= deadline) {
|
|
57
|
+
throw await timeoutError(target);
|
|
58
|
+
}
|
|
59
|
+
await sleep(POLL_INTERVAL_MS);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* A bare TCP connect succeeds against docker's userland proxy the instant
|
|
65
|
+
* the host port is published — before the guest process has bound its own
|
|
66
|
+
* listening socket. Connect-then-read distinguishes the two: an
|
|
67
|
+
* accept-with-nobody-behind-it proxy closes immediately (EOF/RST) on a
|
|
68
|
+
* zero-byte read, while a real peer either sends data or simply holds the
|
|
69
|
+
* connection open past the read timeout.
|
|
70
|
+
*/
|
|
71
|
+
function readProbe(host, port) {
|
|
72
|
+
return new Promise((resolveProbe) => {
|
|
73
|
+
const socket = new net.Socket();
|
|
74
|
+
let settled = false;
|
|
75
|
+
// First-event-wins: whichever of data/timeout/end/error fires first
|
|
76
|
+
// decides the verdict; every listener is torn down immediately so a
|
|
77
|
+
// later event on the same socket can never flip an already-resolved
|
|
78
|
+
// verdict (a chatty peer emitting `data` then `end` must resolve ready
|
|
79
|
+
// on the `data` and ignore the trailing `end`).
|
|
80
|
+
const finish = (ready) => {
|
|
81
|
+
if (settled) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
settled = true;
|
|
85
|
+
clearTimeout(hardTimer);
|
|
86
|
+
socket.removeAllListeners();
|
|
87
|
+
socket.destroy();
|
|
88
|
+
resolveProbe(ready);
|
|
89
|
+
};
|
|
90
|
+
// Hard backstop, independent of socket.setTimeout(): the socket-level
|
|
91
|
+
// timeout below is only armed AFTER connect succeeds, so a connect that
|
|
92
|
+
// neither succeeds nor errors — just hangs — has nothing to bound it,
|
|
93
|
+
// and a plain JS timer costs nothing to add as a second line of defense
|
|
94
|
+
// regardless. This one call's own AbstractWaitStrategy poll loop can't
|
|
95
|
+
// rescue a probe() that never resolves at all; every module that uses
|
|
96
|
+
// the default Wait.forListeningPort() depends on this call actually
|
|
97
|
+
// settling every time.
|
|
98
|
+
const hardTimer = setTimeout(() => finish(false), READ_PROBE_TIMEOUT_MS + CONNECT_PROBE_TIMEOUT_MS);
|
|
99
|
+
// The connect-phase timeout listener is named (not `.once`) so it can be
|
|
100
|
+
// explicitly removed once connect succeeds — leaving it attached would
|
|
101
|
+
// otherwise also fire on the READ-phase timeout re-armed below and race
|
|
102
|
+
// against that timeout's own "ready" verdict (this connect-phase one
|
|
103
|
+
// means not-ready; the post-connect one means ready — two different
|
|
104
|
+
// meanings for the same event name on the same socket).
|
|
105
|
+
const onConnectTimeout = () => finish(false);
|
|
106
|
+
socket.setTimeout(CONNECT_PROBE_TIMEOUT_MS);
|
|
107
|
+
socket.once("error", () => finish(false));
|
|
108
|
+
socket.once("timeout", onConnectTimeout);
|
|
109
|
+
socket.connect(port, host, () => {
|
|
110
|
+
socket.removeListener("timeout", onConnectTimeout);
|
|
111
|
+
socket.setTimeout(READ_PROBE_TIMEOUT_MS);
|
|
112
|
+
socket.once("data", () => finish(true));
|
|
113
|
+
socket.once("timeout", () => finish(true));
|
|
114
|
+
socket.once("end", () => finish(false));
|
|
115
|
+
socket.once("error", () => finish(false));
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
class ListeningPortWaitStrategy extends AbstractWaitStrategy {
|
|
120
|
+
async probe(target) {
|
|
121
|
+
if (target.exposedGuestPorts.length === 0) {
|
|
122
|
+
// No exposed ports: nothing to wait for on the network — vacuously ready.
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
for (const guestPort of target.exposedGuestPorts) {
|
|
126
|
+
const hostPort = target.mappedPort(guestPort);
|
|
127
|
+
if (!(await readProbe(target.host, hostPort))) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/** Readiness = an HTTP GET against the container returning the expected status code (200 by default). Build via `Wait.forHttp`. */
|
|
135
|
+
export class HttpWaitStrategy extends AbstractWaitStrategy {
|
|
136
|
+
path;
|
|
137
|
+
port;
|
|
138
|
+
expectedStatus = 200;
|
|
139
|
+
constructor(path) {
|
|
140
|
+
super();
|
|
141
|
+
this.path = path;
|
|
142
|
+
}
|
|
143
|
+
/** Probe this guest port instead of the first exposed one. */
|
|
144
|
+
forPort(port) {
|
|
145
|
+
this.port = port;
|
|
146
|
+
return this;
|
|
147
|
+
}
|
|
148
|
+
/** Expect this status code instead of 200. */
|
|
149
|
+
forStatusCode(status) {
|
|
150
|
+
this.expectedStatus = status;
|
|
151
|
+
return this;
|
|
152
|
+
}
|
|
153
|
+
/** One HTTP GET attempt; ready iff the response status matches `forStatusCode` (default 200). Internal — called by the base class's poll loop. */
|
|
154
|
+
async probe(target) {
|
|
155
|
+
const guestPort = this.port ?? target.exposedGuestPorts[0];
|
|
156
|
+
if (guestPort === undefined) {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
const hostPort = target.mappedPort(guestPort);
|
|
160
|
+
return new Promise((resolveProbe) => {
|
|
161
|
+
let settled = false;
|
|
162
|
+
const finish = (ready) => {
|
|
163
|
+
if (settled) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
settled = true;
|
|
167
|
+
clearTimeout(hardTimer);
|
|
168
|
+
resolveProbe(ready);
|
|
169
|
+
};
|
|
170
|
+
// Hard backstop alongside the `timeout` option below — see readProbe's
|
|
171
|
+
// comment in this same file for why a socket-level timeout alone isn't
|
|
172
|
+
// trusted as the only bound here.
|
|
173
|
+
const hardTimer = setTimeout(() => {
|
|
174
|
+
req.destroy();
|
|
175
|
+
finish(false);
|
|
176
|
+
}, HTTP_PROBE_TIMEOUT_MS + 500);
|
|
177
|
+
const req = http.request({ host: target.host, port: hostPort, path: this.path, method: "GET", timeout: HTTP_PROBE_TIMEOUT_MS }, (res) => {
|
|
178
|
+
res.resume();
|
|
179
|
+
finish(res.statusCode === this.expectedStatus);
|
|
180
|
+
});
|
|
181
|
+
req.once("timeout", () => {
|
|
182
|
+
req.destroy();
|
|
183
|
+
finish(false);
|
|
184
|
+
});
|
|
185
|
+
req.once("error", () => finish(false));
|
|
186
|
+
req.end();
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
class LogMessageWaitStrategy extends AbstractWaitStrategy {
|
|
191
|
+
pattern;
|
|
192
|
+
times;
|
|
193
|
+
constructor(pattern, times) {
|
|
194
|
+
super();
|
|
195
|
+
this.pattern = pattern;
|
|
196
|
+
this.times = times;
|
|
197
|
+
}
|
|
198
|
+
async probe(target) {
|
|
199
|
+
// times === 0 means "ready on the first probe, regardless of whether
|
|
200
|
+
// logs are even fetchable yet" — a command-only container's first probe
|
|
201
|
+
// may see currentLogs() throw or return "", and count() >= 0 is
|
|
202
|
+
// trivially true, so this branch never needs to touch the logs.
|
|
203
|
+
if (this.times === 0) {
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
206
|
+
let logs;
|
|
207
|
+
try {
|
|
208
|
+
logs = await target.currentLogs();
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
let matches = 0;
|
|
214
|
+
for (const line of logs.split("\n")) {
|
|
215
|
+
// A line matching both whole-line and as a substring still counts
|
|
216
|
+
// once per line — `test()` on the whole line, not a global exec loop.
|
|
217
|
+
if (this.pattern.test(line)) {
|
|
218
|
+
matches++;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return matches >= this.times;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/** Factory namespace for the built-in wait strategies; pass the result to `GenericContainer.waitingFor`. */
|
|
225
|
+
export const Wait = {
|
|
226
|
+
/** Ready once every exposed port accepts a real peer (read-probed, not just connect — see `readProbe` above). The default strategy when none is set. */
|
|
227
|
+
forListeningPort() {
|
|
228
|
+
return new ListeningPortWaitStrategy();
|
|
229
|
+
},
|
|
230
|
+
/** Ready once an HTTP GET to `path` returns the expected status. Chain `.forPort(n)` / `.forStatusCode(n)`. */
|
|
231
|
+
forHttp(path) {
|
|
232
|
+
return new HttpWaitStrategy(path);
|
|
233
|
+
},
|
|
234
|
+
/** Ready once `pattern` has matched at least `times` distinct log lines (default 1). `times=0` is ready immediately, without needing logs to be fetchable yet. */
|
|
235
|
+
forLogMessage(pattern, times = 1) {
|
|
236
|
+
return new LogMessageWaitStrategy(new RegExp(pattern), times);
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
//# sourceMappingURL=wait.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wait.js","sourceRoot":"","sources":["../../src/core/wait.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `rightsize` — the core entry point.
|
|
3
|
+
*
|
|
4
|
+
* Owns the public API surface every consumer builds on: `GenericContainer`
|
|
5
|
+
* (the builder + async-dispose lifecycle guard), `Network`, the `Wait`
|
|
6
|
+
* strategies, `FreePorts`, `RunId`, the `SandboxBackend`/`BackendProvider`
|
|
7
|
+
* contracts plus the `registerBackend` registry, and the typed error
|
|
8
|
+
* classes. This module depends on no backend — import `rightsize/backend-msb`
|
|
9
|
+
* and/or `rightsize/backend-docker` to register one, or `rightsize/modules`
|
|
10
|
+
* for the eighteen preconfigured containers built on top of this surface.
|
|
11
|
+
*
|
|
12
|
+
* @packageDocumentation
|
|
13
|
+
*/
|
|
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";
|
|
17
|
+
export { registerBackend, Backends } from "./core/backends.js";
|
|
18
|
+
export { FreePorts } from "./core/free-ports.js";
|
|
19
|
+
export { Wait, HttpWaitStrategy } from "./core/wait.js";
|
|
20
|
+
export type { WaitTarget, WaitStrategy } from "./core/wait.js";
|
|
21
|
+
export { RunId } from "./core/run-id.js";
|
|
22
|
+
export { Network } from "./core/network.js";
|
|
23
|
+
export type { NetworkMember } from "./core/network.js";
|
|
24
|
+
export { MountableFile } from "./core/mountable-file.js";
|
|
25
|
+
export { GenericContainer } from "./core/generic-container.js";
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `rightsize` — the core entry point.
|
|
3
|
+
*
|
|
4
|
+
* Owns the public API surface every consumer builds on: `GenericContainer`
|
|
5
|
+
* (the builder + async-dispose lifecycle guard), `Network`, the `Wait`
|
|
6
|
+
* strategies, `FreePorts`, `RunId`, the `SandboxBackend`/`BackendProvider`
|
|
7
|
+
* contracts plus the `registerBackend` registry, and the typed error
|
|
8
|
+
* classes. This module depends on no backend — import `rightsize/backend-msb`
|
|
9
|
+
* and/or `rightsize/backend-docker` to register one, or `rightsize/modules`
|
|
10
|
+
* for the eighteen preconfigured containers built on top of this surface.
|
|
11
|
+
*
|
|
12
|
+
* @packageDocumentation
|
|
13
|
+
*/
|
|
14
|
+
export { UnsupportedByBackendError, PortBindConflictError, ContainerLaunchError, BackendError, ProvisionError, } from "./core/errors.js";
|
|
15
|
+
export { registerBackend, Backends } from "./core/backends.js";
|
|
16
|
+
export { FreePorts } from "./core/free-ports.js";
|
|
17
|
+
export { Wait, HttpWaitStrategy } from "./core/wait.js";
|
|
18
|
+
export { RunId } from "./core/run-id.js";
|
|
19
|
+
export { Network } from "./core/network.js";
|
|
20
|
+
export { MountableFile } from "./core/mountable-file.js";
|
|
21
|
+
export { GenericContainer } from "./core/generic-container.js";
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { GenericContainer } from "../core/generic-container.js";
|
|
2
|
+
import type { ContainerSpec } from "../core/model.js";
|
|
3
|
+
/** A single-node ArangoDB container. Auth is disabled by default; see `withRootPassword` to enable it. */
|
|
4
|
+
export declare class ArangoContainer extends GenericContainer {
|
|
5
|
+
private rootPassword;
|
|
6
|
+
constructor(image?: string);
|
|
7
|
+
static start(image?: string): Promise<ArangoContainer>;
|
|
8
|
+
/** Enables auth with the given root password, instead of the default no-auth setup. */
|
|
9
|
+
withRootPassword(password: string): this;
|
|
10
|
+
protected customizeSpec(spec: ContainerSpec, _mapped: (guest: number) => number): ContainerSpec;
|
|
11
|
+
/** The HTTP API endpoint for the running container. */
|
|
12
|
+
get endpoint(): string;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=arango.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arango.d.ts","sourceRoot":"","sources":["../../src/modules/arango.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAEhE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAItD,0GAA0G;AAC1G,qBAAa,eAAgB,SAAQ,gBAAgB;IACnD,OAAO,CAAC,YAAY,CAAqB;gBAE7B,KAAK,SAAkB;WAOb,KAAK,CAAC,KAAK,SAAkB,GAAG,OAAO,CAAC,eAAe,CAAC;IAI9E,uFAAuF;IACvF,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;cAUrB,aAAa,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,aAAa;IAOxG,uDAAuD;IACvD,IAAI,QAAQ,IAAI,MAAM,CAErB;CACF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { GenericContainer } from "../core/generic-container.js";
|
|
2
|
+
import { Wait } from "../core/wait.js";
|
|
3
|
+
const GUEST_PORT = 8529;
|
|
4
|
+
/** A single-node ArangoDB container. Auth is disabled by default; see `withRootPassword` to enable it. */
|
|
5
|
+
export class ArangoContainer extends GenericContainer {
|
|
6
|
+
rootPassword;
|
|
7
|
+
constructor(image = "arangodb:3.11") {
|
|
8
|
+
super(image);
|
|
9
|
+
this.withExposedPorts(GUEST_PORT)
|
|
10
|
+
.withEnv("ARANGO_NO_AUTH", "1")
|
|
11
|
+
.waitingFor(Wait.forHttp("/_api/version").forPort(GUEST_PORT).forStatusCode(200));
|
|
12
|
+
}
|
|
13
|
+
static async start(image = "arangodb:3.11") {
|
|
14
|
+
return (await new ArangoContainer(image).start());
|
|
15
|
+
}
|
|
16
|
+
/** Enables auth with the given root password, instead of the default no-auth setup. */
|
|
17
|
+
withRootPassword(password) {
|
|
18
|
+
this.rootPassword = password;
|
|
19
|
+
return this.withEnv("ARANGO_ROOT_PASSWORD", password);
|
|
20
|
+
}
|
|
21
|
+
// ARANGO_NO_AUTH and ARANGO_ROOT_PASSWORD are mutually exclusive on the
|
|
22
|
+
// image; GenericContainer has no env-removal builder, so the no-auth
|
|
23
|
+
// default is dropped here, at spec-build time, once a root password has
|
|
24
|
+
// actually been requested — rather than threading a removeEnv method
|
|
25
|
+
// through the base class for one module's one edge case.
|
|
26
|
+
customizeSpec(spec, _mapped) {
|
|
27
|
+
if (this.rootPassword === undefined) {
|
|
28
|
+
return spec;
|
|
29
|
+
}
|
|
30
|
+
return { ...spec, env: spec.env.filter(([key]) => key !== "ARANGO_NO_AUTH") };
|
|
31
|
+
}
|
|
32
|
+
/** The HTTP API endpoint for the running container. */
|
|
33
|
+
get endpoint() {
|
|
34
|
+
return `http://${this.host}:${this.getMappedPort(GUEST_PORT)}`;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=arango.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arango.js","sourceRoot":"","sources":["../../src/modules/arango.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAGvC,MAAM,UAAU,GAAG,IAAI,CAAC;AAExB,0GAA0G;AAC1G,MAAM,OAAO,eAAgB,SAAQ,gBAAgB;IAC3C,YAAY,CAAqB;IAEzC,YAAY,KAAK,GAAG,eAAe;QACjC,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC;aAC9B,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC;aAC9B,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;IACtF,CAAC;IAED,MAAM,CAAU,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,eAAe;QACjD,OAAO,CAAC,MAAM,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAoB,CAAC;IACvE,CAAC;IAED,uFAAuF;IACvF,gBAAgB,CAAC,QAAgB;QAC/B,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC;QAC7B,OAAO,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE,QAAQ,CAAC,CAAC;IACxD,CAAC;IAED,wEAAwE;IACxE,qEAAqE;IACrE,wEAAwE;IACxE,qEAAqE;IACrE,yDAAyD;IACtC,aAAa,CAAC,IAAmB,EAAE,OAAkC;QACtF,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,gBAAgB,CAAC,EAAE,CAAC;IAChF,CAAC;IAED,uDAAuD;IACvD,IAAI,QAAQ;QACV,OAAO,UAAU,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC;IACjE,CAAC;CACF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { GenericContainer } from "../core/generic-container.js";
|
|
2
|
+
/**
|
|
3
|
+
* A single-node ClickHouse container, ready-checked via `/ping` (returns
|
|
4
|
+
* the literal body `Ok.` on 200 — `Wait.forHttp`'s status-code check is all
|
|
5
|
+
* that's needed here). Exposes both the HTTP interface (8123, what the
|
|
6
|
+
* helpers here use) and the native protocol port (9000) for consumers that
|
|
7
|
+
* want a native-protocol client instead.
|
|
8
|
+
*
|
|
9
|
+
* `CLICKHOUSE_USER`/`CLICKHOUSE_PASSWORD`/`CLICKHOUSE_DB` (verified against
|
|
10
|
+
* the entrypoint's own logging: `create new user 'test' instead 'default'`,
|
|
11
|
+
* `create database 'test'`) replace the image's default `default` user
|
|
12
|
+
* entirely — once set, the unauthenticated `default` user's usual
|
|
13
|
+
* passwordless access is gone, and every query needs the configured
|
|
14
|
+
* credentials.
|
|
15
|
+
*/
|
|
16
|
+
export declare class ClickHouseContainer extends GenericContainer {
|
|
17
|
+
private usernameState;
|
|
18
|
+
private passwordState;
|
|
19
|
+
private databaseState;
|
|
20
|
+
constructor(image?: string);
|
|
21
|
+
static start(image?: string): Promise<ClickHouseContainer>;
|
|
22
|
+
/** Overrides `CLICKHOUSE_USER` (default `test`). */
|
|
23
|
+
withUsername(username: string): this;
|
|
24
|
+
/** Overrides `CLICKHOUSE_PASSWORD` (default `test`). */
|
|
25
|
+
withPassword(password: string): this;
|
|
26
|
+
/** Overrides `CLICKHOUSE_DB` (default `test`). */
|
|
27
|
+
withDatabase(database: string): this;
|
|
28
|
+
/** The configured user (default `test`). */
|
|
29
|
+
get username(): string;
|
|
30
|
+
/** The configured password (default `test`). */
|
|
31
|
+
get password(): string;
|
|
32
|
+
/** The configured database name (default `test`). */
|
|
33
|
+
get databaseName(): string;
|
|
34
|
+
/** The HTTP interface's base URL for the running container. */
|
|
35
|
+
get httpUrl(): string;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=clickhouse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clickhouse.d.ts","sourceRoot":"","sources":["../../src/modules/clickhouse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAMhE;;;;;;;;;;;;;GAaG;AACH,qBAAa,mBAAoB,SAAQ,gBAAgB;IACvD,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,aAAa,CAAU;gBAEnB,KAAK,SAAsC;WAYjC,KAAK,CAAC,KAAK,SAAsC,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAItG,oDAAoD;IACpD,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKpC,wDAAwD;IACxD,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKpC,kDAAkD;IAClD,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKpC,4CAA4C;IAC5C,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,gDAAgD;IAChD,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,qDAAqD;IACrD,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,+DAA+D;IAC/D,IAAI,OAAO,IAAI,MAAM,CAEpB;CACF"}
|