alasio 4.1.4 → 4.2.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 (49) hide show
  1. package/dist/cli/src/cluster/docker-engine.js +216 -0
  2. package/dist/cli/src/cluster/docker-engine.js.map +1 -0
  3. package/dist/cli/src/cluster/docker.js +294 -199
  4. package/dist/cli/src/cluster/docker.js.map +1 -1
  5. package/dist/cli/src/cluster/host.js +235 -57
  6. package/dist/cli/src/cluster/host.js.map +1 -1
  7. package/dist/cli/src/cluster/k3s.js +108 -0
  8. package/dist/cli/src/cluster/k3s.js.map +1 -0
  9. package/dist/cli/src/cluster/machine.js +173 -0
  10. package/dist/cli/src/cluster/machine.js.map +1 -0
  11. package/dist/cli/src/cluster/node.js +392 -0
  12. package/dist/cli/src/cluster/node.js.map +1 -0
  13. package/dist/cli/src/cluster/root.js +109 -0
  14. package/dist/cli/src/cluster/root.js.map +1 -0
  15. package/dist/cli/src/cluster/tar.js +32 -0
  16. package/dist/cli/src/cluster/tar.js.map +1 -0
  17. package/dist/cli/src/commands/as-root.js +15 -0
  18. package/dist/cli/src/commands/as-root.js.map +1 -0
  19. package/dist/cli/src/commands/common.js +26 -15
  20. package/dist/cli/src/commands/common.js.map +1 -1
  21. package/dist/cli/src/commands/down.js +9 -4
  22. package/dist/cli/src/commands/down.js.map +1 -1
  23. package/dist/cli/src/commands/init.js +35 -28
  24. package/dist/cli/src/commands/init.js.map +1 -1
  25. package/dist/cli/src/commands/status.js +29 -14
  26. package/dist/cli/src/commands/status.js.map +1 -1
  27. package/dist/cli/src/commands/uninstall.js +23 -9
  28. package/dist/cli/src/commands/uninstall.js.map +1 -1
  29. package/dist/cli/src/commands/up.js +26 -9
  30. package/dist/cli/src/commands/up.js.map +1 -1
  31. package/dist/cli/src/commands/upgrade.js +2 -1
  32. package/dist/cli/src/commands/upgrade.js.map +1 -1
  33. package/dist/cli/src/commands.js +2 -1
  34. package/dist/cli/src/commands.js.map +1 -1
  35. package/dist/cli/src/config.js +55 -27
  36. package/dist/cli/src/config.js.map +1 -1
  37. package/dist/cli/src/kube/api.js +1 -0
  38. package/dist/cli/src/kube/api.js.map +1 -1
  39. package/dist/cli/src/main.js +4 -2
  40. package/dist/cli/src/main.js.map +1 -1
  41. package/dist/cli/src/release.js +6 -6
  42. package/dist/cli/src/release.js.map +1 -1
  43. package/dist/cli/src/target.js +43 -27
  44. package/dist/cli/src/target.js.map +1 -1
  45. package/dist/cluster/node/config-v3.toml.tmpl +12 -0
  46. package/dist/cluster/node/pins.json +15 -0
  47. package/package.json +2 -2
  48. package/dist/cli/src/cluster/local.js +0 -392
  49. package/dist/cli/src/cluster/local.js.map +0 -1
