@gjermundgaraba/clankerbox-sdk 0.15.3 → 0.15.4
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/dist/{client-CtI-rSJQ.mjs → client-pUFgD6Xz.mjs} +1 -1
- package/dist/index.d.mts +23 -1
- package/dist/index.mjs +69 -2
- package/dist/node.mjs +1 -1
- package/package.json +1 -1
|
@@ -129,7 +129,7 @@ const formatId = (host, name) => {
|
|
|
129
129
|
};
|
|
130
130
|
//#endregion
|
|
131
131
|
//#region package.json
|
|
132
|
-
var version$1 = "0.15.
|
|
132
|
+
var version$1 = "0.15.4";
|
|
133
133
|
//#endregion
|
|
134
134
|
//#region src/resources.ts
|
|
135
135
|
/** The resources a host reports: machines, checkpoints and the host itself. */
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { A as Invalid, C as ClankerboxError, D as HostError, E as ErrorTag, M as Precondition, N as Unavailable, O as HostErrorTag, P as hostErrors, S as Capacity, T as ConflictKind, _ as Setup, b as release, c as ActionRecord, d as Host, f as Limit, g as Runtime, h as Profile, i as Interface, j as NotFound, k as Internal, l as Checkpoint, m as MachineSpec, n as CreateOptions, o as client_d_exports, p as Machine, s as ActionName, u as CreateRequest, v as SshEndpoint, w as Conflict, x as version, y as SshLogin } from "./client-Cn1bj4It.mjs";
|
|
2
2
|
import * as Action from "@gjermundgaraba/effect-actions/Action";
|
|
3
3
|
import * as ActionHttp from "@gjermundgaraba/effect-actions/ActionHttp";
|
|
4
|
-
import { Duration, Effect, FileSystem, Path, PlatformError, Schema } from "effect";
|
|
4
|
+
import { Duration, Effect, FileSystem, Path, PlatformError, Schema, Scope } from "effect";
|
|
5
5
|
//#region src/api.d.ts
|
|
6
6
|
/**
|
|
7
7
|
* How long a client waits for a read's reply from one host, unless it sets its own. A host
|
|
@@ -381,6 +381,28 @@ export declare const packRecipe: (directory: string) => Effect.Effect<string, In
|
|
|
381
381
|
/** Reads a setup: a script file's text, or a recipe directory packed into one script. */
|
|
382
382
|
export declare const readSetup: (path: string) => Effect.Effect<string, Invalid, FileSystem.FileSystem>;
|
|
383
383
|
//#endregion
|
|
384
|
+
//#region src/ssh.d.ts
|
|
385
|
+
/** What ssh needs of a machine: where it is reached, as whom, and the host key to pin. */
|
|
386
|
+
export interface SshTarget {
|
|
387
|
+
readonly id: string;
|
|
388
|
+
readonly login: SshLogin;
|
|
389
|
+
readonly hostKey: string;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* The machine's SSH target, or what it lacks: an endpoint, which only a running machine has, or
|
|
393
|
+
* a host key, which preparation records.
|
|
394
|
+
*/
|
|
395
|
+
export declare const sshTarget: (machine: Machine) => SshTarget | {
|
|
396
|
+
readonly lacks: "SSH endpoint" | "SSH host key on record";
|
|
397
|
+
};
|
|
398
|
+
/**
|
|
399
|
+
* Writes a one-line known-hosts file pinning the target's host key, and returns the arguments
|
|
400
|
+
* that run ssh against it with strict host key checking, as `user`. The file lasts as long as
|
|
401
|
+
* the scope, which must outlast the ssh it is for. Ports change on fork and restore, and on
|
|
402
|
+
* boat at every start, so a target is read anew for each ssh.
|
|
403
|
+
*/
|
|
404
|
+
export declare const pinnedSsh: (target: SshTarget, user: string, extra: ReadonlyArray<string>) => Effect.Effect<Array<string>, PlatformError.PlatformError, FileSystem.FileSystem | Path.Path | Scope.Scope>;
|
|
405
|
+
//#endregion
|
|
384
406
|
//#region src/text.d.ts
|
|
385
407
|
/**
|
|
386
408
|
* A RAM size, exactly, as a size flag takes one: GiB when it is whole or half GiB, `32G` or
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
-
import { A as parseName, B as Unavailable, C as release, D as Name, E as Id, F as HostErrorTag, I as Internal, L as Invalid, M as Conflict, N as ConflictKind, O as formatId, P as ErrorTag, R as NotFound, S as SshLogin, T as HostId, V as hostErrors, _ as MachineSpec, a as describeIssues, b as Setup, c as readTimeout, d as ActionRecord, f as Checkpoint, g as Machine, h as Limit, i as describeFileError, j as Capacity, k as parseId, l as versionHeader, m as Host, n as client_exports, o as formatMib, p as CreateRequest, s as Http, u as ActionName, v as Profile, w as version, x as SshEndpoint, y as Runtime, z as Precondition } from "./client-
|
|
2
|
+
import { A as parseName, B as Unavailable, C as release, D as Name, E as Id, F as HostErrorTag, I as Internal, L as Invalid, M as Conflict, N as ConflictKind, O as formatId, P as ErrorTag, R as NotFound, S as SshLogin, T as HostId, V as hostErrors, _ as MachineSpec, a as describeIssues, b as Setup, c as readTimeout, d as ActionRecord, f as Checkpoint, g as Machine, h as Limit, i as describeFileError, j as Capacity, k as parseId, l as versionHeader, m as Host, n as client_exports, o as formatMib, p as CreateRequest, s as Http, u as ActionName, v as Profile, w as version, x as SshEndpoint, y as Runtime, z as Precondition } from "./client-pUFgD6Xz.mjs";
|
|
3
3
|
import { Effect, FileSystem, Option, Path, Predicate, Schema } from "effect";
|
|
4
4
|
//#region src/prebuild.ts
|
|
5
5
|
/**
|
|
@@ -218,4 +218,71 @@ const readSetup = (path) => Effect.gen(function* () {
|
|
|
218
218
|
return yield* fs.readFileString(path);
|
|
219
219
|
}).pipe(Effect.catchTag("PlatformError", (error) => Effect.fail(new Invalid({ message: `couldn't read setup ${path}: ${describeFileError(error)}` }))));
|
|
220
220
|
//#endregion
|
|
221
|
-
|
|
221
|
+
//#region src/ssh.ts
|
|
222
|
+
/**
|
|
223
|
+
* The system `ssh`'s arguments for a machine, pinned to its host key: what `clankerbox ssh` runs,
|
|
224
|
+
* and what anything else that reaches a guest through port 22 does, such as a port forward.
|
|
225
|
+
*/
|
|
226
|
+
/**
|
|
227
|
+
* The machine's SSH target, or what it lacks: an endpoint, which only a running machine has, or
|
|
228
|
+
* a host key, which preparation records.
|
|
229
|
+
*/
|
|
230
|
+
const sshTarget = (machine) => {
|
|
231
|
+
const { id, ssh: login, hostKey } = machine;
|
|
232
|
+
if (login === void 0) return { lacks: "SSH endpoint" };
|
|
233
|
+
return hostKey === void 0 ? { lacks: "SSH host key on record" } : {
|
|
234
|
+
id,
|
|
235
|
+
login,
|
|
236
|
+
hostKey
|
|
237
|
+
};
|
|
238
|
+
};
|
|
239
|
+
/**
|
|
240
|
+
* The known-hosts line pinning the machine's host key under its ID: ssh looks the key up by
|
|
241
|
+
* `HostKeyAlias`, so the line doesn't depend on the endpoint, which changes.
|
|
242
|
+
*/
|
|
243
|
+
const knownHostsLine = (id, hostKey) => {
|
|
244
|
+
const [type = "", key = ""] = hostKey.trim().split(/\s+/u);
|
|
245
|
+
return `${id} ${type} ${key}\n`;
|
|
246
|
+
};
|
|
247
|
+
/**
|
|
248
|
+
* ssh's arguments. OpenSSH keeps the first user it is given, so the leading `-l` decides it:
|
|
249
|
+
* one in the caller's arguments or in an ssh config doesn't apply. The destination is the
|
|
250
|
+
* machine's ID, so a `Host <pattern>` block in the user's ssh config can set keys and options
|
|
251
|
+
* per machine; the endpoint and the pinned host key come from command-line options, which no
|
|
252
|
+
* config overrides. The caller's arguments go after the destination, where OpenSSH still reads
|
|
253
|
+
* options (`-L …`) before a remote command.
|
|
254
|
+
*/
|
|
255
|
+
const sshArguments = (target, user, knownHosts, extra) => [
|
|
256
|
+
"-l",
|
|
257
|
+
user,
|
|
258
|
+
"-o",
|
|
259
|
+
`HostName=${target.login.host}`,
|
|
260
|
+
"-o",
|
|
261
|
+
`Port=${target.login.port}`,
|
|
262
|
+
"-o",
|
|
263
|
+
`HostKeyAlias=${target.id}`,
|
|
264
|
+
"-o",
|
|
265
|
+
`UserKnownHostsFile=${knownHosts}`,
|
|
266
|
+
"-o",
|
|
267
|
+
"GlobalKnownHostsFile=/dev/null",
|
|
268
|
+
"-o",
|
|
269
|
+
"StrictHostKeyChecking=yes",
|
|
270
|
+
target.id,
|
|
271
|
+
...extra
|
|
272
|
+
];
|
|
273
|
+
/**
|
|
274
|
+
* Writes a one-line known-hosts file pinning the target's host key, and returns the arguments
|
|
275
|
+
* that run ssh against it with strict host key checking, as `user`. The file lasts as long as
|
|
276
|
+
* the scope, which must outlast the ssh it is for. Ports change on fork and restore, and on
|
|
277
|
+
* boat at every start, so a target is read anew for each ssh.
|
|
278
|
+
*/
|
|
279
|
+
const pinnedSsh = (target, user, extra) => Effect.gen(function* () {
|
|
280
|
+
const fs = yield* FileSystem.FileSystem;
|
|
281
|
+
const path = yield* Path.Path;
|
|
282
|
+
const directory = yield* fs.makeTempDirectoryScoped({ prefix: "clankerbox-ssh-" });
|
|
283
|
+
const knownHosts = path.join(directory, "known_hosts");
|
|
284
|
+
yield* fs.writeFileString(knownHosts, knownHostsLine(target.id, target.hostKey));
|
|
285
|
+
return sshArguments(target, user, knownHosts, extra);
|
|
286
|
+
});
|
|
287
|
+
//#endregion
|
|
288
|
+
export { ActionName, ActionRecord, Capacity, Checkpoint, client_exports as Client, Conflict, ConflictKind, CreateRequest, ErrorTag, Host, HostErrorTag, HostId, Http, Id, Internal, Invalid, Limit, Machine, MachineSpec, Name, NotFound, prebuild_exports as Prebuild, Precondition, Profile, Runtime, Setup, SshEndpoint, SshLogin, Unavailable, describeFileError, describeIssues, formatId, formatMib, hostErrors, loadProfile, packRecipe, parseId, parseName, pinnedSsh, readSetup, readTimeout, release, sshTarget, version, versionHeader };
|
package/dist/node.mjs
CHANGED