@serve.zone/pallet-bundle 35.4.2 → 36.0.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/dist_ts_bundle/classes.controlprocess.d.ts +9 -3
- package/dist_ts_bundle/classes.controlprocess.js +12 -4
- package/dist_ts_bundle/errors.d.ts +3 -1
- package/dist_ts_bundle/errors.js +1 -1
- package/dist_ts_bundle/protocol.d.ts +34 -2
- package/dist_ts_bundle/protocol.js +34 -3
- package/dist_ts_bundle/units.d.ts +38 -2
- package/dist_ts_bundle/units.js +73 -9
- package/package.json +3 -3
- package/readme.md +52 -2
- package/ts_bundle/classes.controlprocess.ts +19 -6
- package/ts_bundle/errors.ts +3 -1
- package/ts_bundle/protocol.ts +37 -2
- package/ts_bundle/readme.md +52 -2
- package/ts_bundle/units.ts +70 -9
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type TPalletControlLifetimeMode, type TPalletControlOneshotMode } from './protocol.js';
|
|
1
|
+
import { type TPalletControlLifetimeMode, type TPalletControlOneshotMode, type TPalletForwardingMode } from './protocol.js';
|
|
2
2
|
/** Why a supervised `pallet-control` process did not complete. */
|
|
3
3
|
export type TPalletControlProcessFailure = 'invalid_input' | 'already_started'
|
|
4
4
|
/** The executable is not the trusted one: unsafe path, other digest, or it could not start. */
|
|
@@ -6,7 +6,9 @@ export type TPalletControlProcessFailure = 'invalid_input' | 'already_started'
|
|
|
6
6
|
/** Pallet refused the `DENO_TLS_CA_STORE` it was started with. */
|
|
7
7
|
| 'invalid_ca_store'
|
|
8
8
|
/** Pallet's packet engine refused the running kernel. */
|
|
9
|
-
| 'unsupported_kernel'
|
|
9
|
+
| 'unsupported_kernel'
|
|
10
|
+
/** The node refused its forwarding mode for a persistent fact of the host (`forwarding_mode_refused`). */
|
|
11
|
+
| 'forwarding_mode_refused' | 'protocol_invalid' | 'shutdown_failed';
|
|
10
12
|
/** The operator's remedy for `unsupported_kernel`, from Pallet's host kernel requirements. */
|
|
11
13
|
export declare const palletUnsupportedKernelRemedy: string;
|
|
12
14
|
export declare class PalletControlProcessError extends Error {
|
|
@@ -17,7 +19,7 @@ export declare class PalletControlProcessError extends Error {
|
|
|
17
19
|
* The failure a `failed` line's reason names, or `undefined` for a reason outside the protocol. A
|
|
18
20
|
* reason whose remedy lies on this host is named apart; every other reason is Pallet's own failure.
|
|
19
21
|
*/
|
|
20
|
-
export declare const palletControlFailure: (reasonArg: unknown) => "unsupported_kernel" | "invalid_ca_store" | "owner_failed" | undefined;
|
|
22
|
+
export declare const palletControlFailure: (reasonArg: unknown) => "unsupported_kernel" | "invalid_ca_store" | "owner_failed" | "forwarding_mode_refused" | undefined;
|
|
21
23
|
export interface IPalletControlProcessOptions {
|
|
22
24
|
/** Trusted installed bundle identity (`IPalletControlBundle.executables.control`), never read from CLI or environment. */
|
|
23
25
|
binaryPath: string;
|
|
@@ -47,6 +49,9 @@ export declare class PalletControlOneshot {
|
|
|
47
49
|
}
|
|
48
50
|
export interface IPalletControlLifetimeOptions extends IPalletControlProcessOptions {
|
|
49
51
|
mode: TPalletControlLifetimeMode;
|
|
52
|
+
/** `runtime-serve` only, and required there: who owns the host's IPv4 forwarding
|
|
53
|
+
* (`TPalletForwardingMode`). The enrollment modes take none. */
|
|
54
|
+
forwardingMode?: TPalletForwardingMode;
|
|
50
55
|
/**
|
|
51
56
|
* How long the child may take to report `ready`. `runtime-serve` defaults to the node's start
|
|
52
57
|
* contract (`palletNodeStartTimeoutSeconds`) and admits up to an hour; the enrollment modes default
|
|
@@ -66,6 +71,7 @@ export interface IPalletControlLifetimeOptions extends IPalletControlProcessOpti
|
|
|
66
71
|
export declare class PalletControlLifetime {
|
|
67
72
|
private readonly options;
|
|
68
73
|
private readonly mode;
|
|
74
|
+
private readonly forwardingMode;
|
|
69
75
|
private used;
|
|
70
76
|
private available;
|
|
71
77
|
constructor(optionsArg: IPalletControlLifetimeOptions);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import { canonicalPath, verifyExecutable } from './paths.js';
|
|
3
3
|
import { PalletControlStderr } from './classes.controlstderr.js';
|
|
4
|
-
import { palletControlLifetimeModes, palletControlLinePrefix, palletControlOneshotModes, } from './protocol.js';
|
|
4
|
+
import { palletControlLifetimeModes, palletControlLinePrefix, palletControlOneshotModes, isPalletForwardingMode, palletForwardingModeArgument, } from './protocol.js';
|
|
5
5
|
import { palletNodeStartTimeoutSeconds } from './units.js';
|
|
6
6
|
/** The operator's remedy for `unsupported_kernel`, from Pallet's host kernel requirements. */
|
|
7
7
|
export const palletUnsupportedKernelRemedy = "Pallet's packet engine refused this host's kernel: boot Linux 6.9 or newer with the nftables filter and NAT " +
|
|
@@ -21,6 +21,7 @@ const failures = new Map([
|
|
|
21
21
|
['invalid_stdin', 'owner_failed'],
|
|
22
22
|
['owner_failed', 'owner_failed'],
|
|
23
23
|
['unsupported_kernel', 'unsupported_kernel'],
|
|
24
|
+
['forwarding_mode_refused', 'forwarding_mode_refused'],
|
|
24
25
|
]);
|
|
25
26
|
/**
|
|
26
27
|
* The failure a `failed` line's reason names, or `undefined` for a reason outside the protocol. A
|
|
@@ -33,7 +34,7 @@ export const palletControlFailure = (reasonArg) => typeof reasonArg === 'string'
|
|
|
33
34
|
* told once when either pipe violates the protocol or its bounds.
|
|
34
35
|
*/
|
|
35
36
|
function spawnControl(optionsArg) {
|
|
36
|
-
const child = plugins.childProcess.spawn(optionsArg.binaryPath, [optionsArg.mode], {
|
|
37
|
+
const child = plugins.childProcess.spawn(optionsArg.binaryPath, [optionsArg.mode, ...(optionsArg.arguments ?? [])], {
|
|
37
38
|
cwd: '/', env: { PATH: '/usr/bin:/bin' }, stdio: [optionsArg.stdin, 'pipe', 'pipe'],
|
|
38
39
|
});
|
|
39
40
|
let exited = false;
|
|
@@ -262,6 +263,7 @@ export class PalletControlOneshot {
|
|
|
262
263
|
export class PalletControlLifetime {
|
|
263
264
|
options;
|
|
264
265
|
mode;
|
|
266
|
+
forwardingMode;
|
|
265
267
|
used = false;
|
|
266
268
|
available = false;
|
|
267
269
|
constructor(optionsArg) {
|
|
@@ -270,11 +272,16 @@ export class PalletControlLifetime {
|
|
|
270
272
|
throw new PalletControlProcessError('invalid_input');
|
|
271
273
|
}
|
|
272
274
|
const runtime = mode === 'runtime-serve';
|
|
275
|
+
const forwardingMode = isPalletForwardingMode(optionsArg.forwardingMode) ? optionsArg.forwardingMode : null;
|
|
276
|
+
if (runtime ? forwardingMode === null : optionsArg.forwardingMode !== undefined) {
|
|
277
|
+
throw new PalletControlProcessError('invalid_input');
|
|
278
|
+
}
|
|
273
279
|
this.mode = mode;
|
|
280
|
+
this.forwardingMode = forwardingMode;
|
|
274
281
|
// The runtime fences what its previous lifetime retained before `ready`, and its stop may join a
|
|
275
282
|
// five-minute native operation, then database cleanup. Its startup limit is the node's contract;
|
|
276
283
|
// an hour covers every per-request deadline of a start at the retained-workload maximum.
|
|
277
|
-
this.options = validated(optionsArg, ['mode'], [
|
|
284
|
+
this.options = validated(optionsArg, ['mode', 'forwardingMode'], [
|
|
278
285
|
['startupTimeoutMs', runtime ? palletNodeStartTimeoutSeconds * 1000 : 15_000, runtime ? 3_600_000 : 60_000],
|
|
279
286
|
['shutdownTimeoutMs', runtime ? 330_000 : 15_000, runtime ? 600_000 : 60_000],
|
|
280
287
|
['terminationGraceMs', 1_000, 60_000],
|
|
@@ -384,6 +391,7 @@ export class PalletControlLifetime {
|
|
|
384
391
|
abort.signal.throwIfAborted();
|
|
385
392
|
child = spawnControl({
|
|
386
393
|
binaryPath: this.options.binaryPath, mode: this.mode, stdin: 'pipe', stderr: this.options.stderr,
|
|
394
|
+
arguments: this.forwardingMode === null ? [] : [palletForwardingModeArgument, this.forwardingMode],
|
|
387
395
|
// The runtime reports for its whole lifetime; only the enrollment owner's output is bounded in total.
|
|
388
396
|
maximumOutputBytes: this.mode === 'runtime-serve' ? null : 1024 * 1024,
|
|
389
397
|
terminationGraceMs: timeouts.terminationGraceMs, onLine: line, onInvalid: () => reject('protocol_invalid'),
|
|
@@ -442,4 +450,4 @@ export class PalletControlLifetime {
|
|
|
442
450
|
return outcome.value;
|
|
443
451
|
}
|
|
444
452
|
}
|
|
445
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5jb250cm9scHJvY2Vzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX2J1bmRsZS9jbGFzc2VzLmNvbnRyb2xwcm9jZXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxhQUFhLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDN0QsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDakUsT0FBTyxFQUNMLDBCQUEwQixFQUFFLHVCQUF1QixFQUFFLHlCQUF5QixHQUUvRSxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFtQjNELDhGQUE4RjtBQUM5RixNQUFNLENBQUMsTUFBTSw2QkFBNkIsR0FDeEMsOEdBQThHO0lBQzlHLDhHQUE4RztJQUM5Ryw2QkFBNkIsQ0FBQztBQUVoQyxNQUFNLE9BQU8seUJBQTBCLFNBQVEsS0FBSztJQUN0QjtJQUE1QixZQUE0QixJQUFrQztRQUM1RCxLQUFLLENBQUMsa0NBQWtDLElBQUksSUFBSSxJQUFJLEtBQUssb0JBQW9CLENBQUMsQ0FBQyxDQUFDLElBQUksNkJBQTZCLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQURsRyxTQUFJLEdBQUosSUFBSSxDQUE4QjtRQUU1RCxJQUFJLENBQUMsSUFBSSxHQUFHLDJCQUEyQixDQUFDO0lBQzFDLENBQUM7Q0FDRjtBQUVELE1BQU0sUUFBUSxHQUFvRixJQUFJLEdBQUcsQ0FBQztJQUN4RyxDQUFDLG1CQUFtQixFQUFFLGNBQWMsQ0FBQztJQUNyQyxDQUFDLGtCQUFrQixFQUFFLGtCQUFrQixDQUFDO0lBQ3hDLENBQUMsZUFBZSxFQUFFLGNBQWMsQ0FBQztJQUNqQyxDQUFDLGNBQWMsRUFBRSxjQUFjLENBQUM7SUFDaEMsQ0FB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
|
|
453
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5jb250cm9scHJvY2Vzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX2J1bmRsZS9jbGFzc2VzLmNvbnRyb2xwcm9jZXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxhQUFhLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDN0QsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDakUsT0FBTyxFQUNMLDBCQUEwQixFQUFFLHVCQUF1QixFQUFFLHlCQUF5QixFQUFFLHNCQUFzQixFQUN0Ryw0QkFBNEIsR0FDN0IsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBcUIzRCw4RkFBOEY7QUFDOUYsTUFBTSxDQUFDLE1BQU0sNkJBQTZCLEdBQ3hDLDhHQUE4RztJQUM5Ryw4R0FBOEc7SUFDOUcsNkJBQTZCLENBQUM7QUFFaEMsTUFBTSxPQUFPLHlCQUEwQixTQUFRLEtBQUs7SUFDdEI7SUFBNUIsWUFBNEIsSUFBa0M7UUFDNUQsS0FBSyxDQUFDLGtDQUFrQyxJQUFJLElBQUksSUFBSSxLQUFLLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxJQUFJLDZCQUE2QixFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFEbEcsU0FBSSxHQUFKLElBQUksQ0FBOEI7UUFFNUQsSUFBSSxDQUFDLElBQUksR0FBRywyQkFBMkIsQ0FBQztJQUMxQyxDQUFDO0NBQ0Y7QUFFRCxNQUFNLFFBQVEsR0FBZ0gsSUFBSSxHQUFHLENBQUM7SUFDcEksQ0FBQyxtQkFBbUIsRUFBRSxjQUFjLENBQUM7SUFDckMsQ0FBQyxrQkFBa0IsRUFBRSxrQkFBa0IsQ0FBQztJQUN4QyxDQUFDLGVBQWUsRUFBRSxjQUFjLENBQUM7SUFDakMsQ0FBQyxjQUFj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
|
|
@@ -19,7 +19,9 @@ export type TPalletBundleErrorCode =
|
|
|
19
19
|
/** A download answered other bytes than its release asset states. */
|
|
20
20
|
| 'invalid_download'
|
|
21
21
|
/** An executable or file does not carry the digest the bundle states. */
|
|
22
|
-
| 'artifact_mismatch'
|
|
22
|
+
| 'artifact_mismatch'
|
|
23
|
+
/** The node unit's file descriptor store could not be released, or its release not confirmed. */
|
|
24
|
+
| 'store_kept';
|
|
23
25
|
export declare class PalletBundleError extends Error {
|
|
24
26
|
readonly code: TPalletBundleErrorCode;
|
|
25
27
|
/**
|
package/dist_ts_bundle/errors.js
CHANGED
|
@@ -17,4 +17,4 @@ export function requireBundle(valueArg, codeArg) {
|
|
|
17
17
|
if (!valueArg)
|
|
18
18
|
throw new PalletBundleError(codeArg);
|
|
19
19
|
}
|
|
20
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
20
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfYnVuZGxlL2Vycm9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUF5QkEsTUFBTSxPQUFPLGlCQUFrQixTQUFRLEtBQUs7SUFPZDtJQU41Qjs7O09BR0c7SUFDYSxhQUFhLENBQXFCO0lBRWxELFlBQTRCLElBQTRCLEVBQUUsYUFBcUUsRUFBRTtRQUMvSCxLQUFLLENBQUMsa0NBQWtDLElBQUksR0FBRyxFQUFFLFVBQVUsQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBRGpHLFNBQUksR0FBSixJQUFJLENBQXdCO1FBRXRELElBQUksQ0FBQyxJQUFJLEdBQUcsbUJBQW1CLENBQUM7UUFDaEMsSUFBSSxVQUFVLENBQUMsYUFBYTtZQUFFLElBQUksQ0FBQyxhQUFhLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7SUFDbEcsQ0FBQztDQUNGO0FBRUQsTUFBTSxVQUFVLGFBQWEsQ0FBQyxRQUFpQixFQUFFLE9BQStCO0lBQzlFLElBQUksQ0FBQyxRQUFRO1FBQUUsTUFBTSxJQUFJLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3RELENBQUMifQ==
|
|
@@ -43,6 +43,38 @@ export declare const palletControlUnitModes: Readonly<{
|
|
|
43
43
|
readonly 'runtime-unit': "pallet.node.process";
|
|
44
44
|
}>;
|
|
45
45
|
export type TPalletControlUnitMode = keyof typeof palletControlUnitModes;
|
|
46
|
-
/**
|
|
47
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Who owns the host's IPv4 forwarding while the node runs, as the node's installer states it on
|
|
48
|
+
* every start of the node (`runtime-serve` and `runtime-unit` take `--forwarding-mode <mode>`,
|
|
49
|
+
* required). It is a fact of the host, never inferred by the node:
|
|
50
|
+
* - `docker-shared`: Docker runs on the host. It switched forwarding on with its iptables `FORWARD`
|
|
51
|
+
* policy DROP; the node never writes forwarding and passes its own flows through Docker's
|
|
52
|
+
* `DOCKER-USER` chain. The host provides the iptables-nft 1.8.10+ frontend.
|
|
53
|
+
* - `exclusive`: nothing else forwards on the host. The node switches forwarding on only while a
|
|
54
|
+
* generation is UP behind its exclusive packet table. The host runs no Docker and persists no
|
|
55
|
+
* forwarding in sysctl configuration; switching a host from `docker-shared` to `exclusive` is
|
|
56
|
+
* done with the node stopped, Docker removed, persisted forwarding removed and a reboot.
|
|
57
|
+
*/
|
|
58
|
+
export declare const palletForwardingModes: readonly ["docker-shared", "exclusive"];
|
|
59
|
+
export type TPalletForwardingMode = typeof palletForwardingModes[number];
|
|
60
|
+
/** The argument that carries the forwarding mode to the node modes. */
|
|
61
|
+
export declare const palletForwardingModeArgument = "--forwarding-mode";
|
|
62
|
+
export declare const isPalletForwardingMode: (valueArg: unknown) => valueArg is TPalletForwardingMode;
|
|
63
|
+
/**
|
|
64
|
+
* The argument that hands a node mode the router network namespace a service manager kept for it:
|
|
65
|
+
* `--router-namespace-descriptor 3`, after the forwarding mode, the descriptor always 3 and
|
|
66
|
+
* inherited without close-on-exec. The node verifies it (a network namespace of the journaled device
|
|
67
|
+
* and inode, in this boot) before adopting it, and marks it close-on-exec itself.
|
|
68
|
+
*/
|
|
69
|
+
export declare const palletRouterNamespaceDescriptorArgument = "--router-namespace-descriptor";
|
|
70
|
+
export declare const palletRouterNamespaceDescriptor = 3;
|
|
71
|
+
/** The `FDNAME=` under which the node stores its router namespace with its service manager. */
|
|
72
|
+
export declare const palletRouterNamespaceDescriptorName = "pallet-router";
|
|
73
|
+
/**
|
|
74
|
+
* The reasons a `failed` line names. `forwarding_mode_refused`: a node mode refused the stated
|
|
75
|
+
* forwarding mode for a fact of the host that persists until an operator changes it (persisted
|
|
76
|
+
* forwarding or Docker under `exclusive`; no iptables-nft frontend, or a host that does not forward,
|
|
77
|
+
* under `docker-shared`) — restarting cannot help.
|
|
78
|
+
*/
|
|
79
|
+
export declare const palletControlFailureReasons: readonly ["invalid_arguments", "invalid_ca_store", "invalid_stdin", "owner_failed", "unsupported_kernel", "forwarding_mode_refused"];
|
|
48
80
|
export type TPalletControlFailureReason = typeof palletControlFailureReasons[number];
|
|
@@ -40,8 +40,39 @@ export const palletControlUnitModes = Object.freeze({
|
|
|
40
40
|
'containerd-serve': palletControlProtocols.containerd,
|
|
41
41
|
'runtime-unit': palletControlProtocols.node,
|
|
42
42
|
});
|
|
43
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* Who owns the host's IPv4 forwarding while the node runs, as the node's installer states it on
|
|
45
|
+
* every start of the node (`runtime-serve` and `runtime-unit` take `--forwarding-mode <mode>`,
|
|
46
|
+
* required). It is a fact of the host, never inferred by the node:
|
|
47
|
+
* - `docker-shared`: Docker runs on the host. It switched forwarding on with its iptables `FORWARD`
|
|
48
|
+
* policy DROP; the node never writes forwarding and passes its own flows through Docker's
|
|
49
|
+
* `DOCKER-USER` chain. The host provides the iptables-nft 1.8.10+ frontend.
|
|
50
|
+
* - `exclusive`: nothing else forwards on the host. The node switches forwarding on only while a
|
|
51
|
+
* generation is UP behind its exclusive packet table. The host runs no Docker and persists no
|
|
52
|
+
* forwarding in sysctl configuration; switching a host from `docker-shared` to `exclusive` is
|
|
53
|
+
* done with the node stopped, Docker removed, persisted forwarding removed and a reboot.
|
|
54
|
+
*/
|
|
55
|
+
export const palletForwardingModes = Object.freeze(['docker-shared', 'exclusive']);
|
|
56
|
+
/** The argument that carries the forwarding mode to the node modes. */
|
|
57
|
+
export const palletForwardingModeArgument = '--forwarding-mode';
|
|
58
|
+
export const isPalletForwardingMode = (valueArg) => palletForwardingModes.some((modeArg) => modeArg === valueArg);
|
|
59
|
+
/**
|
|
60
|
+
* The argument that hands a node mode the router network namespace a service manager kept for it:
|
|
61
|
+
* `--router-namespace-descriptor 3`, after the forwarding mode, the descriptor always 3 and
|
|
62
|
+
* inherited without close-on-exec. The node verifies it (a network namespace of the journaled device
|
|
63
|
+
* and inode, in this boot) before adopting it, and marks it close-on-exec itself.
|
|
64
|
+
*/
|
|
65
|
+
export const palletRouterNamespaceDescriptorArgument = '--router-namespace-descriptor';
|
|
66
|
+
export const palletRouterNamespaceDescriptor = 3;
|
|
67
|
+
/** The `FDNAME=` under which the node stores its router namespace with its service manager. */
|
|
68
|
+
export const palletRouterNamespaceDescriptorName = 'pallet-router';
|
|
69
|
+
/**
|
|
70
|
+
* The reasons a `failed` line names. `forwarding_mode_refused`: a node mode refused the stated
|
|
71
|
+
* forwarding mode for a fact of the host that persists until an operator changes it (persisted
|
|
72
|
+
* forwarding or Docker under `exclusive`; no iptables-nft frontend, or a host that does not forward,
|
|
73
|
+
* under `docker-shared`) — restarting cannot help.
|
|
74
|
+
*/
|
|
44
75
|
export const palletControlFailureReasons = Object.freeze([
|
|
45
|
-
'invalid_arguments', 'invalid_ca_store', 'invalid_stdin', 'owner_failed', 'unsupported_kernel',
|
|
76
|
+
'invalid_arguments', 'invalid_ca_store', 'invalid_stdin', 'owner_failed', 'unsupported_kernel', 'forwarding_mode_refused',
|
|
46
77
|
]);
|
|
47
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
78
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdG9jb2wuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c19idW5kbGUvcHJvdG9jb2wudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O0dBS0c7QUFFSCx1RkFBdUY7QUFDdkYsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsaUJBQWlCLENBQUM7QUFFekQsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUNsRCxVQUFVLEVBQUUsMkJBQTJCO0lBQ3ZDLElBQUksRUFBRSxxQkFBcUI7SUFDM0IsS0FBSyxFQUFFLHNCQUFzQjtJQUM3QixXQUFXLEVBQUUsNEJBQTRCO0lBQ3pDLFVBQVUsRUFBRSwyQkFBMkI7SUFDdkMsYUFBYSxFQUFFLHVCQUF1QjtJQUN0QyxjQUFjLEVBQUUsd0JBQXdCO0NBQ2hDLENBQUMsQ0FBQztBQUVaOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLDBCQUEwQixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDdEQsa0JBQWtCLEVBQUUsc0JBQXNCLENBQUMsVUFBVTtJQUNyRCxzQkFBc0IsRUFBRSxzQkFBc0IsQ0FBQyxVQUFVO0lBQ3pELGVBQWUsRUFBRSxzQkFBc0IsQ0FBQyxJQUFJO0NBQ3BDLENBQUMsQ0FBQztBQUdaLDhGQUE4RjtBQUM5RixNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ3JELGVBQWUsRUFBRSxzQkFBc0IsQ0FBQyxLQUFLO0lBQzdDLGtCQUFrQixFQUFFLHNCQUFzQixDQUFDLEtBQUs7SUFDaEQsaUJBQWlCLEVBQUUsc0JBQXNCLENBQUMsV0FBVztJQUNyRCx1QkFBdUIsRUFBRSxzQkFBc0IsQ0FBQyxXQUFXO0lBQzNELGlCQUFpQixFQUFFLHNCQUFzQixDQUFDLGNBQWM7Q0FDaEQsQ0FBQyxDQUFDO0FBR1o7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUNsRCxrQkFBa0IsRUFBRSxzQkFBc0IsQ0FBQyxVQUFVO0lBQ3JELGNBQWMsRUFBRSxzQkFBc0IsQ0FBQyxJQUFJO0NBQ25DLENBQUMsQ0FBQztBQUdaOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLGVBQWUsRUFBRSxXQUFXLENBQVUsQ0FBQyxDQUFDO0FBRTVGLHVFQUF1RTtBQUN2RSxNQUFNLENBQUMsTUFBTSw0QkFBNEIsR0FBRyxtQkFBbUIsQ0FBQztBQUNoRSxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLFFBQWlCLEVBQXFDLEVBQUUsQ0FDN0YscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLEtBQUssUUFBUSxDQUFDLENBQUM7QUFFaEU7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQUMsTUFBTSx1Q0FBdUMsR0FBRywrQkFBK0IsQ0FBQztBQUN2RixNQUFNLENBQUMsTUFBTSwrQkFBK0IsR0FBRyxDQUFDLENBQUM7QUFDakQsK0ZBQStGO0FBQy9GLE1BQU0sQ0FBQyxNQUFNLG1DQUFtQyxHQUFHLGVBQWUsQ0FBQztBQUVuRTs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLDJCQUEyQixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDdkQsbUJBQW1CLEVBQUUsa0JBQWtCLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxvQkFBb0IsRUFBRSx5QkFBeUI7Q0FDakgsQ0FBQyxDQUFDIn0=
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
|
+
import { type TPalletForwardingMode } from './protocol.js';
|
|
2
3
|
/**
|
|
3
4
|
* The service units an installer writes for Pallet, to the "Service unit contract" in Pallet's readme.
|
|
4
5
|
* Pallet never writes a unit file itself: Spark on fleet nodes and Onebox on its own host install
|
|
@@ -37,6 +38,10 @@ export interface IPalletContainerdUnitOptions {
|
|
|
37
38
|
}
|
|
38
39
|
export interface IPalletNodeUnitOptions {
|
|
39
40
|
unitName: string;
|
|
41
|
+
/** Who owns the host's IPv4 forwarding (`TPalletForwardingMode`), required. Moving a host from
|
|
42
|
+
* `docker-shared` to `exclusive` replaces the unit with the node stopped, Docker removed and the
|
|
43
|
+
* host rebooted. */
|
|
44
|
+
forwardingMode: TPalletForwardingMode;
|
|
40
45
|
/** `<bundle>/pallet-control` of the selected installation. */
|
|
41
46
|
controlExecutable: string;
|
|
42
47
|
workingDirectory: string;
|
|
@@ -64,6 +69,13 @@ export declare const createPalletContainerdServiceDefinition: (optionsArg: IPall
|
|
|
64
69
|
* it started, and the service manager removes whatever remains of the unit's cgroup when the stop
|
|
65
70
|
* timeout ends, before any successor starts. A failed lifetime is restarted by the service manager,
|
|
66
71
|
* never inside the process.
|
|
72
|
+
*
|
|
73
|
+
* The node keeps its router network namespace in the unit's file descriptor store
|
|
74
|
+
* (`FileDescriptorStoreMax=1`, `FileDescriptorStorePreserve=yes`, `NotifyAccess=all`: the native that
|
|
75
|
+
* owns the namespace, a child of the main process, stores it as `FDNAME=pallet-router`), and the
|
|
76
|
+
* manager hands it back to the next main process through `LISTEN_FDS`, so a restart keeps the
|
|
77
|
+
* workloads' links. A reboot empties the store; an installer releases it
|
|
78
|
+
* (`releasePalletNodeDescriptorStore`) whenever it changes the forwarding mode and on uninstall.
|
|
67
79
|
*/
|
|
68
80
|
export declare const createPalletNodeServiceDefinition: (optionsArg: IPalletNodeUnitOptions) => plugins.smartdaemon.SystemdServiceDefinition;
|
|
69
81
|
/**
|
|
@@ -72,5 +84,29 @@ export declare const createPalletNodeServiceDefinition: (optionsArg: IPalletNode
|
|
|
72
84
|
* weakens the contract is refused whatever file produced it.
|
|
73
85
|
*/
|
|
74
86
|
export declare const palletContainerdServiceSettingsMatch: (settingsArg: plugins.smartdaemon.ISystemdServiceSettings, unitNameArg: string) => boolean;
|
|
75
|
-
/**
|
|
76
|
-
|
|
87
|
+
/**
|
|
88
|
+
* The same reading of the node unit: no restart inside a stop, a stop long enough to join, the
|
|
89
|
+
* router namespace's file descriptor store (`notifyAccess` `all`, one descriptor, preserved), and
|
|
90
|
+
* exactly the command line `createPalletNodeServiceDefinition` renders for `expectedArg` — one
|
|
91
|
+
* `ExecStart`, failure not ignored, whose argument vector is the control executable,
|
|
92
|
+
* `runtime-unit`, `--forwarding-mode` and the stated mode, as the manager loaded it (smartdaemon
|
|
93
|
+
* reads it from the unit's D-Bus `ExecStart`, one string per argument). A unit installed for the
|
|
94
|
+
* other forwarding mode, or with any other command line, does not match.
|
|
95
|
+
*/
|
|
96
|
+
export declare const palletNodeServiceSettingsMatch: (settingsArg: plugins.smartdaemon.ISystemdServiceSettings, unitNameArg: string, expectedArg: Pick<IPalletNodeUnitOptions, "controlExecutable" | "forwardingMode">) => boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Release the node unit's file descriptor store, the kept router namespace, as an installer must
|
|
99
|
+
* whenever it changes the node's forwarding mode and when it uninstalls the node: the stopped unit
|
|
100
|
+
* (`inactive`, without a pending job; a `failed` one needs `reset-failed` first) is cleaned with
|
|
101
|
+
* `systemctl clean --what=fdstore`. Resolves once the manager released the store — also when the
|
|
102
|
+
* inspection after the release failed (`released_uninspected`). A `command_failed` clean may have
|
|
103
|
+
* timed out with the store released or kept, so the unit is inspected: an empty store resolves, a
|
|
104
|
+
* kept one rejects `store_kept` with the clean's failure as the cause, and an inspection that fails
|
|
105
|
+
* too rejects `store_kept` with an `AggregateError` of both, the clean's failure first.
|
|
106
|
+
*/
|
|
107
|
+
export declare const releasePalletNodeDescriptorStore: (unitArg: {
|
|
108
|
+
cleanFileDescriptorStore(): Promise<unknown>;
|
|
109
|
+
inspect(): Promise<{
|
|
110
|
+
fileDescriptorStoreCount: number;
|
|
111
|
+
}>;
|
|
112
|
+
}) => Promise<void>;
|
package/dist_ts_bundle/units.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import { PalletBundleError } from './errors.js';
|
|
3
|
+
import { isPalletForwardingMode, palletForwardingModeArgument } from './protocol.js';
|
|
3
4
|
/**
|
|
4
5
|
* The service units an installer writes for Pallet, to the "Service unit contract" in Pallet's readme.
|
|
5
6
|
* Pallet never writes a unit file itself: Spark on fleet nodes and Onebox on its own host install
|
|
@@ -95,12 +96,24 @@ export const createPalletContainerdServiceDefinition = (optionsArg) => definitio
|
|
|
95
96
|
* it started, and the service manager removes whatever remains of the unit's cgroup when the stop
|
|
96
97
|
* timeout ends, before any successor starts. A failed lifetime is restarted by the service manager,
|
|
97
98
|
* never inside the process.
|
|
99
|
+
*
|
|
100
|
+
* The node keeps its router network namespace in the unit's file descriptor store
|
|
101
|
+
* (`FileDescriptorStoreMax=1`, `FileDescriptorStorePreserve=yes`, `NotifyAccess=all`: the native that
|
|
102
|
+
* owns the namespace, a child of the main process, stores it as `FDNAME=pallet-router`), and the
|
|
103
|
+
* manager hands it back to the next main process through `LISTEN_FDS`, so a restart keeps the
|
|
104
|
+
* workloads' links. A reboot empties the store; an installer releases it
|
|
105
|
+
* (`releasePalletNodeDescriptorStore`) whenever it changes the forwarding mode and on uninstall.
|
|
98
106
|
*/
|
|
99
|
-
export const createPalletNodeServiceDefinition = (optionsArg) =>
|
|
107
|
+
export const createPalletNodeServiceDefinition = (optionsArg) => {
|
|
108
|
+
if (!isPalletForwardingMode(optionsArg?.forwardingMode))
|
|
109
|
+
throw new PalletBundleError('invalid_options');
|
|
110
|
+
return nodeServiceDefinition(optionsArg);
|
|
111
|
+
};
|
|
112
|
+
const nodeServiceDefinition = (optionsArg) => definition({
|
|
100
113
|
unitName: optionsArg.unitName,
|
|
101
114
|
description: 'serve.zone Pallet node',
|
|
102
115
|
executable: optionsArg.controlExecutable,
|
|
103
|
-
args: ['runtime-unit'],
|
|
116
|
+
args: ['runtime-unit', palletForwardingModeArgument, optionsArg.forwardingMode],
|
|
104
117
|
workingDirectory: optionsArg.workingDirectory,
|
|
105
118
|
user: 'root',
|
|
106
119
|
group: 'root',
|
|
@@ -108,6 +121,9 @@ export const createPalletNodeServiceDefinition = (optionsArg) => definition({
|
|
|
108
121
|
restartSeconds: 5,
|
|
109
122
|
killMode: 'mixed',
|
|
110
123
|
timeoutStopSeconds: palletNodeStopTimeoutSeconds,
|
|
124
|
+
notifyAccess: 'all',
|
|
125
|
+
fileDescriptorStoreMax: 1,
|
|
126
|
+
fileDescriptorStorePreserve: 'yes',
|
|
111
127
|
dependencies: {
|
|
112
128
|
defaultDependencies: true,
|
|
113
129
|
after: [optionsArg.guardUnitName, optionsArg.containerdUnitName],
|
|
@@ -128,10 +144,58 @@ export const palletContainerdServiceSettingsMatch = (settingsArg, unitNameArg) =
|
|
|
128
144
|
settingsArg.delegate && typeof settingsArg.timeoutStopMicroseconds === 'number' &&
|
|
129
145
|
settingsArg.timeoutStopMicroseconds >= 45_000_000 && settingsArg.limitNoFile === 'infinity' &&
|
|
130
146
|
settingsArg.limitNoFileSoft === 'infinity' && settingsArg.tasksMax === 'infinity' && settingsArg.oomScoreAdjust === -999;
|
|
131
|
-
/**
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
147
|
+
/**
|
|
148
|
+
* The same reading of the node unit: no restart inside a stop, a stop long enough to join, the
|
|
149
|
+
* router namespace's file descriptor store (`notifyAccess` `all`, one descriptor, preserved), and
|
|
150
|
+
* exactly the command line `createPalletNodeServiceDefinition` renders for `expectedArg` — one
|
|
151
|
+
* `ExecStart`, failure not ignored, whose argument vector is the control executable,
|
|
152
|
+
* `runtime-unit`, `--forwarding-mode` and the stated mode, as the manager loaded it (smartdaemon
|
|
153
|
+
* reads it from the unit's D-Bus `ExecStart`, one string per argument). A unit installed for the
|
|
154
|
+
* other forwarding mode, or with any other command line, does not match.
|
|
155
|
+
*/
|
|
156
|
+
export const palletNodeServiceSettingsMatch = (settingsArg, unitNameArg, expectedArg) => {
|
|
157
|
+
if (!isPalletForwardingMode(expectedArg?.forwardingMode) || typeof expectedArg.controlExecutable !== 'string')
|
|
158
|
+
return false;
|
|
159
|
+
const argv = [expectedArg.controlExecutable, 'runtime-unit', palletForwardingModeArgument, expectedArg.forwardingMode];
|
|
160
|
+
const [command, ...more] = settingsArg.execStart;
|
|
161
|
+
return settingsArg.unitName === unitNameArg && settingsArg.type === 'exec' && settingsArg.killMode === 'mixed' &&
|
|
162
|
+
settingsArg.restart === 'on-failure' && settingsArg.notifyAccess === 'all' &&
|
|
163
|
+
settingsArg.fileDescriptorStoreMax === 1 && settingsArg.fileDescriptorStorePreserve === 'yes' &&
|
|
164
|
+
typeof settingsArg.timeoutStopMicroseconds === 'number' &&
|
|
165
|
+
settingsArg.timeoutStopMicroseconds >= palletNodeStopTimeoutSeconds * 1_000_000 && !settingsArg.delegate &&
|
|
166
|
+
Object.keys(settingsArg.environment).length === 0 &&
|
|
167
|
+
command !== undefined && more.length === 0 && !command.ignoreFailure && command.path === expectedArg.controlExecutable &&
|
|
168
|
+
command.argv.length === argv.length && argv.every((value, index) => command.argv[index] === value);
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* Release the node unit's file descriptor store, the kept router namespace, as an installer must
|
|
172
|
+
* whenever it changes the node's forwarding mode and when it uninstalls the node: the stopped unit
|
|
173
|
+
* (`inactive`, without a pending job; a `failed` one needs `reset-failed` first) is cleaned with
|
|
174
|
+
* `systemctl clean --what=fdstore`. Resolves once the manager released the store — also when the
|
|
175
|
+
* inspection after the release failed (`released_uninspected`). A `command_failed` clean may have
|
|
176
|
+
* timed out with the store released or kept, so the unit is inspected: an empty store resolves, a
|
|
177
|
+
* kept one rejects `store_kept` with the clean's failure as the cause, and an inspection that fails
|
|
178
|
+
* too rejects `store_kept` with an `AggregateError` of both, the clean's failure first.
|
|
179
|
+
*/
|
|
180
|
+
export const releasePalletNodeDescriptorStore = async (unitArg) => {
|
|
181
|
+
try {
|
|
182
|
+
await unitArg.cleanFileDescriptorStore();
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
if (error instanceof plugins.smartdaemon.SystemdUnitError && error.code === 'released_uninspected')
|
|
186
|
+
return;
|
|
187
|
+
if (!(error instanceof plugins.smartdaemon.SystemdUnitError) || error.code !== 'command_failed') {
|
|
188
|
+
throw new PalletBundleError('store_kept', { cause: error });
|
|
189
|
+
}
|
|
190
|
+
let snapshot;
|
|
191
|
+
try {
|
|
192
|
+
snapshot = await unitArg.inspect();
|
|
193
|
+
}
|
|
194
|
+
catch (inspection) {
|
|
195
|
+
throw new PalletBundleError('store_kept', { cause: new AggregateError([error, inspection], 'Pallet node store release unconfirmed') });
|
|
196
|
+
}
|
|
197
|
+
if (snapshot.fileDescriptorStoreCount !== 0)
|
|
198
|
+
throw new PalletBundleError('store_kept', { cause: error });
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5pdHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c19idW5kbGUvdW5pdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2hELE9BQU8sRUFBRSxzQkFBc0IsRUFBRSw0QkFBNEIsRUFBOEIsTUFBTSxlQUFlLENBQUM7QUFFakg7Ozs7R0FJRztBQUVILHdGQUF3RjtBQUN4RixNQUFNLENBQUMsTUFBTSw4QkFBOEIsR0FBRywwQkFBMEIsQ0FBQztBQUV6RSxxR0FBcUc7QUFDckcsTUFBTSxDQUFDLE1BQU0sNEJBQTRCLEdBQUcsR0FBRyxDQUFDO0FBRWhEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLENBQUMsTUFBTSw2QkFBNkIsR0FBRyxHQUFHLENBQUM7QUFtQ2pELE1BQU0sVUFBVSxHQUFHLENBQUMsVUFBZ0UsRUFBRSxFQUFFO0lBQ3RGLElBQUksQ0FBQztRQUFDLE9BQU8sSUFBSSxPQUFPLENBQUMsV0FBVyxDQUFDLHdCQUF3QixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQUMsQ0FBQztJQUM1RSxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQUMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLGlCQUFpQixFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFBQyxDQUFDO0FBQ3JGLENBQUMsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxrQ0FBa0MsR0FBRyxDQUFDLFVBQW1DLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQztJQUNwRyxRQUFRLEVBQUUsVUFBVSxDQUFDLFFBQVE7SUFDN0IsV0FBVyxFQUFFLDJDQUEyQztJQUN4RCxVQUFVLEVBQUUsVUFBVSxDQUFDLFVBQVU7SUFDakMsSUFBSSxFQUFFLENBQUMsZUFBZSxDQUFDO0lBQ3ZCLGdCQUFnQixFQUFFLFVB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
|
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"url": "https://community.foss.global/"
|
|
11
11
|
},
|
|
12
12
|
"name": "@serve.zone/pallet-bundle",
|
|
13
|
-
"version": "
|
|
13
|
+
"version": "36.0.0",
|
|
14
14
|
"type": "module",
|
|
15
15
|
"description": "Install surface of Pallet's sealed control bundle: pinned release download and verification, the service units Pallet's contract states, and supervisors for the pallet-control process protocol.",
|
|
16
16
|
"main": "./dist_ts_bundle/index.js",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@git.zone/tspack": "1.4.1",
|
|
26
|
-
"@push.rocks/smartdaemon": "2.
|
|
27
|
-
"@serve.zone/interfaces": "32.
|
|
26
|
+
"@push.rocks/smartdaemon": "2.18.0",
|
|
27
|
+
"@serve.zone/interfaces": "32.44.0"
|
|
28
28
|
},
|
|
29
29
|
"files": [
|
|
30
30
|
"ts_bundle",
|
package/readme.md
CHANGED
|
@@ -128,13 +128,44 @@ with its `SystemdUnitFile`. The unit names and the install root are the installe
|
|
|
128
128
|
- The containerd unit runs `containerd-serve` to the contract in Pallet's readme ("Pallet's own
|
|
129
129
|
containerd"). `palletContainerdServiceSettingsMatch` reads the loaded unit's settings, drop-ins
|
|
130
130
|
included, back against that contract.
|
|
131
|
-
- The node unit runs `runtime-unit
|
|
131
|
+
- The node unit runs `runtime-unit --forwarding-mode <mode>`, the node lifetime as a unit's main
|
|
132
|
+
process, with the host's forwarding mode (`forwardingMode`, required: `docker-shared` while Docker
|
|
133
|
+
runs on the host, `exclusive` once it is removed; see Pallet's readme, "Host forwarding modes"):
|
|
134
|
+
null stdin, stopped
|
|
132
135
|
by SIGTERM, `KillMode=mixed`, restarted on failure by the service manager, after the guard and
|
|
133
|
-
containerd units. `palletNodeServiceSettingsMatch
|
|
136
|
+
containerd units. `palletNodeServiceSettingsMatch(settings, unitName, { controlExecutable,
|
|
137
|
+
forwardingMode })` reads it back, its command line included: exactly one `ExecStart`, whose
|
|
138
|
+
argument vector (smartdaemon ≥ 2.16.0 reads it from the unit's D-Bus property, one string per
|
|
139
|
+
argument) is the control executable, `runtime-unit`, `--forwarding-mode` and the stated mode, so a
|
|
140
|
+
unit installed for the other mode never matches. `palletNodeStopTimeoutSeconds`
|
|
134
141
|
(360) is its least `TimeoutStopSec=`. `palletNodeStartTimeoutSeconds` (600) is how long a start
|
|
135
142
|
may take before its `ready` line: the start fences what the previous lifetime retained first
|
|
136
143
|
(derivation in Pallet's readme, "Foreground node process"). `Type=exec` does not wait for
|
|
137
144
|
`ready`; an installer that does allows at least that long.
|
|
145
|
+
- The node unit keeps the node's router network namespace across restarts in its file descriptor
|
|
146
|
+
store: it renders `NotifyAccess=all` (the native that owns the namespace, a child of the main
|
|
147
|
+
process, stores it as `FDNAME=pallet-router`), `FileDescriptorStoreMax=1` and
|
|
148
|
+
`FileDescriptorStorePreserve=yes`, which need systemd 254 or later, and
|
|
149
|
+
`palletNodeServiceSettingsMatch` requires all three — a node unit a 35.x installer wrote no longer
|
|
150
|
+
matches and must be installed again. The manager hands the namespace back to the next main process
|
|
151
|
+
through `LISTEN_FDS`; a reboot empties the store, and so does unloading the unit.
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
import { releasePalletNodeDescriptorStore } from '@serve.zone/pallet-bundle';
|
|
155
|
+
|
|
156
|
+
// The node unit stopped: on every change of its forwarding mode, and on uninstall.
|
|
157
|
+
await releasePalletNodeDescriptorStore(new SystemdUnit({ unitName: node.unitName }));
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
`releasePalletNodeDescriptorStore(unit)` releases that store (`systemctl clean --what=fdstore`).
|
|
161
|
+
An installer calls it with the node unit stopped — `inactive` with no pending job, a `failed` one
|
|
162
|
+
after `reset-failed` — whenever it changes the node's forwarding mode and when it uninstalls the
|
|
163
|
+
node, so no namespace of the previous mode or installation is adopted. It resolves once the manager
|
|
164
|
+
released the store, also when only the inspection after the release failed; a clean whose outcome
|
|
165
|
+
is unknown is decided by inspecting the unit, and a store still held, or a release it cannot
|
|
166
|
+
confirm, rejects with the `PalletBundleError` code `store_kept`. Its cause is the clean's failure,
|
|
167
|
+
or, when the inspection that was to decide that clean failed as well, an `AggregateError` of both,
|
|
168
|
+
the clean's failure first.
|
|
138
169
|
|
|
139
170
|
## Process supervisors
|
|
140
171
|
|
|
@@ -148,6 +179,10 @@ await new PalletControlOneshot({ binaryPath: control, binarySha256: bundle.execu
|
|
|
148
179
|
// A supervised lifetime held by a stdin pipe: enrollment-serve, enrollment-provision, runtime-serve.
|
|
149
180
|
const lifetime = new PalletControlLifetime({ binaryPath: control, binarySha256, mode: 'enrollment-serve' });
|
|
150
181
|
await lifetime.run(signal, async (running) => { /* talk to the enrollment socket */ });
|
|
182
|
+
|
|
183
|
+
// The node states who owns the host's IPv4 forwarding, always: `docker-shared` while Docker runs on
|
|
184
|
+
// the host, `exclusive` once it is removed. The enrollment modes take no forwarding mode.
|
|
185
|
+
const node = new PalletControlLifetime({ binaryPath: control, binarySha256, mode: 'runtime-serve', forwardingMode: 'docker-shared' });
|
|
151
186
|
```
|
|
152
187
|
|
|
153
188
|
Both verify the executable's digest before every start, start it with a clean environment and `/`
|
|
@@ -158,6 +193,21 @@ while the child is `ready`; closing its stdin is the graceful stop, and a missed
|
|
|
158
193
|
signals SIGTERM and then SIGKILL, which fails the lifetime as `shutdown_failed`. Refusals are
|
|
159
194
|
`PalletControlProcessError` values; `unsupported_kernel` carries the operator's remedy.
|
|
160
195
|
|
|
196
|
+
A node that refuses its stated forwarding mode for a fact of the host that persists until an
|
|
197
|
+
operator changes it fails with the reason `forwarding_mode_refused` (`palletControlFailureReasons`;
|
|
198
|
+
`PalletControlProcessError` code `forwarding_mode_refused`), before or after `ready`: persisted IPv4
|
|
199
|
+
forwarding or a running Docker under `exclusive`, no iptables-nft frontend or a host that does not
|
|
200
|
+
forward under `docker-shared`. Restarting the node cannot help; a supervisor ends it instead.
|
|
201
|
+
Everything transient stays `owner_failed`.
|
|
202
|
+
|
|
203
|
+
A supervisor that keeps the router namespace for `runtime-serve` itself — as Spark does with the
|
|
204
|
+
descriptor its unit's store hands back — passes it as descriptor 3, without close-on-exec, and
|
|
205
|
+
appends `palletRouterNamespaceDescriptorArgument` and `palletRouterNamespaceDescriptor`
|
|
206
|
+
(`--router-namespace-descriptor 3`) after the forwarding mode; the node stores a namespace it
|
|
207
|
+
creates under `palletRouterNamespaceDescriptorName` (`pallet-router`). The node verifies the
|
|
208
|
+
descriptor against its journal before it adopts it, marks it close-on-exec itself and closes the
|
|
209
|
+
inherited number before any child starts. `PalletControlLifetime` never passes a descriptor.
|
|
210
|
+
|
|
161
211
|
A lifetime whose child does not report `ready` within `startupTimeoutMs` fails as
|
|
162
212
|
`startup_timeout`. For `runtime-serve` it defaults to the node's start contract,
|
|
163
213
|
`palletNodeStartTimeoutSeconds` × 1000 (600 s), and admits up to an hour for a node that retains
|
|
@@ -2,8 +2,8 @@ import * as plugins from './plugins.js';
|
|
|
2
2
|
import { canonicalPath, verifyExecutable } from './paths.js';
|
|
3
3
|
import { PalletControlStderr } from './classes.controlstderr.js';
|
|
4
4
|
import {
|
|
5
|
-
palletControlLifetimeModes, palletControlLinePrefix, palletControlOneshotModes,
|
|
6
|
-
type TPalletControlLifetimeMode, type TPalletControlOneshotMode,
|
|
5
|
+
palletControlLifetimeModes, palletControlLinePrefix, palletControlOneshotModes, isPalletForwardingMode,
|
|
6
|
+
palletForwardingModeArgument, type TPalletControlLifetimeMode, type TPalletControlOneshotMode, type TPalletForwardingMode,
|
|
7
7
|
} from './protocol.js';
|
|
8
8
|
import { palletNodeStartTimeoutSeconds } from './units.js';
|
|
9
9
|
|
|
@@ -21,6 +21,8 @@ export type TPalletControlProcessFailure =
|
|
|
21
21
|
| 'invalid_ca_store'
|
|
22
22
|
/** Pallet's packet engine refused the running kernel. */
|
|
23
23
|
| 'unsupported_kernel'
|
|
24
|
+
/** The node refused its forwarding mode for a persistent fact of the host (`forwarding_mode_refused`). */
|
|
25
|
+
| 'forwarding_mode_refused'
|
|
24
26
|
| 'protocol_invalid'
|
|
25
27
|
| 'shutdown_failed';
|
|
26
28
|
|
|
@@ -37,12 +39,13 @@ export class PalletControlProcessError extends Error {
|
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
|
|
40
|
-
const failures: ReadonlyMap<string, 'owner_failed' | 'invalid_ca_store' | 'unsupported_kernel'> = new Map([
|
|
42
|
+
const failures: ReadonlyMap<string, 'owner_failed' | 'invalid_ca_store' | 'unsupported_kernel' | 'forwarding_mode_refused'> = new Map([
|
|
41
43
|
['invalid_arguments', 'owner_failed'],
|
|
42
44
|
['invalid_ca_store', 'invalid_ca_store'],
|
|
43
45
|
['invalid_stdin', 'owner_failed'],
|
|
44
46
|
['owner_failed', 'owner_failed'],
|
|
45
47
|
['unsupported_kernel', 'unsupported_kernel'],
|
|
48
|
+
['forwarding_mode_refused', 'forwarding_mode_refused'],
|
|
46
49
|
]);
|
|
47
50
|
|
|
48
51
|
/**
|
|
@@ -79,11 +82,11 @@ interface IChild {
|
|
|
79
82
|
* told once when either pipe violates the protocol or its bounds.
|
|
80
83
|
*/
|
|
81
84
|
function spawnControl(optionsArg: {
|
|
82
|
-
binaryPath: string; mode: string; stdin: 'ignore' | 'pipe'; stderr: (lineArg: string) => void;
|
|
85
|
+
binaryPath: string; mode: string; arguments?: readonly string[]; stdin: 'ignore' | 'pipe'; stderr: (lineArg: string) => void;
|
|
83
86
|
maximumOutputBytes: number | null; terminationGraceMs: number;
|
|
84
87
|
onLine: (lineArg: string) => void; onInvalid: () => void; onDrainExpired: () => void;
|
|
85
88
|
}): IChild {
|
|
86
|
-
const child = plugins.childProcess.spawn(optionsArg.binaryPath, [optionsArg.mode], {
|
|
89
|
+
const child = plugins.childProcess.spawn(optionsArg.binaryPath, [optionsArg.mode, ...(optionsArg.arguments ?? [])], {
|
|
87
90
|
cwd: '/', env: { PATH: '/usr/bin:/bin' }, stdio: [optionsArg.stdin, 'pipe', 'pipe'],
|
|
88
91
|
});
|
|
89
92
|
let exited = false;
|
|
@@ -288,6 +291,9 @@ export class PalletControlOneshot {
|
|
|
288
291
|
|
|
289
292
|
export interface IPalletControlLifetimeOptions extends IPalletControlProcessOptions {
|
|
290
293
|
mode: TPalletControlLifetimeMode;
|
|
294
|
+
/** `runtime-serve` only, and required there: who owns the host's IPv4 forwarding
|
|
295
|
+
* (`TPalletForwardingMode`). The enrollment modes take none. */
|
|
296
|
+
forwardingMode?: TPalletForwardingMode;
|
|
291
297
|
/**
|
|
292
298
|
* How long the child may take to report `ready`. `runtime-serve` defaults to the node's start
|
|
293
299
|
* contract (`palletNodeStartTimeoutSeconds`) and admits up to an hour; the enrollment modes default
|
|
@@ -308,6 +314,7 @@ export interface IPalletControlLifetimeOptions extends IPalletControlProcessOpti
|
|
|
308
314
|
export class PalletControlLifetime {
|
|
309
315
|
private readonly options: ReturnType<typeof validated>;
|
|
310
316
|
private readonly mode: TPalletControlLifetimeMode;
|
|
317
|
+
private readonly forwardingMode: TPalletForwardingMode | null;
|
|
311
318
|
private used = false;
|
|
312
319
|
private available = false;
|
|
313
320
|
|
|
@@ -317,11 +324,16 @@ export class PalletControlLifetime {
|
|
|
317
324
|
throw new PalletControlProcessError('invalid_input');
|
|
318
325
|
}
|
|
319
326
|
const runtime = mode === 'runtime-serve';
|
|
327
|
+
const forwardingMode = isPalletForwardingMode(optionsArg.forwardingMode) ? optionsArg.forwardingMode : null;
|
|
328
|
+
if (runtime ? forwardingMode === null : optionsArg.forwardingMode !== undefined) {
|
|
329
|
+
throw new PalletControlProcessError('invalid_input');
|
|
330
|
+
}
|
|
320
331
|
this.mode = mode;
|
|
332
|
+
this.forwardingMode = forwardingMode;
|
|
321
333
|
// The runtime fences what its previous lifetime retained before `ready`, and its stop may join a
|
|
322
334
|
// five-minute native operation, then database cleanup. Its startup limit is the node's contract;
|
|
323
335
|
// an hour covers every per-request deadline of a start at the retained-workload maximum.
|
|
324
|
-
this.options = validated(optionsArg, ['mode'], [
|
|
336
|
+
this.options = validated(optionsArg, ['mode', 'forwardingMode'], [
|
|
325
337
|
['startupTimeoutMs', runtime ? palletNodeStartTimeoutSeconds * 1000 : 15_000, runtime ? 3_600_000 : 60_000],
|
|
326
338
|
['shutdownTimeoutMs', runtime ? 330_000 : 15_000, runtime ? 600_000 : 60_000],
|
|
327
339
|
['terminationGraceMs', 1_000, 60_000],
|
|
@@ -419,6 +431,7 @@ export class PalletControlLifetime {
|
|
|
419
431
|
abort.signal.throwIfAborted();
|
|
420
432
|
child = spawnControl({
|
|
421
433
|
binaryPath: this.options.binaryPath, mode: this.mode, stdin: 'pipe', stderr: this.options.stderr,
|
|
434
|
+
arguments: this.forwardingMode === null ? [] : [palletForwardingModeArgument, this.forwardingMode],
|
|
422
435
|
// The runtime reports for its whole lifetime; only the enrollment owner's output is bounded in total.
|
|
423
436
|
maximumOutputBytes: this.mode === 'runtime-serve' ? null : 1024 * 1024,
|
|
424
437
|
terminationGraceMs: timeouts.terminationGraceMs, onLine: line, onInvalid: () => reject('protocol_invalid'),
|
package/ts_bundle/errors.ts
CHANGED
|
@@ -19,7 +19,9 @@ export type TPalletBundleErrorCode =
|
|
|
19
19
|
/** A download answered other bytes than its release asset states. */
|
|
20
20
|
| 'invalid_download'
|
|
21
21
|
/** An executable or file does not carry the digest the bundle states. */
|
|
22
|
-
| 'artifact_mismatch'
|
|
22
|
+
| 'artifact_mismatch'
|
|
23
|
+
/** The node unit's file descriptor store could not be released, or its release not confirmed. */
|
|
24
|
+
| 'store_kept';
|
|
23
25
|
|
|
24
26
|
export class PalletBundleError extends Error {
|
|
25
27
|
/**
|
package/ts_bundle/protocol.ts
CHANGED
|
@@ -49,8 +49,43 @@ export const palletControlUnitModes = Object.freeze({
|
|
|
49
49
|
} as const);
|
|
50
50
|
export type TPalletControlUnitMode = keyof typeof palletControlUnitModes;
|
|
51
51
|
|
|
52
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* Who owns the host's IPv4 forwarding while the node runs, as the node's installer states it on
|
|
54
|
+
* every start of the node (`runtime-serve` and `runtime-unit` take `--forwarding-mode <mode>`,
|
|
55
|
+
* required). It is a fact of the host, never inferred by the node:
|
|
56
|
+
* - `docker-shared`: Docker runs on the host. It switched forwarding on with its iptables `FORWARD`
|
|
57
|
+
* policy DROP; the node never writes forwarding and passes its own flows through Docker's
|
|
58
|
+
* `DOCKER-USER` chain. The host provides the iptables-nft 1.8.10+ frontend.
|
|
59
|
+
* - `exclusive`: nothing else forwards on the host. The node switches forwarding on only while a
|
|
60
|
+
* generation is UP behind its exclusive packet table. The host runs no Docker and persists no
|
|
61
|
+
* forwarding in sysctl configuration; switching a host from `docker-shared` to `exclusive` is
|
|
62
|
+
* done with the node stopped, Docker removed, persisted forwarding removed and a reboot.
|
|
63
|
+
*/
|
|
64
|
+
export const palletForwardingModes = Object.freeze(['docker-shared', 'exclusive'] as const);
|
|
65
|
+
export type TPalletForwardingMode = typeof palletForwardingModes[number];
|
|
66
|
+
/** The argument that carries the forwarding mode to the node modes. */
|
|
67
|
+
export const palletForwardingModeArgument = '--forwarding-mode';
|
|
68
|
+
export const isPalletForwardingMode = (valueArg: unknown): valueArg is TPalletForwardingMode =>
|
|
69
|
+
palletForwardingModes.some((modeArg) => modeArg === valueArg);
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The argument that hands a node mode the router network namespace a service manager kept for it:
|
|
73
|
+
* `--router-namespace-descriptor 3`, after the forwarding mode, the descriptor always 3 and
|
|
74
|
+
* inherited without close-on-exec. The node verifies it (a network namespace of the journaled device
|
|
75
|
+
* and inode, in this boot) before adopting it, and marks it close-on-exec itself.
|
|
76
|
+
*/
|
|
77
|
+
export const palletRouterNamespaceDescriptorArgument = '--router-namespace-descriptor';
|
|
78
|
+
export const palletRouterNamespaceDescriptor = 3;
|
|
79
|
+
/** The `FDNAME=` under which the node stores its router namespace with its service manager. */
|
|
80
|
+
export const palletRouterNamespaceDescriptorName = 'pallet-router';
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The reasons a `failed` line names. `forwarding_mode_refused`: a node mode refused the stated
|
|
84
|
+
* forwarding mode for a fact of the host that persists until an operator changes it (persisted
|
|
85
|
+
* forwarding or Docker under `exclusive`; no iptables-nft frontend, or a host that does not forward,
|
|
86
|
+
* under `docker-shared`) — restarting cannot help.
|
|
87
|
+
*/
|
|
53
88
|
export const palletControlFailureReasons = Object.freeze([
|
|
54
|
-
'invalid_arguments', 'invalid_ca_store', 'invalid_stdin', 'owner_failed', 'unsupported_kernel',
|
|
89
|
+
'invalid_arguments', 'invalid_ca_store', 'invalid_stdin', 'owner_failed', 'unsupported_kernel', 'forwarding_mode_refused',
|
|
55
90
|
] as const);
|
|
56
91
|
export type TPalletControlFailureReason = typeof palletControlFailureReasons[number];
|
package/ts_bundle/readme.md
CHANGED
|
@@ -128,13 +128,44 @@ with its `SystemdUnitFile`. The unit names and the install root are the installe
|
|
|
128
128
|
- The containerd unit runs `containerd-serve` to the contract in Pallet's readme ("Pallet's own
|
|
129
129
|
containerd"). `palletContainerdServiceSettingsMatch` reads the loaded unit's settings, drop-ins
|
|
130
130
|
included, back against that contract.
|
|
131
|
-
- The node unit runs `runtime-unit
|
|
131
|
+
- The node unit runs `runtime-unit --forwarding-mode <mode>`, the node lifetime as a unit's main
|
|
132
|
+
process, with the host's forwarding mode (`forwardingMode`, required: `docker-shared` while Docker
|
|
133
|
+
runs on the host, `exclusive` once it is removed; see Pallet's readme, "Host forwarding modes"):
|
|
134
|
+
null stdin, stopped
|
|
132
135
|
by SIGTERM, `KillMode=mixed`, restarted on failure by the service manager, after the guard and
|
|
133
|
-
containerd units. `palletNodeServiceSettingsMatch
|
|
136
|
+
containerd units. `palletNodeServiceSettingsMatch(settings, unitName, { controlExecutable,
|
|
137
|
+
forwardingMode })` reads it back, its command line included: exactly one `ExecStart`, whose
|
|
138
|
+
argument vector (smartdaemon ≥ 2.16.0 reads it from the unit's D-Bus property, one string per
|
|
139
|
+
argument) is the control executable, `runtime-unit`, `--forwarding-mode` and the stated mode, so a
|
|
140
|
+
unit installed for the other mode never matches. `palletNodeStopTimeoutSeconds`
|
|
134
141
|
(360) is its least `TimeoutStopSec=`. `palletNodeStartTimeoutSeconds` (600) is how long a start
|
|
135
142
|
may take before its `ready` line: the start fences what the previous lifetime retained first
|
|
136
143
|
(derivation in Pallet's readme, "Foreground node process"). `Type=exec` does not wait for
|
|
137
144
|
`ready`; an installer that does allows at least that long.
|
|
145
|
+
- The node unit keeps the node's router network namespace across restarts in its file descriptor
|
|
146
|
+
store: it renders `NotifyAccess=all` (the native that owns the namespace, a child of the main
|
|
147
|
+
process, stores it as `FDNAME=pallet-router`), `FileDescriptorStoreMax=1` and
|
|
148
|
+
`FileDescriptorStorePreserve=yes`, which need systemd 254 or later, and
|
|
149
|
+
`palletNodeServiceSettingsMatch` requires all three — a node unit a 35.x installer wrote no longer
|
|
150
|
+
matches and must be installed again. The manager hands the namespace back to the next main process
|
|
151
|
+
through `LISTEN_FDS`; a reboot empties the store, and so does unloading the unit.
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
import { releasePalletNodeDescriptorStore } from '@serve.zone/pallet-bundle';
|
|
155
|
+
|
|
156
|
+
// The node unit stopped: on every change of its forwarding mode, and on uninstall.
|
|
157
|
+
await releasePalletNodeDescriptorStore(new SystemdUnit({ unitName: node.unitName }));
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
`releasePalletNodeDescriptorStore(unit)` releases that store (`systemctl clean --what=fdstore`).
|
|
161
|
+
An installer calls it with the node unit stopped — `inactive` with no pending job, a `failed` one
|
|
162
|
+
after `reset-failed` — whenever it changes the node's forwarding mode and when it uninstalls the
|
|
163
|
+
node, so no namespace of the previous mode or installation is adopted. It resolves once the manager
|
|
164
|
+
released the store, also when only the inspection after the release failed; a clean whose outcome
|
|
165
|
+
is unknown is decided by inspecting the unit, and a store still held, or a release it cannot
|
|
166
|
+
confirm, rejects with the `PalletBundleError` code `store_kept`. Its cause is the clean's failure,
|
|
167
|
+
or, when the inspection that was to decide that clean failed as well, an `AggregateError` of both,
|
|
168
|
+
the clean's failure first.
|
|
138
169
|
|
|
139
170
|
## Process supervisors
|
|
140
171
|
|
|
@@ -148,6 +179,10 @@ await new PalletControlOneshot({ binaryPath: control, binarySha256: bundle.execu
|
|
|
148
179
|
// A supervised lifetime held by a stdin pipe: enrollment-serve, enrollment-provision, runtime-serve.
|
|
149
180
|
const lifetime = new PalletControlLifetime({ binaryPath: control, binarySha256, mode: 'enrollment-serve' });
|
|
150
181
|
await lifetime.run(signal, async (running) => { /* talk to the enrollment socket */ });
|
|
182
|
+
|
|
183
|
+
// The node states who owns the host's IPv4 forwarding, always: `docker-shared` while Docker runs on
|
|
184
|
+
// the host, `exclusive` once it is removed. The enrollment modes take no forwarding mode.
|
|
185
|
+
const node = new PalletControlLifetime({ binaryPath: control, binarySha256, mode: 'runtime-serve', forwardingMode: 'docker-shared' });
|
|
151
186
|
```
|
|
152
187
|
|
|
153
188
|
Both verify the executable's digest before every start, start it with a clean environment and `/`
|
|
@@ -158,6 +193,21 @@ while the child is `ready`; closing its stdin is the graceful stop, and a missed
|
|
|
158
193
|
signals SIGTERM and then SIGKILL, which fails the lifetime as `shutdown_failed`. Refusals are
|
|
159
194
|
`PalletControlProcessError` values; `unsupported_kernel` carries the operator's remedy.
|
|
160
195
|
|
|
196
|
+
A node that refuses its stated forwarding mode for a fact of the host that persists until an
|
|
197
|
+
operator changes it fails with the reason `forwarding_mode_refused` (`palletControlFailureReasons`;
|
|
198
|
+
`PalletControlProcessError` code `forwarding_mode_refused`), before or after `ready`: persisted IPv4
|
|
199
|
+
forwarding or a running Docker under `exclusive`, no iptables-nft frontend or a host that does not
|
|
200
|
+
forward under `docker-shared`. Restarting the node cannot help; a supervisor ends it instead.
|
|
201
|
+
Everything transient stays `owner_failed`.
|
|
202
|
+
|
|
203
|
+
A supervisor that keeps the router namespace for `runtime-serve` itself — as Spark does with the
|
|
204
|
+
descriptor its unit's store hands back — passes it as descriptor 3, without close-on-exec, and
|
|
205
|
+
appends `palletRouterNamespaceDescriptorArgument` and `palletRouterNamespaceDescriptor`
|
|
206
|
+
(`--router-namespace-descriptor 3`) after the forwarding mode; the node stores a namespace it
|
|
207
|
+
creates under `palletRouterNamespaceDescriptorName` (`pallet-router`). The node verifies the
|
|
208
|
+
descriptor against its journal before it adopts it, marks it close-on-exec itself and closes the
|
|
209
|
+
inherited number before any child starts. `PalletControlLifetime` never passes a descriptor.
|
|
210
|
+
|
|
161
211
|
A lifetime whose child does not report `ready` within `startupTimeoutMs` fails as
|
|
162
212
|
`startup_timeout`. For `runtime-serve` it defaults to the node's start contract,
|
|
163
213
|
`palletNodeStartTimeoutSeconds` × 1000 (600 s), and admits up to an hour for a node that retains
|
package/ts_bundle/units.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import { PalletBundleError } from './errors.js';
|
|
3
|
+
import { isPalletForwardingMode, palletForwardingModeArgument, type TPalletForwardingMode } from './protocol.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* The service units an installer writes for Pallet, to the "Service unit contract" in Pallet's readme.
|
|
@@ -45,6 +46,10 @@ export interface IPalletContainerdUnitOptions {
|
|
|
45
46
|
|
|
46
47
|
export interface IPalletNodeUnitOptions {
|
|
47
48
|
unitName: string;
|
|
49
|
+
/** Who owns the host's IPv4 forwarding (`TPalletForwardingMode`), required. Moving a host from
|
|
50
|
+
* `docker-shared` to `exclusive` replaces the unit with the node stopped, Docker removed and the
|
|
51
|
+
* host rebooted. */
|
|
52
|
+
forwardingMode: TPalletForwardingMode;
|
|
48
53
|
/** `<bundle>/pallet-control` of the selected installation. */
|
|
49
54
|
controlExecutable: string;
|
|
50
55
|
workingDirectory: string;
|
|
@@ -128,12 +133,23 @@ export const createPalletContainerdServiceDefinition = (optionsArg: IPalletConta
|
|
|
128
133
|
* it started, and the service manager removes whatever remains of the unit's cgroup when the stop
|
|
129
134
|
* timeout ends, before any successor starts. A failed lifetime is restarted by the service manager,
|
|
130
135
|
* never inside the process.
|
|
136
|
+
*
|
|
137
|
+
* The node keeps its router network namespace in the unit's file descriptor store
|
|
138
|
+
* (`FileDescriptorStoreMax=1`, `FileDescriptorStorePreserve=yes`, `NotifyAccess=all`: the native that
|
|
139
|
+
* owns the namespace, a child of the main process, stores it as `FDNAME=pallet-router`), and the
|
|
140
|
+
* manager hands it back to the next main process through `LISTEN_FDS`, so a restart keeps the
|
|
141
|
+
* workloads' links. A reboot empties the store; an installer releases it
|
|
142
|
+
* (`releasePalletNodeDescriptorStore`) whenever it changes the forwarding mode and on uninstall.
|
|
131
143
|
*/
|
|
132
|
-
export const createPalletNodeServiceDefinition = (optionsArg: IPalletNodeUnitOptions) =>
|
|
144
|
+
export const createPalletNodeServiceDefinition = (optionsArg: IPalletNodeUnitOptions) => {
|
|
145
|
+
if (!isPalletForwardingMode(optionsArg?.forwardingMode)) throw new PalletBundleError('invalid_options');
|
|
146
|
+
return nodeServiceDefinition(optionsArg);
|
|
147
|
+
};
|
|
148
|
+
const nodeServiceDefinition = (optionsArg: IPalletNodeUnitOptions) => definition({
|
|
133
149
|
unitName: optionsArg.unitName,
|
|
134
150
|
description: 'serve.zone Pallet node',
|
|
135
151
|
executable: optionsArg.controlExecutable,
|
|
136
|
-
args: ['runtime-unit'],
|
|
152
|
+
args: ['runtime-unit', palletForwardingModeArgument, optionsArg.forwardingMode],
|
|
137
153
|
workingDirectory: optionsArg.workingDirectory,
|
|
138
154
|
user: 'root',
|
|
139
155
|
group: 'root',
|
|
@@ -141,6 +157,9 @@ export const createPalletNodeServiceDefinition = (optionsArg: IPalletNodeUnitOpt
|
|
|
141
157
|
restartSeconds: 5,
|
|
142
158
|
killMode: 'mixed',
|
|
143
159
|
timeoutStopSeconds: palletNodeStopTimeoutSeconds,
|
|
160
|
+
notifyAccess: 'all',
|
|
161
|
+
fileDescriptorStoreMax: 1,
|
|
162
|
+
fileDescriptorStorePreserve: 'yes',
|
|
144
163
|
dependencies: {
|
|
145
164
|
defaultDependencies: true,
|
|
146
165
|
after: [optionsArg.guardUnitName, optionsArg.containerdUnitName],
|
|
@@ -165,11 +184,53 @@ export const palletContainerdServiceSettingsMatch = (settingsArg: plugins.smartd
|
|
|
165
184
|
settingsArg.timeoutStopMicroseconds >= 45_000_000 && settingsArg.limitNoFile === 'infinity' &&
|
|
166
185
|
settingsArg.limitNoFileSoft === 'infinity' && settingsArg.tasksMax === 'infinity' && settingsArg.oomScoreAdjust === -999;
|
|
167
186
|
|
|
168
|
-
/**
|
|
187
|
+
/**
|
|
188
|
+
* The same reading of the node unit: no restart inside a stop, a stop long enough to join, the
|
|
189
|
+
* router namespace's file descriptor store (`notifyAccess` `all`, one descriptor, preserved), and
|
|
190
|
+
* exactly the command line `createPalletNodeServiceDefinition` renders for `expectedArg` — one
|
|
191
|
+
* `ExecStart`, failure not ignored, whose argument vector is the control executable,
|
|
192
|
+
* `runtime-unit`, `--forwarding-mode` and the stated mode, as the manager loaded it (smartdaemon
|
|
193
|
+
* reads it from the unit's D-Bus `ExecStart`, one string per argument). A unit installed for the
|
|
194
|
+
* other forwarding mode, or with any other command line, does not match.
|
|
195
|
+
*/
|
|
169
196
|
export const palletNodeServiceSettingsMatch = (settingsArg: plugins.smartdaemon.ISystemdServiceSettings,
|
|
170
|
-
unitNameArg: string): boolean =>
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
settingsArg.
|
|
175
|
-
|
|
197
|
+
unitNameArg: string, expectedArg: Pick<IPalletNodeUnitOptions, 'controlExecutable' | 'forwardingMode'>): boolean => {
|
|
198
|
+
if (!isPalletForwardingMode(expectedArg?.forwardingMode) || typeof expectedArg.controlExecutable !== 'string') return false;
|
|
199
|
+
const argv = [expectedArg.controlExecutable, 'runtime-unit', palletForwardingModeArgument, expectedArg.forwardingMode];
|
|
200
|
+
const [command, ...more] = settingsArg.execStart;
|
|
201
|
+
return settingsArg.unitName === unitNameArg && settingsArg.type === 'exec' && settingsArg.killMode === 'mixed' &&
|
|
202
|
+
settingsArg.restart === 'on-failure' && settingsArg.notifyAccess === 'all' &&
|
|
203
|
+
settingsArg.fileDescriptorStoreMax === 1 && settingsArg.fileDescriptorStorePreserve === 'yes' &&
|
|
204
|
+
typeof settingsArg.timeoutStopMicroseconds === 'number' &&
|
|
205
|
+
settingsArg.timeoutStopMicroseconds >= palletNodeStopTimeoutSeconds * 1_000_000 && !settingsArg.delegate &&
|
|
206
|
+
Object.keys(settingsArg.environment).length === 0 &&
|
|
207
|
+
command !== undefined && more.length === 0 && !command.ignoreFailure && command.path === expectedArg.controlExecutable &&
|
|
208
|
+
command.argv.length === argv.length && argv.every((value, index) => command.argv[index] === value);
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Release the node unit's file descriptor store, the kept router namespace, as an installer must
|
|
213
|
+
* whenever it changes the node's forwarding mode and when it uninstalls the node: the stopped unit
|
|
214
|
+
* (`inactive`, without a pending job; a `failed` one needs `reset-failed` first) is cleaned with
|
|
215
|
+
* `systemctl clean --what=fdstore`. Resolves once the manager released the store — also when the
|
|
216
|
+
* inspection after the release failed (`released_uninspected`). A `command_failed` clean may have
|
|
217
|
+
* timed out with the store released or kept, so the unit is inspected: an empty store resolves, a
|
|
218
|
+
* kept one rejects `store_kept` with the clean's failure as the cause, and an inspection that fails
|
|
219
|
+
* too rejects `store_kept` with an `AggregateError` of both, the clean's failure first.
|
|
220
|
+
*/
|
|
221
|
+
export const releasePalletNodeDescriptorStore = async (unitArg: {
|
|
222
|
+
cleanFileDescriptorStore(): Promise<unknown>;
|
|
223
|
+
inspect(): Promise<{ fileDescriptorStoreCount: number }>;
|
|
224
|
+
}): Promise<void> => {
|
|
225
|
+
try { await unitArg.cleanFileDescriptorStore(); }
|
|
226
|
+
catch (error) {
|
|
227
|
+
if (error instanceof plugins.smartdaemon.SystemdUnitError && error.code === 'released_uninspected') return;
|
|
228
|
+
if (!(error instanceof plugins.smartdaemon.SystemdUnitError) || error.code !== 'command_failed') {
|
|
229
|
+
throw new PalletBundleError('store_kept', { cause: error });
|
|
230
|
+
}
|
|
231
|
+
let snapshot: { fileDescriptorStoreCount: number };
|
|
232
|
+
try { snapshot = await unitArg.inspect(); }
|
|
233
|
+
catch (inspection) { throw new PalletBundleError('store_kept', { cause: new AggregateError([error, inspection], 'Pallet node store release unconfirmed') }); }
|
|
234
|
+
if (snapshot.fileDescriptorStoreCount !== 0) throw new PalletBundleError('store_kept', { cause: error });
|
|
235
|
+
}
|
|
236
|
+
};
|