@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.
@@ -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' | 'protocol_invalid' | 'shutdown_failed';
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5jb250cm9scHJvY2Vzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX2J1bmRsZS9jbGFzc2VzLmNvbnRyb2xwcm9jZXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxhQUFhLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDN0QsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDakUsT0FBTyxFQUNMLDBCQUEwQixFQUFFLHVCQUF1QixFQUFFLHlCQUF5QixHQUUvRSxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFtQjNELDhGQUE4RjtBQUM5RixNQUFNLENBQUMsTUFBTSw2QkFBNkIsR0FDeEMsOEdBQThHO0lBQzlHLDhHQUE4RztJQUM5Ryw2QkFBNkIsQ0FBQztBQUVoQyxNQUFNLE9BQU8seUJBQTBCLFNBQVEsS0FBSztJQUN0QjtJQUE1QixZQUE0QixJQUFrQztRQUM1RCxLQUFLLENBQUMsa0NBQWtDLElBQUksSUFBSSxJQUFJLEtBQUssb0JBQW9CLENBQUMsQ0FBQyxDQUFDLElBQUksNkJBQTZCLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQURsRyxTQUFJLEdBQUosSUFBSSxDQUE4QjtRQUU1RCxJQUFJLENBQUMsSUFBSSxHQUFHLDJCQUEyQixDQUFDO0lBQzFDLENBQUM7Q0FDRjtBQUVELE1BQU0sUUFBUSxHQUFvRixJQUFJLEdBQUcsQ0FBQztJQUN4RyxDQUFDLG1CQUFtQixFQUFFLGNBQWMsQ0FBQztJQUNyQyxDQUFDLGtCQUFrQixFQUFFLGtCQUFrQixDQUFDO0lBQ3hDLENBQUMsZUFBZSxFQUFFLGNBQWMsQ0FBQztJQUNqQyxDQUFDLGNBQWMsRUFBRSxjQUFjLENBQUM7SUFDaEMsQ0FBQyxvQkFBb0IsRUFBRSxvQkFBb0IsQ0FBQztDQUM3QyxDQUFDLENBQUM7QUFFSDs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLFNBQWtCLEVBQUUsRUFBRSxDQUN6RCxPQUFPLFNBQVMsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQXVCdEU7Ozs7R0FJRztBQUNILFNBQVMsWUFBWSxDQUFDLFVBSXJCO0lBQ0MsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRTtRQUNqRixHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsRUFBRSxLQUFLLEVBQUUsQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUM7S0FDcEYsQ0FBQyxDQUFDO0lBQ0gsSUFBSSxNQUFNLEdBQUcsS0FBSyxDQUFDO0lBQ25CLElBQUksVUFBVSxHQUFHLEtBQUssQ0FBQztJQUN2QixJQUFJLFdBQVcsR0FBRyxDQUFDLENBQUM7SUFDcEIsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzFDLE1BQU0sSUFBSSxHQUFHLElBQUksT0FBTyxDQUEyRSxDQUFDLE9BQU8sRUFBRSxFQUFFO1FBQzdHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxFQUFFLEdBQUcsTUFBTSxHQUFHLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuRyxLQUFLLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUU7WUFDckIsSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7Z0JBQUMsT0FBTyxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQUMsQ0FBQztRQUN4RyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUFFLFNBQXNELEVBQUUsU0FBa0IsRUFBRSxFQUFFO1FBQ2hHLE1BQU0sT0FBTyxHQUFHLElBQUksV0FBVyxDQUFDLE9BQU8sRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzFELE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3hHLElBQUksT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNqQixJQUFJLENBQUM7WUFDSCxJQUFJLEtBQUssRUFBRSxNQUFNLEtBQUssSUFBSSxTQUFTLEVBQUUsQ0FBQztnQkFDcEMsNERBQTREO2dCQUM1RCxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVE7b0JBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO2dCQUN6RSxJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsSUFBSSxHQUFHLElBQUk7b0JBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO2dCQUNwRSxXQUFXLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQztnQkFDNUIsSUFBSSxVQUFVLENBQUMsa0JBQWtCLEtBQUssSUFBSSxJQUFJLFdBQVcsR0FBRyxVQUFVLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztvQkFDMUYsTUFBTSxJQUFJLEtBQUssQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO2dCQUMvQyxDQUFDO2dCQUNELElBQUksV0FBVyxFQUFFLENBQUM7b0JBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFBQyxTQUFTO2dCQUFDLENBQUM7Z0JBQ3pELE9BQU8sSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUNuRCxLQUFLLElBQUksS0FBSyxFQUFFLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDO29CQUN4RCxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztvQkFDckMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO29CQUNuQyxJQUFJLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSTt3QkFBRSxNQUFNLElBQUksS0FBSyxDQUFDLGlCQUFpQixDQUFDLENBQUM7b0JBQzNELFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQzFCLENBQUM7Z0JBQ0QsSUFBSSxPQUFPLENBQUMsTUFBTSxHQUFHLElBQUk7b0JBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQ2hFLENBQUM7WUFDRCxJQUFJLFNBQVMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDO2dCQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUNsSCxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsVUFBVSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3ZCLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUN0QixDQUFDO2dCQUFTLENBQUM7WUFDVCxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDdkIsQ0FBQztJQUNILENBQUMsQ0FBQztJQUNGLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU8sRUFBRSxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLFVBQVUsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN2SCxvRkFBb0Y7SUFDcEYsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtRQUNsQixNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQzVCLElBQUksVUFBVTtnQkFBRSxPQUFPO1lBQ3ZCLFVBQVUsQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUM1QixLQUFLLENBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxDQUFDO1lBQ3hCLEtBQUssQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLENBQUM7UUFDMUIsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ2xDLEtBQUssTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUM5QyxDQUFDLENBQUMsQ0FBQztJQUNILE9BQU87UUFDTCxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLE1BQU07UUFDbEQsSUFBSSxFQUFFLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztLQUN0RCxDQUFDO0FBQ0osQ0FBQztBQU9ELE1BQU0sU0FBUyxHQUFHLENBQUMsVUFBeUYsRUFDMUcsVUFBNkIsRUFBRSxXQUF3QyxFQUFFLEVBQUU7SUFDM0UsSUFBSSxDQUFDO1FBQ0gsTUFBTSxPQUFPLEdBQUcsQ0FBQyxZQUFZLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxRQUFRLEVBQUUsR0FBRyxVQUFVLEVBQUUsR0FBRyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMzSCxJQUFJLENBQUMsVUFBVSxJQUFJLE9BQU8sVUFBVSxLQUFLLFFBQVEsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDO1lBQzdGLE1BQU0sQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLEtBQUssTUFBTSxDQUFDLFNBQVMsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUMxSCxNQUFNLElBQUksS0FBSyxFQUFFLENBQUM7UUFDcEIsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQztRQUMzQixNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsV0FBVyxJQUFJLENBQUMsQ0FBQztRQUM3QyxJQUFJLE9BQU8sT0FBTyxDQUFDLFlBQVksS0FBSyxRQUFRLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQztZQUMxRixDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLElBQUksV0FBVyxHQUFHLENBQUMsSUFBSSxPQUFPLENBQUMsUUFBUSxLQUFLLE9BQU8sSUFBSSxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsS0FBSyxXQUFXO1lBQzNILENBQUMsT0FBTyxDQUFDLE1BQU0sS0FBSyxTQUFTLElBQUksT0FBTyxPQUFPLENBQUMsTUFBTSxLQUFLLFVBQVUsQ0FBQztZQUFFLE1BQU0sSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUM1RixNQUFNLFFBQVEsR0FBMkIsRUFBRSxDQUFDO1FBQzVDLEtBQUssTUFBTSxDQUFDLEdBQUcsRUFBRSxRQUFRLEVBQUUsT0FBTyxDQUFDLElBQUksV0FBVyxFQUFFLENBQUM7WUFDbkQsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLFFBQVEsQ0FBQztZQUN2QyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxHQUFHLENBQUMsSUFBSSxLQUFLLEdBQUcsT0FBTztnQkFBRSxNQUFNLElBQUksS0FBSyxFQUFFLENBQUM7WUFDakgsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQztRQUN4QixDQUFDO1FBQ0QsT0FBTztZQUNMLFVBQVUsRUFBRSxhQUFhLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFLFlBQVksRUFBRSxPQUFPLENBQUMsWUFBWSxFQUFFLFdBQVc7WUFDOUYsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLE9BQWUsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLFFBQVE7U0FDbEYsQ0FBQztJQUNKLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxNQUFNLElBQUkseUJBQXlCLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDdkQsQ0FBQztBQUNILENBQUMsQ0FBQztBQVFGOzs7OztHQUtHO0FBQ0gsTUFBTSxPQUFPLG9CQUFvQjtJQUNkLE9BQU8sQ0FBK0I7SUFDL0MsSUFBSSxHQUFHLEtBQUssQ0FBQztJQUVyQixZQUFZLFVBQXdDO1FBQ2xELElBQUksQ0FBQyxPQUFPLEdBQUcsU0FBUyxDQUFDLFVBQVUsRUFBRSxFQUFFLEVBQUU7WUFDdkMsQ0FBQyxvQkFBb0IsRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLEVBQUUsQ0FBQyxtQkFBbUIsRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLEVBQUUsQ0FBQyxvQkFBb0IsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDO1NBQ3pILENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTSxHQUFHLENBQUMsT0FBa0MsRUFBRSxTQUFzQjtRQUNuRSxJQUFJLENBQUMsQ0FBQyxTQUFTLFlBQVksV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLHlCQUF5QixFQUFFLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDOUYsT0FBTyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUkseUJBQXlCLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLHlCQUF5QixDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQztRQUN2RixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFTyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQWtDLEVBQUUsU0FBc0I7UUFDOUUsTUFBTSxRQUFRLEdBQUcseUJBQXlCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDcEQsTUFBTSxFQUFFLFFBQVEsRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDbEMsTUFBTSxLQUFLLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQztRQUNwQyxJQUFJLEtBQXlCLENBQUM7UUFDOUIsOEZBQThGO1FBQzlGLCtFQUErRTtRQUMvRSxJQUFJLFFBQWtELENBQUM7UUFDdkQsSUFBSSxPQUFpRCxDQUFDO1FBQ3RELElBQUksY0FBYyxHQUFHLEtBQUssQ0FBQztRQUMzQixJQUFJLFlBQVksR0FBRyxLQUFLLENBQUM7UUFDekIsSUFBSSxRQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLGlGQUFpRjtRQUNqRixNQUFNLFFBQVEsR0FBMEQsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLENBQUM7UUFDN0YsSUFBSSxTQUFvRCxDQUFDO1FBQ3pELElBQUksTUFBNEYsQ0FBQztRQUNqRyxNQUFNLElBQUksR0FBRyxDQUFDLFNBQXdDLEVBQUUsRUFBRTtZQUN4RCxJQUFJLFNBQVMsSUFBSSxDQUFDLENBQUMsT0FBTyxJQUFJLE9BQU8sS0FBSyxXQUFXLENBQUM7Z0JBQUUsT0FBTyxHQUFHLFNBQVMsQ0FBQztZQUM1RSxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDZCxJQUFJLFFBQVE7Z0JBQUUsT0FBTztZQUNyQixRQUFRLEdBQUcsSUFBSSxDQUFDO1lBQ2hCLElBQUksS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUM7Z0JBQzdCLGlGQUFpRjtnQkFDakYsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDdEIsU0FBUyxHQUFHLFVBQVUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLEtBQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO29CQUFFLGNBQWMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFDbkgsQ0FBQztRQUNILENBQUMsQ0FBQztRQUNGLE1BQU0sTUFBTSxHQUFHLENBQUMsU0FBdUMsRUFBRSxFQUFFO1lBQ3pELDJFQUEyRTtZQUMzRSxJQUFJLENBQUMsWUFBWTtnQkFBRSxRQUFRLEtBQUssU0FBUyxDQUFDO1lBQzFDLElBQUksRUFBRSxDQUFDO1FBQ1QsQ0FBQyxDQUFDO1FBQ0YsTUFBTSxPQUFPLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3hDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDN0QsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ3ZGLE1BQU0sSUFBSSxHQUFHLENBQUMsT0FBZSxFQUFFLEVBQUU7WUFDL0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsdUJBQXVCLENBQUM7Z0JBQUUsT0FBTztZQUN6RCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsdUJBQXVCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUN4RSxJQUFJLENBQUMsS0FBSyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssQ0FBQyxRQUFRLEtBQUssUUFBUTtnQkFDNUYsUUFBUSxDQUFDLEtBQUssS0FBSyxTQUFTLElBQUksUUFBUSxDQUFDLEtBQUssS0FBSyxRQUFRO2dCQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQztZQUM1RyxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNqRCxNQUFNLEtBQUssR0FBRyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDakQsSUFBSSxLQUFLLENBQUMsS0FBSyxLQUFLLE9BQU8sSUFBSSxJQUFJLEtBQUssZ0JBQWdCLElBQUksUUFBUSxDQUFDLEtBQUssS0FBSyxTQUFTO2dCQUFFLFFBQVEsQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDO2lCQUM5RyxJQUFJLEtBQUssQ0FBQyxLQUFLLEtBQUssU0FBUyxJQUFJLElBQUksS0FBSyxnQkFBZ0IsSUFBSSxRQUFRLENBQUMsS0FBSyxLQUFLLE9BQU87Z0JBQUUsUUFBUSxDQUFDLEtBQUssR0FBRyxTQUFTLENBQUM7aUJBQ3JILElBQUksS0FBSyxDQUFDLEtBQUssS0FBSyxRQUFRLElBQUksSUFBSSxLQUFLLHVCQUF1QixJQUFJLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDN0YsUUFBUSxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUM7Z0JBQzFCLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNoQixDQUFDOztnQkFBTSxNQUFNLElBQUksS0FBSyxDQUFDLDRCQUE0QixDQUFDLENBQUM7UUFDdkQsQ0FBQyxDQUFDO1FBQ0YsSUFBSSxDQUFDO1lBQ0gsSUFBSSxTQUFTLENBQUMsT0FBTztnQkFBRSxPQUFPLEVBQUUsQ0FBQztZQUNqQyxNQUFNLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNuSCxLQUFLLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQzlCLEtBQUssR0FBRyxZQUFZLENBQUM7Z0JBQ25CLFVBQVUsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTTtnQkFDaEcsa0JBQWtCLEVBQUUsSUFBSSxHQUFHLElBQUksRUFBRSxrQkFBa0IsRUFBRSxRQUFRLENBQUMsa0JBQWtCLEVBQUUsTUFBTSxFQUFFLElBQUk7Z0JBQzlGLFNBQVMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsa0JBQWtCLENBQUM7Z0JBQzNDLGNBQWMsRUFBRSxHQUFHLEVBQUUsR0FBRyxZQUFZLEdBQUcsSUFBSSxDQUFDLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7YUFDdEUsQ0FBQyxDQUFDO1lBQ0gsTUFBTSxHQUFHLE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQztZQUMxQixNQUFNLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFDckIsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDO1FBQ2xFLENBQUM7Z0JBQVMsQ0FBQztZQUNULHVGQUF1RjtZQUN2RixJQUFJLEtBQUssRUFBRSxDQUFDO2dCQUFDLE1BQU0sR0FBRyxNQUFNLEtBQUssQ0FBQyxJQUFJLENBQUM7Z0JBQUMsTUFBTSxLQUFLLENBQUMsTUFBTSxDQUFDO1lBQUMsQ0FBQztZQUM3RCxTQUFTLENBQUMsbUJBQW1CLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ2hELFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNwQixZQUFZLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDMUIsQ0FBQztRQUNELE1BQU0sSUFBSSxHQUFHLFFBQVEsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztZQUNyRSxDQUFDLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDN0QsQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQzFELENBQUMsUUFBUSxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNsRSxJQUFJLElBQUk7WUFBRSxNQUFNLElBQUkseUJBQXlCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdEQsQ0FBQztDQUNGO0FBZUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLE9BQU8scUJBQXFCO0lBQ2YsT0FBTyxDQUErQjtJQUN0QyxJQUFJLENBQTZCO0lBQzFDLElBQUksR0FBRyxLQUFLLENBQUM7SUFDYixTQUFTLEdBQUcsS0FBSyxDQUFDO0lBRTFCLFlBQVksVUFBeUM7UUFDbkQsTUFBTSxJQUFJLEdBQUcsVUFBVSxFQUFFLElBQUksQ0FBQztRQUM5QixJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsMEJBQTBCLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNqRixNQUFNLElBQUkseUJBQXlCLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDdkQsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLElBQUksS0FBSyxlQUFlLENBQUM7UUFDekMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsaUdBQWlHO1FBQ2pHLGlHQUFpRztRQUNqRyx5RkFBeUY7UUFDekYsSUFBSSxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUMsVUFBVSxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDN0MsQ0FBQyxrQkFBa0IsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLDZCQUE2QixHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7WUFDM0csQ0FBQyxtQkFBbUIsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7WUFDN0UsQ0FBQyxvQkFBb0IsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDO1NBQ3RDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxJQUFXLE9BQU87UUFDaEIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQ3hCLENBQUM7SUFFRCxpR0FBaUc7SUFDMUYsR0FBRyxDQUFVLFNBQXNCLEVBQUUsWUFBMEQ7UUFDcEcsSUFBSSxDQUFDLENBQUMsU0FBUyxZQUFZLFdBQVcsQ0FBQyxJQUFJLE9BQU8sWUFBWSxLQUFLLFVBQVUsRUFBRSxDQUFDO1lBQzlFLE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLHlCQUF5QixDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLElBQUk7WUFBRSxPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSx5QkFBeUIsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7UUFDdkYsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRU8sS0FBSyxDQUFDLE9BQU8sQ0FBVSxTQUFzQixFQUFFLFlBQTBEO1FBQy9HLE1BQU0sUUFBUSxHQUFHLDBCQUEwQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2RCxNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUNsQyxNQUFNLEtBQUssR0FBRyxJQUFJLGVBQWUsRUFBRSxDQUFDO1FBQ3BDLElBQUksS0FBeUIsQ0FBQztRQUM5QixJQUFJLFFBQWtELENBQUM7UUFDdkQsSUFBSSxPQUFpRCxDQUFDO1FBQ3RELElBQUksY0FBYyxHQUFHLEtBQUssQ0FBQztRQUMzQixJQUFJLFlBQVksR0FBRyxLQUFLLENBQUM7UUFDekIsSUFBSSxVQUFVLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLElBQUksUUFBUSxHQUFHLEtBQUssQ0FBQztRQUNyQixJQUFJLFNBQVMsR0FBRyxLQUFLLENBQUM7UUFDdEIsSUFBSSxXQUFXLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLElBQUksWUFBWSxHQUFHLEtBQUssQ0FBQztRQUN6QixJQUFJLFNBQW9ELENBQUM7UUFDekQsSUFBSSxTQUFvRCxDQUFDO1FBQ3pELElBQUksWUFBeUIsQ0FBQztRQUM5QixJQUFJLFdBQTJELENBQUM7UUFDaEUsTUFBTSxLQUFLLEdBQUcsSUFBSSxPQUFPLENBQU8sQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUUsR0FBRyxZQUFZLEdBQUcsT0FBTyxDQUFDLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hHLEtBQUssS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNsQyxNQUFNLElBQUksR0FBRyxDQUFDLFNBQXlCLEVBQUUsRUFBRTtZQUN6QyxxRkFBcUY7WUFDckYsSUFBSSxLQUFLLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQztnQkFBRSxjQUFjLEdBQUcsSUFBSSxDQUFDO1FBQ3BELENBQUMsQ0FBQztRQUNGLE1BQU0sSUFBSSxHQUFHLENBQUMsU0FBd0MsRUFBRSxFQUFFO1lBQ3hELGlGQUFpRjtZQUNqRixJQUFJLFNBQVMsSUFBSSxDQUFDLENBQUMsT0FBTyxJQUFJLE9BQU8sS0FBSyxXQUFXLENBQUM7Z0JBQUUsT0FBTyxHQUFHLFNBQVMsQ0FBQztZQUM1RSxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztZQUN2QixLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDZCxXQUFXLENBQUMsSUFBSSx5QkFBeUIsQ0FBQyxPQUFPLElBQUksV0FBVyxDQUFDLENBQUMsQ0FBQztZQUNuRSxJQUFJLFFBQVE7Z0JBQUUsT0FBTztZQUNyQixRQUFRLEdBQUcsSUFBSSxDQUFDO1lBQ2hCLElBQUksS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUM7Z0JBQzdCLHFGQUFxRjtnQkFDckYsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUM7Z0JBQzNCLFNBQVMsR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFO29CQUMxQixJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7b0JBQ2hCLFNBQVMsR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO2dCQUM3RSxDQUFDLEVBQUUsUUFBUSxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFDakMsQ0FBQztRQUNILENBQUMsQ0FBQztRQUNGLE1BQU0sTUFBTSxHQUFHLENBQUMsU0FBdUMsRUFBRSxFQUFFO1lBQ3pELElBQUksQ0FBQyxZQUFZO2dCQUFFLFFBQVEsS0FBSyxTQUFTLENBQUM7WUFDMUMsSUFBSSxFQUFFLENBQUM7UUFDVCxDQUFDLENBQUM7UUFDRixNQUFNLE9BQU8sR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDeEMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUM3RCxNQUFNLFlBQVksR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsUUFBUSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDMUYsTUFBTSxJQUFJLEdBQUcsQ0FBQyxPQUFlLEVBQUUsRUFBRTtZQUMvQixJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyx1QkFBdUIsQ0FBQztnQkFBRSxPQUFPO1lBQ3pELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ3hFLElBQUksQ0FBQyxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksWUFBWSxJQUFJLEtBQUssQ0FBQyxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQy9HLE1BQU0sSUFBSSxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQztZQUMvQyxDQUFDO1lBQ0QsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDakQsTUFBTSxLQUFLLEdBQUcsb0JBQW9CLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ2pELElBQUksS0FBSyxDQUFDLEtBQUssS0FBSyxPQUFPLElBQUksSUFBSSxLQUFLLGdCQUFnQixJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ3ZFLFNBQVMsR0FBRyxJQUFJLENBQUM7Z0JBQ2pCLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEVBQUUsQ0FBQztvQkFBQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztvQkFBQyxZQUFZLEVBQUUsQ0FBQztnQkFBQyxDQUFDO1lBQy9FLENBQUM7aUJBQU0sSUFBSSxLQUFLLENBQUMsS0FBSyxLQUFLLFNBQVMsSUFBSSxJQUFJLEtBQUssZ0JBQWdCLEVBQUUsQ0FBQztnQkFDbEUsV0FBVyxHQUFHLElBQUksQ0FBQztnQkFDbkIsWUFBWSxHQUFHLElBQUksQ0FBQztnQkFDcEIsSUFBSSxDQUFDLFFBQVE7b0JBQUUsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ3hDLENBQUM7aUJBQU0sSUFBSSxLQUFLLENBQUMsS0FBSyxLQUFLLFFBQVEsSUFBSSxJQUFJLEtBQUssdUJBQXVCLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUMvRixZQUFZLEdBQUcsSUFBSSxDQUFDO2dCQUNwQixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDaEIsQ0FBQzs7Z0JBQU0sTUFBTSxJQUFJLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO1FBQ3ZELENBQUMsQ0FBQztRQUNGLElBQUksT0FBZ0QsQ0FBQztRQUNyRCxJQUFJLGVBQWUsR0FBRyxLQUFLLENBQUM7UUFDNUIsSUFBSSxjQUF1QixDQUFDO1FBQzVCLElBQUksQ0FBQztZQUNILElBQUksU0FBUyxDQUFDLE9BQU87Z0JBQUUsT0FBTyxFQUFFLENBQUM7WUFDakMsTUFBTSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDbkgsS0FBSyxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUM5QixLQUFLLEdBQUcsWUFBWSxDQUFDO2dCQUNuQixVQUFVLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNO2dCQUNoRyxzR0FBc0c7Z0JBQ3RHLGtCQUFrQixFQUFFLElBQUksQ0FBQyxJQUFJLEtBQUssZUFBZSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxJQUFJO2dCQUN0RSxrQkFBa0IsRUFBRSxRQUFRLENBQUMsa0JBQWtCLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDO2dCQUMxRyxjQUFjLEVBQUUsR0FBRyxFQUFFLEdBQUcsWUFBWSxHQUFHLElBQUksQ0FBQyxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO2FBQ3RFLENBQUMsQ0FBQztZQUNILEtBQUssS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtnQkFDOUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7Z0JBQ3ZCLHlFQUF5RTtnQkFDekUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPO29CQUFFLE9BQU8sS0FBSyxtQkFBbUIsQ0FBQztxQkFDaEQsSUFBSSxDQUFDLFFBQVEsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUM7b0JBQUUsVUFBVSxHQUFHLElBQUksQ0FBQztnQkFDM0QsSUFBSSxFQUFFLENBQUM7WUFDVCxDQUFDLENBQUMsQ0FBQztZQUNILE1BQU0sS0FBSyxDQUFDO1lBQ1osWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzNCLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUztnQkFBRSxNQUFNLElBQUkseUJBQXlCLENBQUMsT0FBTyxJQUFJLGNBQWMsQ0FBQyxDQUFDO1lBQzVHLElBQUksQ0FBQztnQkFBQyxPQUFPLEdBQUcsRUFBRSxLQUFLLEVBQUUsTUFBTSxZQUFZLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFBQyxDQUFDO1lBQzlELE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztnQkFBQyxjQUFjLEdBQUcsS0FBSyxDQUFDO1lBQUMsQ0FBQztRQUNuRSxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLDBGQUEwRjtZQUMxRixJQUFJLENBQUMsQ0FBQyxLQUFLLFlBQVkseUJBQXlCLENBQUM7Z0JBQUUsT0FBTyxLQUFLLG1CQUFtQixDQUFDO1FBQ3JGLENBQUM7Z0JBQVMsQ0FBQztZQUNULFlBQVksQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUMzQixJQUFJLEVBQUUsQ0FBQztZQUNQLHdGQUF3RjtZQUN4RixJQUFJLEtBQUssRUFBRSxDQUFDO2dCQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQztnQkFBQyxNQUFNLEtBQUssQ0FBQyxNQUFNLENBQUM7WUFBQyxDQUFDO1lBQ3BELFNBQVMsQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDaEQsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ3hCLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMxQixDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsS0FBSyxLQUFLLFNBQVMsSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUNsRSxNQUFNLElBQUksR0FBRyxRQUFRLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDdkUsQ0FBQyxPQUFPLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUM1RixpRUFBaUU7WUFDakUsQ0FBQyxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMxRCxJQUFJLElBQUk7WUFBRSxNQUFNLElBQUkseUJBQXlCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDcEQsSUFBSSxlQUFlO1lBQUUsTUFBTSxjQUFjLENBQUM7UUFDMUMscUZBQXFGO1FBQ3JGLElBQUksQ0FBQyxPQUFPO1lBQUUsTUFBTSxJQUFJLHlCQUF5QixDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2xFLE9BQU8sT0FBTyxDQUFDLEtBQUssQ0FBQztJQUN2QixDQUFDO0NBQ0YifQ==
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
  /**
@@ -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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfYnVuZGxlL2Vycm9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUF1QkEsTUFBTSxPQUFPLGlCQUFrQixTQUFRLEtBQUs7SUFPZDtJQU41Qjs7O09BR0c7SUFDYSxhQUFhLENBQXFCO0lBRWxELFlBQTRCLElBQTRCLEVBQUUsYUFBcUUsRUFBRTtRQUMvSCxLQUFLLENBQUMsa0NBQWtDLElBQUksR0FBRyxFQUFFLFVBQVUsQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBRGpHLFNBQUksR0FBSixJQUFJLENBQXdCO1FBRXRELElBQUksQ0FBQyxJQUFJLEdBQUcsbUJBQW1CLENBQUM7UUFDaEMsSUFBSSxVQUFVLENBQUMsYUFBYTtZQUFFLElBQUksQ0FBQyxhQUFhLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7SUFDbEcsQ0FBQztDQUNGO0FBRUQsTUFBTSxVQUFVLGFBQWEsQ0FBQyxRQUFpQixFQUFFLE9BQStCO0lBQzlFLElBQUksQ0FBQyxRQUFRO1FBQUUsTUFBTSxJQUFJLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3RELENBQUMifQ==
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
- /** The reasons a `failed` line names. */
47
- export declare const palletControlFailureReasons: readonly ["invalid_arguments", "invalid_ca_store", "invalid_stdin", "owner_failed", "unsupported_kernel"];
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
- /** The reasons a `failed` line names. */
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdG9jb2wuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c19idW5kbGUvcHJvdG9jb2wudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O0dBS0c7QUFFSCx1RkFBdUY7QUFDdkYsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsaUJBQWlCLENBQUM7QUFFekQsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUNsRCxVQUFVLEVBQUUsMkJBQTJCO0lBQ3ZDLElBQUksRUFBRSxxQkFBcUI7SUFDM0IsS0FBSyxFQUFFLHNCQUFzQjtJQUM3QixXQUFXLEVBQUUsNEJBQTRCO0lBQ3pDLFVBQVUsRUFBRSwyQkFBMkI7SUFDdkMsYUFBYSxFQUFFLHVCQUF1QjtJQUN0QyxjQUFjLEVBQUUsd0JBQXdCO0NBQ2hDLENBQUMsQ0FBQztBQUVaOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLDBCQUEwQixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDdEQsa0JBQWtCLEVBQUUsc0JBQXNCLENBQUMsVUFBVTtJQUNyRCxzQkFBc0IsRUFBRSxzQkFBc0IsQ0FBQyxVQUFVO0lBQ3pELGVBQWUsRUFBRSxzQkFBc0IsQ0FBQyxJQUFJO0NBQ3BDLENBQUMsQ0FBQztBQUdaLDhGQUE4RjtBQUM5RixNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ3JELGVBQWUsRUFBRSxzQkFBc0IsQ0FBQyxLQUFLO0lBQzdDLGtCQUFrQixFQUFFLHNCQUFzQixDQUFDLEtBQUs7SUFDaEQsaUJBQWlCLEVBQUUsc0JBQXNCLENBQUMsV0FBVztJQUNyRCx1QkFBdUIsRUFBRSxzQkFBc0IsQ0FBQyxXQUFXO0lBQzNELGlCQUFpQixFQUFFLHNCQUFzQixDQUFDLGNBQWM7Q0FDaEQsQ0FBQyxDQUFDO0FBR1o7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUNsRCxrQkFBa0IsRUFBRSxzQkFBc0IsQ0FBQyxVQUFVO0lBQ3JELGNBQWMsRUFBRSxzQkFBc0IsQ0FBQyxJQUFJO0NBQ25DLENBQUMsQ0FBQztBQUdaLHlDQUF5QztBQUN6QyxNQUFNLENBQUMsTUFBTSwyQkFBMkIsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ3ZELG1CQUFtQixFQUFFLGtCQUFrQixFQUFFLGVBQWUsRUFBRSxjQUFjLEVBQUUsb0JBQW9CO0NBQ3RGLENBQUMsQ0FBQyJ9
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
- /** The same reading of the node unit: no restart inside a stop, and a stop long enough to join. */
76
- export declare const palletNodeServiceSettingsMatch: (settingsArg: plugins.smartdaemon.ISystemdServiceSettings, unitNameArg: string) => boolean;
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>;
@@ -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) => definition({
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
- /** The same reading of the node unit: no restart inside a stop, and a stop long enough to join. */
132
- export const palletNodeServiceSettingsMatch = (settingsArg, unitNameArg) => settingsArg.unitName === unitNameArg && settingsArg.type === 'exec' && settingsArg.killMode === 'mixed' &&
133
- settingsArg.restart === 'on-failure' &&
134
- typeof settingsArg.timeoutStopMicroseconds === 'number' &&
135
- settingsArg.timeoutStopMicroseconds >= palletNodeStopTimeoutSeconds * 1_000_000 && !settingsArg.delegate &&
136
- Object.keys(settingsArg.environment).length === 0;
137
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5pdHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c19idW5kbGUvdW5pdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRWhEOzs7O0dBSUc7QUFFSCx3RkFBd0Y7QUFDeEYsTUFBTSxDQUFDLE1BQU0sOEJBQThCLEdBQUcsMEJBQTBCLENBQUM7QUFFekUscUdBQXFHO0FBQ3JHLE1BQU0sQ0FBQyxNQUFNLDRCQUE0QixHQUFHLEdBQUcsQ0FBQztBQUVoRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxDQUFDLE1BQU0sNkJBQTZCLEdBQUcsR0FBRyxDQUFDO0FBK0JqRCxNQUFNLFVBQVUsR0FBRyxDQUFDLFVBQWdFLEVBQUUsRUFBRTtJQUN0RixJQUFJLENBQUM7UUFBQyxPQUFPLElBQUksT0FBTyxDQUFDLFdBQVcsQ0FBQyx3QkFBd0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUFDLENBQUM7SUFDNUUsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUFDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQUMsQ0FBQztBQUNyRixDQUFDLENBQUM7QUFFRjs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sa0NBQWtDLEdBQUcsQ0FBQyxVQUFtQyxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUM7SUFDcEcsUUFBUSxFQUFFLFVBQVUsQ0FBQyxRQUFRO0lBQzdCLFdBQVcsRUFBRSwyQ0FBMkM7SUFDeEQsVUFBVSxFQUFFLFVBQVUsQ0FBQyxVQUFVO0lBQ2pDLElBQUksRUFBRSxDQUFDLGVBQWUsQ0FBQztJQUN2QixnQkFBZ0IsRUFBRSxVQUFVLENBQUMsZ0JBQWdCO0lBQzdDLElBQUksRUFBRSxNQUFNO0lBQ1osS0FBSyxFQUFFLE1BQU07SUFDYixPQUFPLEVBQUUsSUFBSTtJQUNiLFFBQVEsRUFBRSxPQUFPO0lBQ2pCLGtCQUFrQixFQUFFLEdBQUc7SUFDdkIsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLG1CQUFtQixFQUFFLEdBQUcsRUFBRTtJQUM3RSxZQUFZLEVBQUU7UUFDWixtQkFBbUIsRUFBRSxLQUFLO1FBQzFCLEtBQUssRUFBRSxFQUFFO1FBQ1QsTUFBTSxFQUFFLENBQUMsb0JBQW9CLEVBQUUsOEJBQThCLEVBQUUsaUJBQWlCLENBQUM7UUFDakYsUUFBUSxFQUFFLEVBQUU7UUFDWixLQUFLLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQztRQUM3QixTQUFTLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQztLQUMvQjtJQUNELE9BQU8sRUFBRSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsVUFBVSxFQUFFLENBQUMsb0JBQW9CLEVBQUUsOEJBQThCLENBQUMsRUFBRTtDQUM5RixDQUFDLENBQUM7QUFFSDs7Ozs7O0dBTUc7QUFDSCxNQUFNLENBQUMsTUFBTSx1Q0FBdUMsR0FBRyxDQUFDLFVBQXdDLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQztJQUM5RyxRQUFRLEVBQUUsVUFBVSxDQUFDLFFBQVE7SUFDN0IsV0FBVyxFQUFFLDhCQUE4QjtJQUMzQyxVQUFVLEVBQUUsVUFBVSxDQUFDLGlCQUFpQjtJQUN4QyxJQUFJLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQztJQUMxQixnQkFBZ0IsRUFBRSxVQUFVLENBQUMsZ0JBQWdCO0lBQzdDLElBQUksRUFBRSxNQUFNO0lBQ1osS0FBSyxFQUFFLE1BQU07SUFDYixPQUFPLEVBQUUsUUFBUTtJQUNqQixjQUFjLEVBQUUsQ0FBQztJQUNqQixRQUFRLEVBQUUsU0FBUztJQUNuQix1RkFBdUY7SUFDdkYsa0JBQWtCLEVBQUUsRUFBRTtJQUN0QixxRkFBcUY7SUFDckYsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLG1CQUFtQixFQUFFLEdBQUcsRUFBRTtJQUMxRSxRQUFRLEVBQUUsSUFBSTtJQUNkLFdBQVcsRUFBRSxVQUFVO0lBQ3ZCLFFBQVEsRUFBRSxVQUFVO0lBQ3BCLGNBQWMsRUFBRSxDQUFDLEdBQUc7SUFDcEIsWUFBWSxFQUFFO1FBQ1osbUJBQW1CLEVBQUUsSUFBSTtRQUN6QixLQUFLLEVBQUUsQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDO1FBQ2pDLE1BQU0sRUFBRSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUM7UUFDakMsUUFBUSxFQUFFLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQztRQUNwQyxLQUFLLEVBQUUsRUFBRTtRQUNULFNBQVMsRUFBRSxFQUFFO0tBQ2Q7Q0FDRixDQUFDLENBQUM7QUFFSDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxDQUFDLE1BQU0saUNBQWlDLEdBQUcsQ0FBQyxVQUFrQyxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUM7SUFDbEcsUUFBUSxFQUFFLFVBQVUsQ0FBQyxRQUFRO0lBQzdCLFdBQVcsRUFBRSx3QkFBd0I7SUFDckMsVUFBVSxFQUFFLFVBQVUsQ0FBQyxpQkFBaUI7SUFDeEMsSUFBSSxFQUFFLENBQUMsY0FBYyxDQUFDO0lBQ3RCLGdCQUFnQixFQUFFLFVBQVUsQ0FBQyxnQkFBZ0I7SUFDN0MsSUFBSSxFQUFFLE1BQU07SUFDWixLQUFLLEVBQUUsTUFBTTtJQUNiLE9BQU8sRUFBRSxZQUFZO0lBQ3JCLGNBQWMsRUFBRSxDQUFDO0lBQ2pCLFFBQVEsRUFBRSxPQUFPO0lBQ2pCLGtCQUFrQixFQUFFLDRCQUE0QjtJQUNoRCxZQUFZLEVBQUU7UUFDWixtQkFBbUIsRUFBRSxJQUFJO1FBQ3pCLEtBQUssRUFBRSxDQUFDLFVBQVUsQ0FBQyxhQUFhLEVBQUUsVUFBVSxDQUFDLGtCQUFrQixDQUFDO1FBQ2hFLE1BQU0sRUFBRSxFQUFFO1FBQ1YsUUFBUSxFQUFFLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQztRQUNwQyxLQUFLLEVBQUUsQ0FBQyxVQUFVLENBQUMsa0JBQWtCLENBQUM7UUFDdEMsU0FBUyxFQUFFLEVBQUU7S0FDZDtDQUNGLENBQUMsQ0FBQztBQUVIOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxvQ0FBb0MsR0FBRyxDQUFDLFdBQXdELEVBQzNHLFdBQW1CLEVBQVcsRUFBRSxDQUNoQyxXQUFXLENBQUMsUUFBUSxLQUFLLFdBQVcsSUFBSSxXQUFXLENBQUMsSUFBSSxLQUFLLFFBQVEsSUFBSSxXQUFXLENBQUMsWUFBWSxLQUFLLEtBQUs7SUFDM0csV0FBVyxDQUFDLE9BQU8sS0FBSyxRQUFRLElBQUksT0FBTyxXQUFXLENBQUMsbUJBQW1CLEtBQUssUUFBUTtJQUN2RixXQUFXLENBQUMsbUJBQW1CLEdBQUcsQ0FBQyxJQUFJLFdBQVcsQ0FBQyxtQkFBbUIsSUFBSSxVQUFVLElBQUksV0FBVyxDQUFDLFFBQVEsS0FBSyxTQUFTO0lBQzFILFdBQVcsQ0FBQyxRQUFRLElBQUksT0FBTyxXQUFXLENBQUMsdUJBQXVCLEtBQUssUUFBUTtJQUMvRSxXQUFXLENBQUMsdUJBQXVCLElBQUksVUFBVSxJQUFJLFdBQVcsQ0FBQyxXQUFXLEtBQUssVUFBVTtJQUMzRixXQUFXLENBQUMsZUFBZSxLQUFLLFVBQVUsSUFBSSxXQUFXLENBQUMsUUFBUSxLQUFLLFVBQVUsSUFBSSxXQUFXLENBQUMsY0FBYyxLQUFLLENBQUMsR0FBRyxDQUFDO0FBRTNILG1HQUFtRztBQUNuRyxNQUFNLENBQUMsTUFBTSw4QkFBOEIsR0FBRyxDQUFDLFdBQXdELEVBQ3JHLFdBQW1CLEVBQVcsRUFBRSxDQUNoQyxXQUFXLENBQUMsUUFBUSxLQUFLLFdBQVcsSUFBSSxXQUFXLENBQUMsSUFBSSxLQUFLLE1BQU0sSUFBSSxXQUFXLENBQUMsUUFBUSxLQUFLLE9BQU87SUFDdkcsV0FBVyxDQUFDLE9BQU8sS0FBSyxZQUFZO0lBQ3BDLE9BQU8sV0FBVyxDQUFDLHVCQUF1QixLQUFLLFFBQVE7SUFDdkQsV0FBVyxDQUFDLHVCQUF1QixJQUFJLDRCQUE0QixHQUFHLFNBQVMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRO0lBQ3hHLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMifQ==
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": "35.4.2",
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.14.0",
27
- "@serve.zone/interfaces": "32.38.0"
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`, the node lifetime as a unit's main process: null stdin, stopped
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` reads it back. `palletNodeStopTimeoutSeconds`
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'),
@@ -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
  /**
@@ -49,8 +49,43 @@ export const palletControlUnitModes = Object.freeze({
49
49
  } as const);
50
50
  export type TPalletControlUnitMode = keyof typeof palletControlUnitModes;
51
51
 
52
- /** The reasons a `failed` line names. */
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];
@@ -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`, the node lifetime as a unit's main process: null stdin, stopped
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` reads it back. `palletNodeStopTimeoutSeconds`
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
@@ -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) => definition({
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
- /** The same reading of the node unit: no restart inside a stop, and a stop long enough to join. */
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
- settingsArg.unitName === unitNameArg && settingsArg.type === 'exec' && settingsArg.killMode === 'mixed' &&
172
- settingsArg.restart === 'on-failure' &&
173
- typeof settingsArg.timeoutStopMicroseconds === 'number' &&
174
- settingsArg.timeoutStopMicroseconds >= palletNodeStopTimeoutSeconds * 1_000_000 && !settingsArg.delegate &&
175
- Object.keys(settingsArg.environment).length === 0;
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
+ };