@@ -0,0 +1,216 @@
1
+ /**
2
+ * Docker's Engine API, over the Unix socket Docker listens on: as much of it as the
3
+ * cluster in Docker (./docker.ts) needs, its images, network, volumes and containers and
4
+ * commands run in them, called with node:http, so neither the Docker CLI nor a client
5
+ * library is needed. Paths are those of API version 1.44 (Docker 25), the oldest it is
6
+ * written for.
7
+ *
8
+ * The socket is the one `DOCKER_HOST` names (`unix://PATH`), /var/run/docker.sock when
9
+ * it names none.
10
+ */
11
+ import { request as httpRequest, STATUS_CODES } from "node:http";
12
+ import { buffer } from "node:stream/consumers";
13
+ import { Context, Effect, Layer, Result, Schedule, Schema } from "effect";
14
+ import { tarEntries } from "./tar.js";
15
+ const API_VERSION = "v1.44";
16
+ const DEFAULT_SOCKET = "/var/run/docker.sock";
17
+ /** Docker refused a call, or could not be reached: the status it answered with, when it answered. */
18
+ export class DockerError extends Schema.TaggedError()("DockerError", {
19
+ /** The call, as its method and path. */
20
+ call: Schema.String,
21
+ /** Docker's HTTP status (404 for absent, 409 for a conflict), when it answered. */
22
+ status: Schema.optional(Schema.Number),
23
+ /** What Docker answered, or why it could not be reached. */
24
+ reason: Schema.String,
25
+ }) {
26
+ get message() {
27
+ return `Docker ${this.status === undefined ? "failed" : `answered ${this.status} to`} ${this.call}: ${this.reason}`;
28
+ }
29
+ }
30
+ /** `DOCKER_HOST` names a Docker that is not reached over a Unix socket. */
31
+ export class DockerHostUnsupported extends Schema.TaggedError()("DockerHostUnsupported", {
32
+ host: Schema.String,
33
+ }) {
34
+ get message() {
35
+ return `DOCKER_HOST is ${this.host}, but alasio reaches Docker only over a Unix socket (unix://PATH)`;
36
+ }
37
+ }
38
+ /** Whether `error` is Docker's answer `status`. */
39
+ export const hasStatus = (status) => (error) => error.status === status;
40
+ /**
41
+ * Whether `error` is Docker's answer to removing a container it killed but did not see
42
+ * exit within the time it waits: the kill stands, and the container exits once its
43
+ * processes do, which those waiting on a FUSE mount whose client dies with them, as
44
+ * JuiceFS's on a node are, can take longer to.
45
+ */
46
+ const killedNotYetExited = (error) => error.status === 500 && error.reason.includes("did not receive an exit event");
47
+ /** The socket of the Docker `env` names, by `DOCKER_HOST`. */
48
+ export function dockerSocket(env) {
49
+ const host = env["DOCKER_HOST"];
50
+ if (!host)
51
+ return Result.succeed(DEFAULT_SOCKET);
52
+ if (host.startsWith("unix://"))
53
+ return Result.succeed(host.slice("unix://".length));
54
+ return Result.fail(new DockerHostUnsupported({ host }));
55
+ }
56
+ /** Docker's Engine API, as the cluster in Docker calls it. Objects are addressed by name. */
57
+ export class DockerEngine extends Context.Service()("alasio/cluster/DockerEngine") {
58
+ /** The Docker `env` names (dockerSocket). */
59
+ static layer = (env = process.env) => Layer.effect(DockerEngine, Effect.map(Effect.fromResult(dockerSocket(env)), makeDockerEngine));
60
+ }
61
+ const describe = (call) => `${call.method} ${call.path}`;
62
+ const unreachable = (call, cause) => new DockerError({ call: describe(call), reason: cause instanceof Error ? cause.message : String(cause) });
63
+ /** A label filter of a list call, in the JSON Docker's `filters` parameter takes. */
64
+ const labelFilter = (labels) => JSON.stringify({ label: Object.entries(labels).map(([key, value]) => `${key}=${value}`) });
65
+ /** The content of the first regular file in `tar`, a tar archive as Docker's archive endpoint sends one; null when it holds none. */
66
+ export function firstFile(tar) {
67
+ return tarEntries(tar).find(({ type }) => type === "file")?.content ?? null;
68
+ }
69
+ /**
70
+ * The output of a command whose exec ran without a terminal: Docker sends it in frames of
71
+ * an 8-byte header (the stream, 1 for stdout or 2 for stderr, and the size, big-endian, at
72
+ * byte 4) and what was written.
73
+ */
74
+ export function demultiplex(raw) {
75
+ const stdout = [];
76
+ const stderr = [];
77
+ for (let offset = 0; offset + 8 <= raw.length;) {
78
+ const size = raw.readUInt32BE(offset + 4);
79
+ const payload = raw.subarray(offset + 8, offset + 8 + size);
80
+ (raw[offset] === 2 ? stderr : stdout).push(payload);
81
+ offset += 8 + size;
82
+ }
83
+ return { stdout: Buffer.concat(stdout), stderr: Buffer.concat(stderr) };
84
+ }
85
+ /** The Engine API on the Unix socket `socketPath`. */
86
+ function makeDockerEngine(socketPath) {
87
+ const send = (call, headers = {}) => {
88
+ const query = new URLSearchParams();
89
+ for (const [key, value] of Object.entries(call.query ?? {})) {
90
+ for (const each of typeof value === "string" ? [value] : value)
91
+ query.append(key, each);
92
+ }
93
+ const body = call.body === undefined ? undefined : JSON.stringify(call.body);
94
+ const request = httpRequest({
95
+ socketPath,
96
+ method: call.method,
97
+ path: `/${API_VERSION}${call.path}${query.size ? `?${query}` : ""}`,
98
+ headers: body === undefined ? headers : { ...headers, "Content-Type": "application/json", "Content-Length": Buffer.byteLength(body) },
99
+ });
100
+ request.end(body);
101
+ return request;
102
+ };
103
+ const readAll = (call, stream) => Effect.tryPromise({ try: () => buffer(stream), catch: (cause) => unreachable(call, cause) });
104
+ /** Docker's refusal of `call`: the status of `response`, and the message its body holds. */
105
+ const refusal = (call, response) => readAll(call, response).pipe(Effect.flatMap((body) => {
106
+ const status = response.statusCode ?? 0;
107
+ const text = body.toString("utf8").trim();
108
+ let reason = text || STATUS_CODES[status] || "no message";
109
+ try {
110
+ const parsed = JSON.parse(text);
111
+ if (typeof parsed === "object" && parsed !== null && "message" in parsed && typeof parsed.message === "string")
112
+ reason = parsed.message;
113
+ }
114
+ catch {
115
+ // Not JSON: the text is the message.
116
+ }
117
+ return Effect.fail(new DockerError({ call: describe(call), status, reason }));
118
+ }));
119
+ /** The response to `call`, open while the scope is; a status of 400 or over is its refusal (304, already so, is not). */
120
+ const open = (call) => Effect.acquireRelease(Effect.callback((resume) => {
121
+ const request = send(call);
122
+ request.on("response", (response) => resume(Effect.succeed(response)));
123
+ request.on("error", (cause) => resume(Effect.fail(unreachable(call, cause))));
124
+ return Effect.sync(() => request.destroy());
125
+ }), (response) => Effect.sync(() => response.destroy())).pipe(Effect.tap((response) => ((response.statusCode ?? 0) >= 400 ? refusal(call, response) : Effect.void)));
126
+ const body = (call) => Effect.scoped(Effect.flatMap(open(call), (response) => readAll(call, response)));
127
+ /** The JSON Docker answers `call` with, as the Engine API documents it. */
128
+ const json = (call) => Effect.map(body(call), (content) => JSON.parse(content.toString("utf8")));
129
+ const orNull = (effect) => effect.pipe(Effect.catchIf(hasStatus(404), () => Effect.succeed(null)));
130
+ const orGone = (effect) => effect.pipe(Effect.asVoid, Effect.catchIf(hasStatus(404), () => Effect.void));
131
+ const name = (value) => encodeURIComponent(value);
132
+ /**
133
+ * Starts exec `id` attached, `stdin` written to it and then closed, and collects what it
134
+ * writes until it ends. Docker upgrades the connection to a raw stream for this.
135
+ */
136
+ const attach = (id, stdin) => {
137
+ const call = { method: "POST", path: `/exec/${id}/start`, body: { Detach: false, Tty: false } };
138
+ return Effect.callback((resume) => {
139
+ const request = send(call, { Connection: "Upgrade", Upgrade: "tcp" });
140
+ let stream = null;
141
+ request.on("upgrade", (_response, socket, head) => {
142
+ stream = socket;
143
+ const chunks = [head];
144
+ socket.on("data", (chunk) => chunks.push(chunk));
145
+ socket.on("error", (cause) => resume(Effect.fail(unreachable(call, cause))));
146
+ socket.on("close", () => resume(Effect.succeed(Buffer.concat(chunks))));
147
+ if (stdin !== undefined)
148
+ socket.end(stdin);
149
+ });
150
+ // A daemon that answers without upgrading refused.
151
+ request.on("response", (response) => resume(refusal(call, response)));
152
+ request.on("error", (cause) => resume(Effect.fail(unreachable(call, cause))));
153
+ return Effect.sync(() => {
154
+ request.destroy();
155
+ stream?.destroy();
156
+ });
157
+ });
158
+ };
159
+ const exec = Effect.fnUntraced(function* (container, command, { stdin } = {}) {
160
+ const { Id: id } = yield* json({
161
+ method: "POST",
162
+ path: `/containers/${name(container)}/exec`,
163
+ body: { AttachStdin: stdin !== undefined, AttachStdout: true, AttachStderr: true, Tty: false, Cmd: command },
164
+ });
165
+ const { stdout, stderr } = demultiplex(yield* attach(id, stdin));
166
+ // Docker records the exit code before it closes the exec's streams.
167
+ const inspect = { method: "GET", path: `/exec/${id}/json` };
168
+ const { ExitCode: exitCode } = yield* json(inspect);
169
+ if (exitCode === null)
170
+ return yield* new DockerError({ call: describe(inspect), reason: `${JSON.stringify(command[0])} has no exit code` });
171
+ return { exitCode, stdout, stderr: stderr.toString("utf8") };
172
+ });
173
+ const pullImage = Effect.fnUntraced(function* (reference) {
174
+ const call = { method: "POST", path: "/images/create", query: { fromImage: reference } };
175
+ // A pull that fails once it has begun still answers 200: its progress, one JSON object
176
+ // a line, ends with the error.
177
+ const progress = (yield* body(call)).toString("utf8").split("\n").filter((line) => line.trim());
178
+ for (const line of progress) {
179
+ const { error } = JSON.parse(line);
180
+ if (error)
181
+ return yield* new DockerError({ call: describe(call), reason: error });
182
+ }
183
+ });
184
+ const readFile = Effect.fnUntraced(function* (container, path) {
185
+ const call = { method: "GET", path: `/containers/${name(container)}/archive`, query: { path } };
186
+ const file = firstFile(yield* body(call));
187
+ if (!file)
188
+ return yield* new DockerError({ call: describe(call), reason: `${path} in ${container} is not a file` });
189
+ return file;
190
+ });
191
+ return DockerEngine.of({
192
+ version: json({ method: "GET", path: "/version" }),
193
+ // A reference as it is: the route takes its slashes and colons.
194
+ inspectImage: (reference) => orNull(json({ method: "GET", path: `/images/${reference}/json` })),
195
+ pullImage,
196
+ inspectNetwork: (network) => orNull(json({ method: "GET", path: `/networks/${name(network)}` })),
197
+ listNetworks: json({ method: "GET", path: "/networks" }),
198
+ createNetwork: (network) => Effect.asVoid(body({ method: "POST", path: "/networks/create", body: network })),
199
+ removeNetwork: (network) => orGone(body({ method: "DELETE", path: `/networks/${name(network)}` })),
200
+ disconnectNetwork: (network, container) => Effect.asVoid(body({ method: "POST", path: `/networks/${name(network)}/disconnect`, body: { Container: container, Force: true } })),
201
+ createVolume: (volume) => Effect.asVoid(body({ method: "POST", path: "/volumes/create", body: volume })),
202
+ listVolumes: (labels) => json({ method: "GET", path: "/volumes", query: { filters: labelFilter(labels) } }).pipe(Effect.map(({ Volumes }) => Volumes ?? [])),
203
+ removeVolume: (volume) => orGone(body({ method: "DELETE", path: `/volumes/${name(volume)}` })),
204
+ listContainers: (labels) => json({ method: "GET", path: "/containers/json", query: { all: "true", filters: labelFilter(labels) } }),
205
+ inspectContainer: (container) => orNull(json({ method: "GET", path: `/containers/${name(container)}/json` })),
206
+ createContainer: (container, spec) => Effect.asVoid(body({ method: "POST", path: "/containers/create", query: { name: container }, body: spec })),
207
+ startContainer: (container) => Effect.asVoid(body({ method: "POST", path: `/containers/${name(container)}/start` })),
208
+ stopContainer: (container) => Effect.asVoid(body({ method: "POST", path: `/containers/${name(container)}/stop` })),
209
+ // Asked again while Docker has killed it but not seen it exit, for as long as a
210
+ // node's dying processes may take.
211
+ removeContainer: (container) => orGone(body({ method: "DELETE", path: `/containers/${name(container)}`, query: { force: "true" } }).pipe(Effect.retry({ while: killedNotYetExited, schedule: Schedule.max([Schedule.spaced("1 second"), Schedule.during("2 minutes")]) }))),
212
+ exec,
213
+ readFile,
214
+ });
215
+ }
216
+ //# sourceMappingURL=docker-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-engine.js","sourceRoot":"","sources":["../../../../src/cluster/docker-engine.ts"],"names":[],"mappings":"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"}