alasio 4.1.3 → 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 (50) 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/manifests/config.js +2 -2
  42. package/dist/cli/src/release.js +6 -6
  43. package/dist/cli/src/release.js.map +1 -1
  44. package/dist/cli/src/target.js +43 -27
  45. package/dist/cli/src/target.js.map +1 -1
  46. package/dist/cluster/node/config-v3.toml.tmpl +12 -0
  47. package/dist/cluster/node/pins.json +15 -0
  48. package/package.json +2 -2
  49. package/dist/cli/src/cluster/local.js +0 -392
  50. package/dist/cli/src/cluster/local.js.map +0 -1
@@ -0,0 +1,173 @@
1
+ /**
2
+ * What a cluster alasio makes on this machine needs of the machine: Linux on x86-64, which
3
+ * its k3s and gVisor are built for, and inotify limits that hold its file watches. Every
4
+ * process that runs as root on the machine, in a container or not, shares
5
+ * fs.inotify.max_user_instances, as root, with the machine's own: k3s, kubelet,
6
+ * containerd's shims, and each pod's, so the kernel's default of 128 runs out once a few
7
+ * dozen pods run, and new pods then fail to start. kind and k3d ask the same of a machine.
8
+ * alasio raises the limits that are too low itself, as root (./root.ts): now, and for
9
+ * every boot, in a file of /etc/sysctl.d/ of its own.
10
+ *
11
+ * The machine is its kind and its files, under the directory that stands for its root,
12
+ * which is / but in tests; what alasio does to it as root, it does to those files, and
13
+ * through RootSystem, which runs commands and kills processes.
14
+ */
15
+ import { spawn } from "node:child_process";
16
+ import { join } from "node:path";
17
+ import { Context, Effect, FileSystem, Layer, Schema } from "effect";
18
+ /** The operating system and architecture a cluster on this machine runs on, as Node names them. */
19
+ const LOCAL_PLATFORM = { platform: "linux", arch: "x64" };
20
+ /** This machine: its operating system and processor architecture, as Node names them, and the directory that stands for its root. */
21
+ export class Machine extends Context.Service()("alasio/cluster/Machine") {
22
+ /** This process's. */
23
+ static layer = Layer.succeed(Machine, Machine.of({ platform: process.platform, arch: process.arch, root: "/" }));
24
+ }
25
+ /** Where `path`, a path of this machine, is under `root`. */
26
+ export const under = (root, path) => join(root, path);
27
+ /** This machine is not one a cluster alasio makes runs on: what it is. */
28
+ export class UnsupportedMachine extends Schema.TaggedError()("UnsupportedMachine", {
29
+ platform: Schema.String,
30
+ arch: Schema.String,
31
+ }) {
32
+ get message() {
33
+ return `the cluster alasio makes on this machine runs on Linux on x86-64, and this is ${this.platform} on ${this.arch}: ` +
34
+ "run alasio on such a machine, or give it a cluster elsewhere with alasio init --kubeconfig";
35
+ }
36
+ }
37
+ /** Fails, saying what this machine is, unless a cluster alasio makes runs on it. */
38
+ export const requireLocalMachine = Effect.flatMap(Machine, ({ platform, arch }) => platform === LOCAL_PLATFORM.platform && arch === LOCAL_PLATFORM.arch ? Effect.void : Effect.fail(new UnsupportedMachine({ platform, arch })));
39
+ /** The inotify limits a cluster on this machine needs, by their sysctl names: at least these. */
40
+ export const INOTIFY_MINIMUMS = {
41
+ "fs.inotify.max_user_instances": 1024,
42
+ "fs.inotify.max_user_watches": 524288,
43
+ };
44
+ /** Where alasio raises the inotify limits for every boot: a file of /etc/sysctl.d/ of its own. */
45
+ export const SYSCTL_FILE = "/etc/sysctl.d/60-alasio-inotify.conf";
46
+ /** The path of the sysctl `name` under /proc/sys, its dots the path's slashes. */
47
+ const procSys = (name) => `/proc/sys/${name.replaceAll(".", "/")}`;
48
+ /** A limit lower than a cluster on this machine needs: its sysctl name, its value, and the least it needs. */
49
+ const Shortfall = Schema.Struct({ name: Schema.String, value: Schema.Number, minimum: Schema.Number });
50
+ /** How a shortfall reads. */
51
+ export const describeShortfall = ({ name, value, minimum }) => `${name} is ${value}, and the cluster needs at least ${minimum}`;
52
+ /** This machine's inotify limits are lower than a cluster on it needs: which, and what raises them. */
53
+ export class InotifyLimitsTooLow extends Schema.TaggedError()("InotifyLimitsTooLow", {
54
+ shortfalls: Schema.Array(Shortfall),
55
+ }) {
56
+ get message() {
57
+ return [
58
+ "this machine's inotify limits are too low for the cluster alasio makes on it:",
59
+ ...this.shortfalls.map((shortfall) => ` ${describeShortfall(shortfall)}`),
60
+ "alasio up raises them, as root.",
61
+ ].join("\n");
62
+ }
63
+ }
64
+ /** The inotify limits of this machine that are lower than a cluster on it needs. */
65
+ export const inotifyShortfalls = Effect.gen(function* () {
66
+ const fs = yield* FileSystem.FileSystem;
67
+ const { root } = yield* Machine;
68
+ const limits = yield* Effect.forEach(Object.entries(INOTIFY_MINIMUMS), ([name, minimum]) => Effect.map(fs.readFileString(under(root, procSys(name))), (text) => ({ name, value: Number(text.trim()), minimum })));
69
+ // One that reads as no number is short too.
70
+ return limits.filter(({ value, minimum }) => !(value >= minimum));
71
+ });
72
+ /** A command alasio ran as root exited with another code than 0, or did not start. */
73
+ export class RootCommandFailed extends Schema.TaggedError()("RootCommandFailed", {
74
+ command: Schema.String,
75
+ reason: Schema.String,
76
+ }) {
77
+ get message() {
78
+ return `${this.command} ${this.reason}`;
79
+ }
80
+ }
81
+ /**
82
+ * What alasio does to this machine as root beyond its files: the commands it runs, whose
83
+ * output goes to stderr, as what a command is doing does, those it asks something, and the
84
+ * processes it kills, by their executables.
85
+ */
86
+ export class RootSystem extends Context.Service()("alasio/cluster/RootSystem") {
87
+ /** This machine itself. */
88
+ static layer = Layer.effect(RootSystem, Effect.map(FileSystem.FileSystem, (fs) => RootSystem.of({
89
+ run: (command, args, env = {}) => Effect.callback((resume) => {
90
+ const failed = (reason) => resume(Effect.fail(new RootCommandFailed({ command: [command, ...args].join(" "), reason })));
91
+ const child = spawn(command, args, { env: { ...process.env, ...env }, stdio: ["ignore", process.stderr, process.stderr] });
92
+ child.on("error", (cause) => failed(`did not start: ${cause.message}`));
93
+ child.on("close", (code, signal) => (code === 0 ? resume(Effect.void) : failed(signal ? `was killed by ${signal}` : `exited with ${code}`)));
94
+ }),
95
+ ask: (command, args) => Effect.callback((resume) => {
96
+ const child = spawn(command, args, { stdio: ["ignore", "pipe", process.stderr] });
97
+ let stdout = "";
98
+ child.stdout.on("data", (chunk) => (stdout += chunk));
99
+ child.on("error", (cause) => resume(Effect.fail(new RootCommandFailed({ command: [command, ...args].join(" "), reason: `did not start: ${cause.message}` }))));
100
+ child.on("close", (code) => resume(Effect.succeed({ exitCode: code ?? 1, stdout })));
101
+ }),
102
+ kill: (executables) => Effect.gen(function* () {
103
+ let killed = 0;
104
+ for (const pid of (yield* fs.readDirectory("/proc")).filter((entry) => /^\d+$/u.test(entry))) {
105
+ // A process gone since, or a kernel thread, has no executable to read.
106
+ const executable = yield* fs.readLink(`/proc/${pid}/exe`).pipe(Effect.orElseSucceed(() => ""));
107
+ if (!executables.includes(executable.replace(/ \(deleted\)$/u, "")))
108
+ continue;
109
+ try {
110
+ process.kill(Number(pid), "SIGKILL");
111
+ killed += 1;
112
+ }
113
+ catch {
114
+ // Gone already.
115
+ }
116
+ }
117
+ return killed;
118
+ }),
119
+ })));
120
+ }
121
+ /** The step that raises the limits that are too low, to the least a cluster here needs, now and for every boot. */
122
+ export const RaiseInotify = Schema.TaggedStruct("RaiseInotify", {
123
+ limits: Schema.Array(Schema.Struct({ name: Schema.String, minimum: Schema.Number })),
124
+ });
125
+ /** The step that raises this machine's inotify limits that are too low, or none when none is. */
126
+ export const inotifyStep = Effect.map(inotifyShortfalls, (shortfalls) => (shortfalls.length > 0 ? RaiseInotify.make({ limits: shortfalls.map(({ name, minimum }) => ({ name, minimum })) }) : null));
127
+ /** What the step does, as alasio says it will. */
128
+ export const describeRaiseInotify = ({ limits }) => `raise ${limits.map(({ name, minimum }) => `${name} to ${minimum}`).join(" and ")}, now and for every boot, in ${SYSCTL_FILE}`;
129
+ /** The limits SYSCTL_FILE says, `name = value` a line, by name. */
130
+ function sysctlLimits(file) {
131
+ return new Map(file.split("\n").flatMap((line) => {
132
+ const match = /^\s*([\w.]+)\s*=\s*(\S+)\s*$/u.exec(line);
133
+ return match ? [[match[1] ?? "", match[2] ?? ""]] : [];
134
+ }));
135
+ }
136
+ /** SYSCTL_FILE with `limits`, beside those it says already. */
137
+ function sysctlFile(existing, limits) {
138
+ const said = new Map(sysctlLimits(existing));
139
+ for (const { name, minimum } of limits)
140
+ said.set(name, String(minimum));
141
+ const header = "# The inotify limits the cluster alasio makes here needs, which alasio raised; alasio uninstall --purge removes this file.";
142
+ return [header, ...[...said].map(([name, value]) => `${name} = ${value}`), ""].join("\n");
143
+ }
144
+ /** Raises the limits, as root: in SYSCTL_FILE, beside those raised before, and in the running kernel. */
145
+ export const raiseInotify = Effect.fnUntraced(function* ({ limits }) {
146
+ const fs = yield* FileSystem.FileSystem;
147
+ const { root } = yield* Machine;
148
+ const file = under(root, SYSCTL_FILE);
149
+ const existing = (yield* fs.exists(file)) ? yield* fs.readFileString(file) : "";
150
+ yield* fs.makeDirectory(under(root, "/etc/sysctl.d"), { recursive: true });
151
+ yield* fs.writeFileString(file, sysctlFile(existing, limits));
152
+ for (const { name, minimum } of limits)
153
+ yield* fs.writeFileString(under(root, procSys(name)), `${minimum}\n`);
154
+ yield* Effect.logInfo(`raised ${limits.map(({ name, minimum }) => `${name} to ${minimum}`).join(" and ")}`);
155
+ });
156
+ /** The step that removes SYSCTL_FILE, which raises the inotify limits at every boot; the running kernel keeps them until it stops. */
157
+ export const ForgetInotify = Schema.TaggedStruct("ForgetInotify", {});
158
+ /** The step that removes SYSCTL_FILE, or none when there is none. */
159
+ export const forgetInotifyStep = Effect.gen(function* () {
160
+ const fs = yield* FileSystem.FileSystem;
161
+ const { root } = yield* Machine;
162
+ return (yield* fs.exists(under(root, SYSCTL_FILE))) ? ForgetInotify.make({}) : null;
163
+ });
164
+ /** What the step does, as alasio says it will. */
165
+ export const describeForgetInotify = () => `remove ${SYSCTL_FILE}, which raises the inotify limits at every boot`;
166
+ /** Removes SYSCTL_FILE, as root. */
167
+ export const forgetInotify = Effect.gen(function* () {
168
+ const fs = yield* FileSystem.FileSystem;
169
+ const { root } = yield* Machine;
170
+ yield* fs.remove(under(root, SYSCTL_FILE), { force: true });
171
+ yield* Effect.logInfo(`removed ${SYSCTL_FILE}`);
172
+ });
173
+ //# sourceMappingURL=machine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine.js","sourceRoot":"","sources":["../../../../src/cluster/machine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,392 @@
1
+ /**
2
+ * This machine made a node of k3s, as the cluster alasio makes on it outside Docker is
3
+ * (./host.ts): k3s installed by its own install script, as the systemd service `k3s`, from
4
+ * the binary cluster/node/pins.json pins, with gVisor beside it, containerd's runtime
5
+ * `runsc`, and set in /etc/rancher/k3s/config.yaml. The node image (cluster/node) is
6
+ * built from the same pins, and k3s reads the same containerd template in it, so a node
7
+ * in Docker and one on a machine run the same k3s and gVisor alike.
8
+ *
9
+ * Every download is checked against its pin as the operator downloads it, and again as
10
+ * root before it is installed. What alasio installed, and the digest of the files that
11
+ * configure the node, are in /etc/rancher/k3s/alasio.json, which everyone reads, so a
12
+ * command not run as root knows what changes and asks root for that alone; and k3s's own
13
+ * uninstall script, which removes /etc/rancher/k3s, removes it too.
14
+ *
15
+ * The steps here are each one's own work as root (./root.ts), the same for any machine
16
+ * made a node: a server here, which NodeConfig's role says, as an agent of another
17
+ * machine's server would.
18
+ */
19
+ import { createHash, randomUUID } from "node:crypto";
20
+ import { dirname } from "node:path";
21
+ import { fileURLToPath } from "node:url";
22
+ import { zstdDecompressSync } from "node:zlib";
23
+ import { Duration, Effect, FileSystem, Option, Schedule, Schema } from "effect";
24
+ import pins from "../../../cluster/node/pins.json" with { type: "json" };
25
+ import { Registries } from "../config.js";
26
+ import { clusterKubeconfig, KUBELET_ARGS, NotYet, registriesYaml } from "./k3s.js";
27
+ import { Machine, RootSystem, under } from "./machine.js";
28
+ import { tarEntries } from "./tar.js";
29
+ /** This version's pins, cluster/node/pins.json's. */
30
+ export const NODE_PINS = pins;
31
+ /** Where what `pins` pins is downloaded from: k3s's binary and install script from its repository, gVisor's release from Google's. */
32
+ export const downloads = ({ k3s, gvisor }) => ({
33
+ k3s: { url: `https://github.com/k3s-io/k3s/releases/download/${encodeURIComponent(k3s.version)}/k3s`, algorithm: "sha256", digest: k3s.sha256 },
34
+ installScript: { url: `https://raw.githubusercontent.com/k3s-io/k3s/${k3s.installScript.commit}/install.sh`, algorithm: "sha256", digest: k3s.installScript.sha256 },
35
+ gvisor: { url: `https://storage.googleapis.com/gvisor/releases/release/${gvisor.release}/x86_64/gvisor.tar.zstd`, algorithm: "sha512", digest: gvisor.sha512 },
36
+ });
37
+ const BIN = "/usr/local/bin";
38
+ const K3S_ETC = "/etc/rancher/k3s";
39
+ const CONFIG_YAML = `${K3S_ETC}/config.yaml`;
40
+ const REGISTRIES_YAML = `${K3S_ETC}/registries.yaml`;
41
+ /** What alasio installed, and the digest of the files that configure the node. */
42
+ const STAMP = `${K3S_ETC}/alasio.json`;
43
+ /** The kubeconfig k3s writes, root's alone. */
44
+ const K3S_KUBECONFIG = `${K3S_ETC}/k3s.yaml`;
45
+ const CONTAINERD = "/var/lib/rancher/k3s/agent/etc/containerd";
46
+ /** runsc's options, which the containerd template names where systemd runs the machine. */
47
+ export const RUNSC_TOML = `${CONTAINERD}/runsc.toml`;
48
+ /** The systemd service k3s's install script makes. */
49
+ export const SERVICE = "k3s";
50
+ const SERVICE_FILE = `/etc/systemd/system/${SERVICE}.service`;
51
+ /** Where k3s keeps the password its node registers with. */
52
+ const NODE_PASSWORD = "/etc/rancher/node";
53
+ const KILLALL = `${BIN}/k3s-killall.sh`;
54
+ const UNINSTALL = `${BIN}/k3s-uninstall.sh`;
55
+ /** The networks of the cluster's pods and Services, as k3s is set with them: k3s's own. */
56
+ const CLUSTER_CIDR = "10.42.0.0/16";
57
+ const SERVICE_CIDR = "10.43.0.0/16";
58
+ /** What a firewall must let in to the machine from the cluster: its pods and its Services, as k3s's requirements say. */
59
+ export const CLUSTER_NETWORKS = [CLUSTER_CIDR, SERVICE_CIDR];
60
+ /** The directories JuiceFS's CSI driver keeps on the node, its mounts in them, which nothing of k3s's removes. */
61
+ const JUICEFS = ["/var/lib/juicefs", "/run/juicefs-csi"];
62
+ /** What alasio installs of gVisor's release, in BIN: runsc and its shim, and the binaries runsc runs beside it. */
63
+ const GVISOR = ["runsc", "containerd-shim-runsc-v1", "gvisor-bin"];
64
+ /** The containerd template, cluster/node's, as this package has it. */
65
+ const TEMPLATE_SOURCE = new URL("../../../cluster/node/config-v3.toml.tmpl", import.meta.url);
66
+ /** How a node is made: a server, its volumes in `storagePath`, pulling through `registries`. */
67
+ export const NodeConfig = Schema.Struct({
68
+ role: Schema.Literal("server"),
69
+ storagePath: Schema.String,
70
+ registries: Schema.optionalKey(Registries),
71
+ });
72
+ /** The containerd template, which registers gVisor as the runtime `runsc`. */
73
+ export const containerdTemplate = Effect.flatMap(FileSystem.FileSystem, (fs) => fs.readFileString(fileURLToPath(TEMPLATE_SOURCE)));
74
+ /**
75
+ * The files that make k3s and its containerd a node of `config`, by their paths, with the
76
+ * containerd template `template`: k3s's config.yaml, written as JSON, which YAML reads as
77
+ * it is, the registries, the template, and runsc's options. Pure, for tests.
78
+ */
79
+ export function nodeFiles(config, template) {
80
+ const k3s = {
81
+ "disable": ["traefik"],
82
+ "cluster-cidr": CLUSTER_CIDR,
83
+ "service-cidr": SERVICE_CIDR,
84
+ "default-local-storage-path": config.storagePath,
85
+ "kubelet-arg": KUBELET_ARGS,
86
+ };
87
+ return new Map([
88
+ [CONFIG_YAML, `# k3s as alasio's cluster runs it: alasio up writes this file.\n${JSON.stringify(k3s)}\n`],
89
+ ...(config.registries ? [[REGISTRIES_YAML, `${registriesYaml(config.registries)}\n`]] : []),
90
+ [`${CONTAINERD}/config-v3.toml.tmpl`, template],
91
+ [RUNSC_TOML, `# runsc's options where systemd runs the machine: its sandboxes' cgroups placed through systemd.\n[runsc_config]\n systemd-cgroup = "true"\n`],
92
+ ]);
93
+ }
94
+ /** A digest of `files` that two sets of files share only when they are the same. */
95
+ export const filesDigest = (files) => createHash("sha256").update(JSON.stringify([...files])).digest("hex");
96
+ /** A firewall alasio opens the cluster's networks in, where it is active. */
97
+ export const Firewall = Schema.Literals(["ufw", "firewalld"]);
98
+ /**
99
+ * What alasio installed on this machine, as STAMP records it: k3s's version, gVisor's
100
+ * release, the digest of the files that configure the node, and the firewall it opened
101
+ * the cluster's networks in, with those it added a rule for itself, which are all it
102
+ * removes.
103
+ */
104
+ export const NodeStamp = Schema.Struct({
105
+ k3s: Schema.optionalKey(Schema.String),
106
+ gvisor: Schema.optionalKey(Schema.String),
107
+ config: Schema.optionalKey(Schema.String),
108
+ firewall: Schema.optionalKey(Schema.Struct({ tool: Firewall, networks: Schema.Array(Schema.String), added: Schema.Array(Schema.String) })),
109
+ });
110
+ /** What alasio installed, or null when STAMP is not there: alasio installed nothing, or k3s's uninstall script removed it. One that cannot be read records nothing. */
111
+ export const readStamp = Effect.gen(function* () {
112
+ const fs = yield* FileSystem.FileSystem;
113
+ const { root } = yield* Machine;
114
+ const path = under(root, STAMP);
115
+ if (!(yield* fs.exists(path)))
116
+ return null;
117
+ const text = yield* fs.readFileString(path);
118
+ return Option.getOrElse(Schema.decodeUnknownOption(Schema.fromJsonString(NodeStamp))(text), () => ({}));
119
+ });
120
+ /** STAMP with `changes`, readable by everyone. */
121
+ const recordStamp = Effect.fnUntraced(function* (changes) {
122
+ const fs = yield* FileSystem.FileSystem;
123
+ const { root } = yield* Machine;
124
+ yield* fs.makeDirectory(under(root, K3S_ETC), { recursive: true });
125
+ yield* writeFile(under(root, STAMP), JSON.stringify({ ...(yield* readStamp), ...changes }), 0o644);
126
+ });
127
+ /** A file downloaded, where it is, and what it is checked against. */
128
+ export const Artifact = Schema.Struct({
129
+ path: Schema.String,
130
+ url: Schema.String,
131
+ algorithm: Schema.Literals(["sha256", "sha512"]),
132
+ digest: Schema.String,
133
+ });
134
+ /** A file is not what its pin says. */
135
+ export class ChecksumMismatch extends Schema.TaggedError()("ChecksumMismatch", {
136
+ url: Schema.String,
137
+ algorithm: Schema.String,
138
+ expected: Schema.String,
139
+ actual: Schema.String,
140
+ }) {
141
+ get message() {
142
+ return `${this.url} is not what alasio pins: its ${this.algorithm} is ${this.actual}, not ${this.expected}`;
143
+ }
144
+ }
145
+ /** `content`, which must be `download`'s, by its digest. */
146
+ export const checked = (download, content) => {
147
+ const actual = createHash(download.algorithm).update(content).digest("hex");
148
+ return actual === download.digest ? Effect.succeed(content) : Effect.fail(new ChecksumMismatch({ ...download, expected: download.digest, actual }));
149
+ };
150
+ /** The content of `artifact`, checked against its digest as it is read. */
151
+ const verified = (artifact) => Effect.flatMap(FileSystem.FileSystem, (fs) => Effect.flatMap(fs.readFile(artifact.path), (content) => checked(artifact, content)));
152
+ /** Writes `content` to `path` whole, beside it, then moves it over it, as a running executable cannot be written to. */
153
+ const writeFile = Effect.fnUntraced(function* (path, content, mode) {
154
+ const fs = yield* FileSystem.FileSystem;
155
+ yield* fs.makeDirectory(dirname(path), { recursive: true });
156
+ const written = `${path}.${randomUUID()}`;
157
+ if (typeof content === "string")
158
+ yield* fs.writeFileString(written, content, { flag: "wx", mode });
159
+ else
160
+ yield* fs.writeFile(written, content, { flag: "wx", mode });
161
+ yield* fs.chmod(written, mode);
162
+ yield* fs.rename(written, path);
163
+ });
164
+ /** The step that lets `networks`, the cluster's, in to the machine through `firewall`, which is active. */
165
+ export const OpenFirewall = Schema.TaggedStruct("OpenFirewall", { firewall: Firewall, networks: Schema.Array(Schema.String) });
166
+ /** The step that writes the files that configure k3s and its containerd as a node of `config`. */
167
+ export const ConfigureNode = Schema.TaggedStruct("ConfigureNode", { config: NodeConfig });
168
+ /** The step that installs gVisor's release, from its archive, in place of `previous`. */
169
+ export const InstallGvisor = Schema.TaggedStruct("InstallGvisor", { release: Schema.String, previous: Schema.optionalKey(Schema.String), archive: Artifact });
170
+ /** The step that installs k3s's binary, with its install script, which makes its service, enables it, and starts it anew. */
171
+ export const InstallK3s = Schema.TaggedStruct("InstallK3s", {
172
+ version: Schema.String,
173
+ previous: Schema.optionalKey(Schema.String),
174
+ role: Schema.Literal("server"),
175
+ binary: Artifact,
176
+ script: Artifact,
177
+ });
178
+ /** The step that starts k3s's service, enabling it, or restarts it. */
179
+ export const StartK3s = Schema.TaggedStruct("StartK3s", { restart: Schema.Boolean });
180
+ /** The step that stops k3s's service, disabling it, and stops its pods. */
181
+ export const StopK3s = Schema.TaggedStruct("StopK3s", {});
182
+ /** The step that removes k3s, with its uninstall script, gVisor, and the firewall's rules for the cluster's networks alasio added, by STAMP's `firewall`. */
183
+ export const RemoveNode = Schema.TaggedStruct("RemoveNode", { firewall: Schema.optionalKey(Schema.Struct({ tool: Firewall, added: Schema.Array(Schema.String) })) });
184
+ /** The step that removes the directory of the node's volumes. */
185
+ export const RemoveStorage = Schema.TaggedStruct("RemoveStorage", { path: Schema.String });
186
+ /** The step that reads k3s's kubeconfig, after restarting k3s, which renews its certificates, when `renew`. */
187
+ export const ReadKubeconfig = Schema.TaggedStruct("ReadKubeconfig", { renew: Schema.Boolean });
188
+ export const NodeStep = Schema.Union([OpenFirewall, ConfigureNode, InstallGvisor, InstallK3s, StartK3s, StopK3s, RemoveNode, RemoveStorage, ReadKubeconfig]);
189
+ /** What `step` does, as alasio says it will. */
190
+ export function describeNodeStep(step) {
191
+ const replacing = (previous) => (previous ? `, in place of ${previous},` : "");
192
+ switch (step._tag) {
193
+ case "OpenFirewall":
194
+ return `let the cluster's pods and Services, ${step.networks.join(" and ")}, in to this machine through ${step.firewall}, as k3s needs; ` +
195
+ "nothing else is opened, k3s's API server's port 6443 staying closed to the rest";
196
+ case "ConfigureNode":
197
+ return `write k3s's configuration in ${K3S_ETC}, and its containerd's, with gVisor as the runtime runsc, in ${CONTAINERD}`;
198
+ case "InstallGvisor":
199
+ return `install gVisor ${step.release}${replacing(step.previous)} in ${BIN}: ${GVISOR.join(", ")}`;
200
+ case "InstallK3s":
201
+ return `install k3s ${step.version}${replacing(step.previous)} in ${BIN}, with its own install script, as the systemd service ${SERVICE}, enabled and started anew`;
202
+ case "StartK3s":
203
+ return step.restart ? `restart the service ${SERVICE}, with its new configuration` : `enable and start the service ${SERVICE}`;
204
+ case "StopK3s":
205
+ return `stop and disable the service ${SERVICE}, and stop the cluster's pods, gVisor's and those k3s-killall.sh stops`;
206
+ case "RemoveNode":
207
+ return `stop the cluster's gVisor pods, ` +
208
+ (step.firewall && step.firewall.added.length > 0 ? `remove the rules alasio added to ${step.firewall.tool} for ${step.firewall.added.join(" and ")}, ` : "") +
209
+ `uninstall k3s with k3s-uninstall.sh, which removes its service, ${K3S_ETC} and its data, ` +
210
+ `and remove what it leaves, its node's password in ${NODE_PASSWORD}, gVisor from ${BIN}, and JuiceFS's mounts and directories, ` +
211
+ JUICEFS.join(" and ");
212
+ case "RemoveStorage":
213
+ return `remove ${step.path}, the cluster's volumes`;
214
+ case "ReadKubeconfig":
215
+ return `${step.renew ? `restart the service ${SERVICE}, which renews its certificates, and ` : ""}read its kubeconfig, ${K3S_KUBECONFIG}, for alasio to reach it`;
216
+ }
217
+ }
218
+ /** gVisor's executables, as this machine names them, which its processes run. */
219
+ const gvisorExecutables = Effect.gen(function* () {
220
+ const fs = yield* FileSystem.FileSystem;
221
+ const { root } = yield* Machine;
222
+ const bin = under(root, `${BIN}/gvisor-bin`);
223
+ const beside = (yield* fs.exists(bin)) ? (yield* fs.readDirectory(bin)).map((name) => `${BIN}/gvisor-bin/${name}`) : [];
224
+ return [`${BIN}/runsc`, `${BIN}/containerd-shim-runsc-v1`, ...beside];
225
+ });
226
+ /** Kills gVisor's processes, the cluster's sandboxes and their shims, which k3s's own scripts do not stop. */
227
+ const killGvisor = Effect.gen(function* () {
228
+ const killed = yield* (yield* RootSystem).kill(yield* gvisorExecutables);
229
+ if (killed > 0)
230
+ yield* Effect.logInfo(`stopped ${killed} of gVisor's processes`);
231
+ });
232
+ /**
233
+ * Unmounts what is mounted in JUICEFS, at once, as their FUSE clients are gone with the
234
+ * cluster's pods, then removes them. A mount point's spaces and the like are octal
235
+ * escapes in /proc/self/mounts.
236
+ */
237
+ const removeJuicefs = Effect.gen(function* () {
238
+ const fs = yield* FileSystem.FileSystem;
239
+ const { root } = yield* Machine;
240
+ const table = under(root, "/proc/self/mounts");
241
+ const mounts = (yield* fs.exists(table)) ? (yield* fs.readFileString(table)).split("\n").map((line) => (line.split(" ")[1] ?? "").replace(/\\(\d{3})/gu, (_, code) => String.fromCharCode(Number.parseInt(code, 8)))) : [];
242
+ const inside = mounts.filter((point) => JUICEFS.some((directory) => point === directory || point.startsWith(`${directory}/`))).toSorted().toReversed();
243
+ for (const point of inside)
244
+ yield* (yield* RootSystem).run("umount", ["--lazy", point]);
245
+ for (const directory of JUICEFS)
246
+ yield* fs.remove(under(root, directory), { recursive: true, force: true });
247
+ });
248
+ /** What a firewall alasio opens the cluster's networks in is asked, and told, as root. */
249
+ const FIREWALLS = {
250
+ // ufw's rules hold as they are added, and `ufw show added` says each as `ufw allow from NETWORK`.
251
+ ufw: {
252
+ lets: (network) => Effect.flatMap(RootSystem, (system) => system.ask("ufw", ["show", "added"])).pipe(Effect.map(({ stdout }) => stdout.split("\n").some((line) => line.trim() === `ufw allow from ${network}`))),
253
+ allow: (network) => Effect.flatMap(RootSystem, (system) => system.run("ufw", ["allow", "from", network, "to", "any"])),
254
+ remove: (network) => Effect.flatMap(RootSystem, (system) => system.run("ufw", ["delete", "allow", "from", network, "to", "any"])),
255
+ apply: Effect.void,
256
+ },
257
+ // firewalld's trusted zone lets its sources in, its permanent rules holding once reloaded.
258
+ firewalld: {
259
+ lets: (network) => Effect.flatMap(RootSystem, (system) => system.ask("firewall-cmd", ["--permanent", "--zone=trusted", `--query-source=${network}`])).pipe(Effect.map(({ exitCode }) => exitCode === 0)),
260
+ allow: (network) => Effect.flatMap(RootSystem, (system) => system.run("firewall-cmd", ["--permanent", "--zone=trusted", `--add-source=${network}`])),
261
+ remove: (network) => Effect.flatMap(RootSystem, (system) => system.run("firewall-cmd", ["--permanent", "--zone=trusted", `--remove-source=${network}`])),
262
+ apply: Effect.flatMap(RootSystem, (system) => system.run("firewall-cmd", ["--reload"])),
263
+ },
264
+ };
265
+ /** Removes the rules for `added` from `tool`, those alasio added, and no other. */
266
+ const closeFirewall = ({ tool, added }) => Effect.gen(function* () {
267
+ if (added.length === 0)
268
+ return;
269
+ for (const network of added)
270
+ yield* FIREWALLS[tool].remove(network);
271
+ yield* FIREWALLS[tool].apply;
272
+ yield* Effect.logInfo(`removed ${tool}'s rules for ${added.join(" and ")}`);
273
+ });
274
+ /** Whether k3s's service is installed. */
275
+ const serviceInstalled = Effect.gen(function* () {
276
+ const fs = yield* FileSystem.FileSystem;
277
+ const { root } = yield* Machine;
278
+ return yield* fs.exists(under(root, SERVICE_FILE));
279
+ });
280
+ const systemctl = (...args) => Effect.flatMap(RootSystem, (system) => system.run("systemctl", args));
281
+ /** The kubeconfig k3s wrote, once it is one. */
282
+ const kubeconfigWritten = Effect.gen(function* () {
283
+ const fs = yield* FileSystem.FileSystem;
284
+ const { root } = yield* Machine;
285
+ const path = under(root, K3S_KUBECONFIG);
286
+ const content = (yield* fs.exists(path)) ? yield* fs.readFileString(path) : "";
287
+ if (clusterKubeconfig(content, SERVICE) === null)
288
+ return yield* new NotYet({ message: `${K3S_KUBECONFIG} is not yet a kubeconfig with a cluster and a user` });
289
+ return content;
290
+ });
291
+ /** Does `step`, as root: k3s's kubeconfig, when it reads it. */
292
+ export const performNodeStep = (step) => Effect.gen(function* () {
293
+ const fs = yield* FileSystem.FileSystem;
294
+ const { root } = yield* Machine;
295
+ const system = yield* RootSystem;
296
+ switch (step._tag) {
297
+ case "OpenFirewall": {
298
+ const firewall = FIREWALLS[step.firewall];
299
+ const previous = (yield* readStamp)?.firewall;
300
+ const added = previous?.tool === step.firewall ? [...previous.added] : [];
301
+ for (const network of step.networks) {
302
+ if (yield* firewall.lets(network))
303
+ continue;
304
+ yield* firewall.allow(network);
305
+ added.push(network);
306
+ }
307
+ yield* firewall.apply;
308
+ yield* recordStamp({ firewall: { tool: step.firewall, networks: step.networks, added } });
309
+ return yield* Effect.logInfo(`${step.firewall} lets ${step.networks.join(" and ")} in`);
310
+ }
311
+ case "ConfigureNode": {
312
+ const files = nodeFiles(step.config, yield* containerdTemplate);
313
+ for (const [path, content] of files)
314
+ yield* writeFile(under(root, path), content, path.startsWith(K3S_ETC) ? 0o600 : 0o644);
315
+ if (!files.has(REGISTRIES_YAML))
316
+ yield* fs.remove(under(root, REGISTRIES_YAML), { force: true });
317
+ yield* recordStamp({ config: filesDigest(files) });
318
+ return yield* Effect.logInfo(`wrote ${[...files.keys()].join(", ")}`);
319
+ }
320
+ case "InstallGvisor": {
321
+ const entries = tarEntries(Buffer.from(zstdDecompressSync(yield* verified(step.archive))));
322
+ for (const entry of entries.filter(({ name }) => GVISOR.some((installed) => name === installed || name.startsWith(`${installed}/`)))) {
323
+ const path = under(root, `${BIN}/${entry.name.replace(/\/$/u, "")}`);
324
+ if (entry.type === "directory")
325
+ yield* fs.makeDirectory(path, { recursive: true, mode: entry.mode });
326
+ else
327
+ yield* writeFile(path, entry.content, entry.mode);
328
+ }
329
+ yield* recordStamp({ gvisor: step.release });
330
+ return yield* Effect.logInfo(`installed gVisor ${step.release}`);
331
+ }
332
+ case "InstallK3s": {
333
+ yield* writeFile(under(root, `${BIN}/k3s`), yield* verified(step.binary), 0o755);
334
+ const script = yield* verified(step.script);
335
+ yield* Effect.scoped(Effect.gen(function* () {
336
+ const directory = yield* fs.makeTempDirectoryScoped({ prefix: "alasio-k3s-" });
337
+ yield* fs.writeFile(`${directory}/install.sh`, script, { mode: 0o700 });
338
+ // Its binary is there already, checked; the script makes and starts its service, anew though nothing of it changed.
339
+ yield* system.run("sh", [`${directory}/install.sh`], {
340
+ INSTALL_K3S_SKIP_DOWNLOAD: "true",
341
+ INSTALL_K3S_SKIP_SELINUX_RPM: "true",
342
+ INSTALL_K3S_SELINUX_WARN: "true",
343
+ INSTALL_K3S_FORCE_RESTART: "true",
344
+ INSTALL_K3S_EXEC: step.role,
345
+ });
346
+ }));
347
+ yield* recordStamp({ k3s: step.version });
348
+ return yield* Effect.logInfo(`installed k3s ${step.version}`);
349
+ }
350
+ case "StartK3s":
351
+ return yield* (step.restart ? systemctl("restart", SERVICE) : systemctl("enable", "--now", SERVICE));
352
+ case "StopK3s": {
353
+ yield* systemctl("disable", "--now", SERVICE);
354
+ yield* killGvisor;
355
+ if (yield* fs.exists(under(root, KILLALL)))
356
+ yield* system.run(KILLALL, []);
357
+ return;
358
+ }
359
+ case "RemoveNode": {
360
+ // k3s first, which would start the pods gVisor's end again.
361
+ if (yield* serviceInstalled)
362
+ yield* systemctl("stop", SERVICE);
363
+ yield* killGvisor;
364
+ if (step.firewall)
365
+ yield* closeFirewall(step.firewall);
366
+ if (yield* fs.exists(under(root, UNINSTALL)))
367
+ yield* system.run(UNINSTALL, []);
368
+ yield* removeJuicefs;
369
+ // alasio's own, and the node's password, which k3s keeps and its uninstall script leaves.
370
+ for (const path of [...GVISOR.map((name) => `${BIN}/${name}`), CONFIG_YAML, REGISTRIES_YAML, STAMP, CONTAINERD, NODE_PASSWORD]) {
371
+ yield* fs.remove(under(root, path), { recursive: true, force: true });
372
+ }
373
+ // What k3s's uninstall script leaves of the directories it made, when it is empty.
374
+ for (const path of [K3S_ETC, "/etc/rancher", "/var/lib/rancher/k3s", "/var/lib/rancher"]) {
375
+ const at = under(root, path);
376
+ if ((yield* fs.exists(at)) && (yield* fs.readDirectory(at)).length === 0)
377
+ yield* fs.remove(at, { recursive: true });
378
+ }
379
+ return yield* Effect.logInfo("removed k3s and gVisor");
380
+ }
381
+ case "RemoveStorage":
382
+ // A path of the operator's, which they made, as the rest of their own paths.
383
+ yield* fs.remove(step.path, { recursive: true, force: true });
384
+ return yield* Effect.logInfo(`removed ${step.path}`);
385
+ case "ReadKubeconfig": {
386
+ if (step.renew)
387
+ yield* systemctl("restart", SERVICE);
388
+ return yield* kubeconfigWritten.pipe(Effect.retry({ while: (error) => error._tag === "NotYet", schedule: Schedule.max([Schedule.spaced("1 second"), Schedule.during(Duration.minutes(5))]) }));
389
+ }
390
+ }
391
+ });
392
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../../../../src/cluster/node.ts"],"names":[],"mappings":"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"}