@serve.zone/pallet-bundle 35.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_ts_bundle/classes.controlprocess.d.ts +71 -0
- package/dist_ts_bundle/classes.controlprocess.js +441 -0
- package/dist_ts_bundle/classes.controlstderr.d.ts +36 -0
- package/dist_ts_bundle/classes.controlstderr.js +95 -0
- package/dist_ts_bundle/classes.releaseclient.d.ts +38 -0
- package/dist_ts_bundle/classes.releaseclient.js +285 -0
- package/dist_ts_bundle/errors.d.ts +35 -0
- package/dist_ts_bundle/errors.js +20 -0
- package/dist_ts_bundle/index.d.ts +10 -0
- package/dist_ts_bundle/index.js +11 -0
- package/dist_ts_bundle/inventory.d.ts +90 -0
- package/dist_ts_bundle/inventory.js +78 -0
- package/dist_ts_bundle/paths.d.ts +12 -0
- package/dist_ts_bundle/paths.js +76 -0
- package/dist_ts_bundle/plugins.d.ts +14 -0
- package/dist_ts_bundle/plugins.js +19 -0
- package/dist_ts_bundle/protocol.d.ts +48 -0
- package/dist_ts_bundle/protocol.js +47 -0
- package/dist_ts_bundle/units.d.ts +67 -0
- package/dist_ts_bundle/units.js +128 -0
- package/dist_ts_bundle/verify.d.ts +75 -0
- package/dist_ts_bundle/verify.js +263 -0
- package/dist_ts_bundle/version.d.ts +7 -0
- package/dist_ts_bundle/version.js +17 -0
- package/license.md +21 -0
- package/package.json +35 -0
- package/readme.md +176 -0
- package/ts_bundle/classes.controlprocess.ts +453 -0
- package/ts_bundle/classes.controlstderr.ts +92 -0
- package/ts_bundle/classes.releaseclient.ts +288 -0
- package/ts_bundle/errors.ts +40 -0
- package/ts_bundle/index.ts +10 -0
- package/ts_bundle/inventory.ts +104 -0
- package/ts_bundle/paths.ts +74 -0
- package/ts_bundle/plugins.ts +25 -0
- package/ts_bundle/protocol.ts +56 -0
- package/ts_bundle/readme.md +176 -0
- package/ts_bundle/units.ts +165 -0
- package/ts_bundle/verify.ts +353 -0
- package/ts_bundle/version.ts +18 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# @serve.zone/pallet-bundle
|
|
2
|
+
|
|
3
|
+
The install surface of Pallet's sealed control bundle, released from Pallet's repository with
|
|
4
|
+
Pallet's own version. An installer — Spark on fleet nodes, Onebox on its own host — uses it to
|
|
5
|
+
|
|
6
|
+
- download a pinned Pallet release and verify it with tspack,
|
|
7
|
+
- verify the extracted bundle: its control record, every executable's role and build provenance, the
|
|
8
|
+
component manifests and the notice and source inventories,
|
|
9
|
+
- write the service units Pallet's "Service unit contract" states, and read them back from the
|
|
10
|
+
service manager,
|
|
11
|
+
- run and supervise `pallet-control` modes over its `PALLET_CONTROL` process protocol.
|
|
12
|
+
|
|
13
|
+
Pallet is the source of truth for all of it. Pallet's own packaging runs this package's verifier over
|
|
14
|
+
every bundle it seals, so a release never disagrees with the version of this package that carries
|
|
15
|
+
the same version number.
|
|
16
|
+
|
|
17
|
+
## Issue Reporting and Security
|
|
18
|
+
|
|
19
|
+
For reporting bugs, issues, or security vulnerabilities, please visit
|
|
20
|
+
[community.foss.global/](https://community.foss.global/). This is the central community hub for all
|
|
21
|
+
issue reporting. Developers who sign and comply with our contribution agreement and go through
|
|
22
|
+
identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull
|
|
23
|
+
Requests directly.
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
pnpm install @serve.zone/pallet-bundle
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The package runs under Node.js and Deno; it uses `node:` APIs and the global `fetch` only.
|
|
32
|
+
|
|
33
|
+
It reads its own version at runtime from the `package.json` beside its compiled modules
|
|
34
|
+
(`version.ts`, resolved relative to `import.meta.url`). Consume it as an npm dependency and do not
|
|
35
|
+
bundle it into another file: a bundler that inlines the modules loses that manifest, and
|
|
36
|
+
`palletBundleVersion` and every call that takes a pin (the release client and the verifiers) then fail. `deno compile`
|
|
37
|
+
keeps it: a compiled binary embeds each npm package it
|
|
38
|
+
uses with its `package.json`, whether the dependency comes from a `node_modules` directory
|
|
39
|
+
installed by pnpm or from Deno's own `nodeModulesDir: "auto"` install.
|
|
40
|
+
|
|
41
|
+
## Pins
|
|
42
|
+
|
|
43
|
+
A release is selected only by its pin, the values a consumer compiles in:
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import type { IPalletBundlePin } from '@serve.zone/pallet-bundle';
|
|
47
|
+
|
|
48
|
+
const pin: IPalletBundlePin = {
|
|
49
|
+
version: '35.3.0',
|
|
50
|
+
sourceCommit: '<the 40-hex commit of the v35.3.0 tag>',
|
|
51
|
+
manifestSha256: '<SHA-256 of that release\'s tspack-manifest.json>',
|
|
52
|
+
};
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Every entry point refuses a pin whose `version` differs from this package's own version
|
|
56
|
+
(`version_mismatch`): the inventory and contracts it states belong to that one Pallet version.
|
|
57
|
+
Upgrade the package and the pin together.
|
|
58
|
+
|
|
59
|
+
## Download, extract and verify
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { PalletReleaseClient, extractPalletControlBundle } from '@serve.zone/pallet-bundle';
|
|
63
|
+
|
|
64
|
+
const client = new PalletReleaseClient();
|
|
65
|
+
const bundle = await client.run(pin, 'linux-amd64', '/opt/onebox/pallet', (download) =>
|
|
66
|
+
extractPalletControlBundle(download, 'linux-amd64', '/opt/onebox/pallet', pin, signal), signal);
|
|
67
|
+
// bundle.directory is a fresh private directory below /opt/onebox/pallet; the caller owns it.
|
|
68
|
+
console.log(bundle.executables.control.path, bundle.executables.control.sha256);
|
|
69
|
+
console.log(bundle.containerdManifestSha256, bundle.provenance.store.projectVersion);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`PalletReleaseClient.run` resolves the release `v<version>` of `serve.zone/pallet` on
|
|
73
|
+
`https://code.foss.global`, requires its tag to name the pinned commit, verifies the release metadata
|
|
74
|
+
against the pinned manifest digest (tspack `verifyMetadata`), downloads the manifest, the checksums
|
|
75
|
+
and the target's archive into a private directory below the given parent, verifies the archive
|
|
76
|
+
(tspack `verifyBundle`) and hands the directory to the callback. It removes the download directory
|
|
77
|
+
when the callback settles. A release that exists without all of its assets answers
|
|
78
|
+
`release_pending` with the missing asset names.
|
|
79
|
+
|
|
80
|
+
`extractPalletControlBundle` extracts the target's archive with tspack `extractBundle`, then runs
|
|
81
|
+
`verifyPalletControlBundle` over it and removes the extraction again if that fails. For a bundle
|
|
82
|
+
that is already extracted, call `verifyPalletControlBundle(directory, sealedFiles, pin, target)`
|
|
83
|
+
with the file records of the pinned manifest.
|
|
84
|
+
|
|
85
|
+
The verifier checks, against the sealed records of the bundle's files:
|
|
86
|
+
|
|
87
|
+
- `control-build.json`: exactly its keys, Pallet's package name, the pinned version and commit, a
|
|
88
|
+
clean source, the target and the fixed host paths; every file it declares carries the sealed
|
|
89
|
+
digest and size, and every executable in the bundle is one it declares;
|
|
90
|
+
- the executables `pallet-control` starts by name (`pallet-control`, `pallet-smartdb`,
|
|
91
|
+
`pallet-runtime`, `pallet-guard`, `pallet-dns`, `pallet-vpn`) and their tsrust provenance: the
|
|
92
|
+
sealed digest, the owning project and binary, the target, a clean build, and for `pallet-runtime`
|
|
93
|
+
the pinned version and commit;
|
|
94
|
+
- the clock and containerd manifests, which list every file below their directories with digest,
|
|
95
|
+
size and mode, and the digests the control record pins for them and for the DNS and VPN notices;
|
|
96
|
+
- the notice trees (`native-notices/`, `notices/smartnftables/`) and the clock and containerd notice
|
|
97
|
+
and corresponding-source inventories: each manifest names exactly the files below it.
|
|
98
|
+
|
|
99
|
+
Refusals are `PalletBundleError` values with a fixed `code`; see `TPalletBundleErrorCode`.
|
|
100
|
+
|
|
101
|
+
## Service units
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { SystemdUnit, SystemdUnitFile } from '@push.rocks/smartdaemon';
|
|
105
|
+
import {
|
|
106
|
+
createPalletGuardServiceDefinition, createPalletContainerdServiceDefinition,
|
|
107
|
+
createPalletNodeServiceDefinition, palletContainerdServiceSettingsMatch,
|
|
108
|
+
} from '@serve.zone/pallet-bundle';
|
|
109
|
+
|
|
110
|
+
const control = '/opt/onebox/pallet/current/pallet-control';
|
|
111
|
+
const guard = createPalletGuardServiceDefinition({ unitName: 'onebox-pallet-guard.service',
|
|
112
|
+
executable: control, workingDirectory: '/opt/onebox/pallet' });
|
|
113
|
+
const containerd = createPalletContainerdServiceDefinition({ unitName: 'onebox-pallet-containerd.service',
|
|
114
|
+
controlExecutable: control, workingDirectory: '/opt/onebox/pallet',
|
|
115
|
+
guardUnitName: guard.unitName, nodeUnitName: 'onebox-pallet-node.service' });
|
|
116
|
+
const node = createPalletNodeServiceDefinition({ unitName: 'onebox-pallet-node.service',
|
|
117
|
+
controlExecutable: control, workingDirectory: '/opt/onebox/pallet',
|
|
118
|
+
guardUnitName: guard.unitName, containerdUnitName: containerd.unitName });
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The definitions are `SystemdServiceDefinition` values of `@push.rocks/smartdaemon`; install them
|
|
122
|
+
with its `SystemdUnitFile`. The unit names and the install root are the installer's.
|
|
123
|
+
|
|
124
|
+
- The guard unit is a oneshot that runs `guard-recover` before `network-pre.target` and
|
|
125
|
+
`systemd-networkd.service`, which both require it. Install it only after the first
|
|
126
|
+
`guard-commission`. Its executable is `pallet-control` or an installer's own executable that
|
|
127
|
+
verifies the installation before it starts that mode.
|
|
128
|
+
- The containerd unit runs `containerd-serve` to the contract in Pallet's readme ("Pallet's own
|
|
129
|
+
containerd"). `palletContainerdServiceSettingsMatch` reads the loaded unit's settings, drop-ins
|
|
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
|
|
132
|
+
by SIGTERM, `KillMode=mixed`, restarted on failure by the service manager, after the guard and
|
|
133
|
+
containerd units. `palletNodeServiceSettingsMatch` reads it back.
|
|
134
|
+
|
|
135
|
+
## Process supervisors
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
import { PalletControlOneshot, PalletControlLifetime } from '@serve.zone/pallet-bundle';
|
|
139
|
+
|
|
140
|
+
// A null-stdin oneshot: guard-recover, guard-commission, network-acquire, network-acquire-local, store-provision.
|
|
141
|
+
await new PalletControlOneshot({ binaryPath: control, binarySha256: bundle.executables.control.sha256 })
|
|
142
|
+
.run('store-provision', signal);
|
|
143
|
+
|
|
144
|
+
// A supervised lifetime held by a stdin pipe: enrollment-serve, enrollment-provision, runtime-serve.
|
|
145
|
+
const lifetime = new PalletControlLifetime({ binaryPath: control, binarySha256, mode: 'enrollment-serve' });
|
|
146
|
+
await lifetime.run(signal, async (running) => { /* talk to the enrollment socket */ });
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Both verify the executable's digest before every start, start it with a clean environment and `/`
|
|
150
|
+
as its working directory, read the `PALLET_CONTROL` lines of the mode's protocol and forward its
|
|
151
|
+
standard error line by line, bounded (`PalletControlStderr`). They never restart a child. A oneshot
|
|
152
|
+
succeeds only on `ready`, `stopped`, drained pipes and exit status 0. A lifetime runs the operation
|
|
153
|
+
while the child is `ready`; closing its stdin is the graceful stop, and a missed shutdown deadline
|
|
154
|
+
signals SIGTERM and then SIGKILL, which fails the lifetime as `shutdown_failed`. Refusals are
|
|
155
|
+
`PalletControlProcessError` values; `unsupported_kernel` carries the operator's remedy.
|
|
156
|
+
|
|
157
|
+
## License and Legal Information
|
|
158
|
+
|
|
159
|
+
This repository contains open-source code licensed under the MIT License. A copy of the license is included in this package as `license.md`.
|
|
160
|
+
|
|
161
|
+
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
|
|
162
|
+
|
|
163
|
+
### Trademarks
|
|
164
|
+
|
|
165
|
+
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.
|
|
166
|
+
|
|
167
|
+
Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
|
|
168
|
+
|
|
169
|
+
### Company Information
|
|
170
|
+
|
|
171
|
+
Task Venture Capital GmbH<br>
|
|
172
|
+
Registered at District Court Bremen HRB 35230 HB, Germany
|
|
173
|
+
|
|
174
|
+
For any legal inquiries or further information, please contact us via email at hello@task.vc.
|
|
175
|
+
|
|
176
|
+
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import { PalletBundleError } from './errors.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The service units an installer writes for Pallet, to the "Service unit contract" in Pallet's readme.
|
|
6
|
+
* Pallet never writes a unit file itself: Spark on fleet nodes and Onebox on its own host install
|
|
7
|
+
* these definitions under their own unit names and install roots.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** The one network provider the guard's supported host profile orders itself before. */
|
|
11
|
+
export const palletGuardNetworkProviderName = 'systemd-networkd.service';
|
|
12
|
+
|
|
13
|
+
/** How long a stop of the node may take: a five-minute native operation, then the database joins. */
|
|
14
|
+
export const palletNodeStopTimeoutSeconds = 360;
|
|
15
|
+
|
|
16
|
+
export interface IPalletGuardUnitOptions {
|
|
17
|
+
unitName: string;
|
|
18
|
+
/**
|
|
19
|
+
* The boot command's executable. It runs `guard-recover`: `pallet-control` itself, or an
|
|
20
|
+
* installer's own executable that verifies the installed bundle before it starts that mode.
|
|
21
|
+
*/
|
|
22
|
+
executable: string;
|
|
23
|
+
workingDirectory: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface IPalletContainerdUnitOptions {
|
|
27
|
+
unitName: string;
|
|
28
|
+
/** `<bundle>/pallet-control` of the selected installation. */
|
|
29
|
+
controlExecutable: string;
|
|
30
|
+
workingDirectory: string;
|
|
31
|
+
guardUnitName: string;
|
|
32
|
+
/** The node unit, the only CRI client, which this unit starts before. */
|
|
33
|
+
nodeUnitName: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface IPalletNodeUnitOptions {
|
|
37
|
+
unitName: string;
|
|
38
|
+
/** `<bundle>/pallet-control` of the selected installation. */
|
|
39
|
+
controlExecutable: string;
|
|
40
|
+
workingDirectory: string;
|
|
41
|
+
guardUnitName: string;
|
|
42
|
+
containerdUnitName: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const definition = (optionsArg: plugins.smartdaemon.ISystemdServiceDefinitionOptions) => {
|
|
46
|
+
try { return new plugins.smartdaemon.SystemdServiceDefinition(optionsArg); }
|
|
47
|
+
catch (error) { throw new PalletBundleError('invalid_options', { cause: error }); }
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The retained allocation-pool guard's boot unit: a oneshot that recovers the commissioned guard
|
|
52
|
+
* before networkd, required by `network-pre.target` and by networkd itself. The installer installs it
|
|
53
|
+
* only after the first `guard-commission`, and never replaces an installed one with other bytes.
|
|
54
|
+
*/
|
|
55
|
+
export const createPalletGuardServiceDefinition = (optionsArg: IPalletGuardUnitOptions) => definition({
|
|
56
|
+
unitName: optionsArg.unitName,
|
|
57
|
+
description: 'serve.zone retained allocation-pool guard',
|
|
58
|
+
executable: optionsArg.executable,
|
|
59
|
+
args: ['guard-recover'],
|
|
60
|
+
workingDirectory: optionsArg.workingDirectory,
|
|
61
|
+
user: 'root',
|
|
62
|
+
group: 'root',
|
|
63
|
+
restart: 'no',
|
|
64
|
+
killMode: 'mixed',
|
|
65
|
+
timeoutStopSeconds: 360,
|
|
66
|
+
startup: { type: 'oneshot', remainAfterExit: true, timeoutStartSeconds: 600 },
|
|
67
|
+
dependencies: {
|
|
68
|
+
defaultDependencies: false,
|
|
69
|
+
after: [],
|
|
70
|
+
before: ['network-pre.target', palletGuardNetworkProviderName, 'shutdown.target'],
|
|
71
|
+
requires: [],
|
|
72
|
+
wants: ['network-pre.target'],
|
|
73
|
+
conflicts: ['shutdown.target'],
|
|
74
|
+
},
|
|
75
|
+
install: { wantedBy: [], requiredBy: ['network-pre.target', palletGuardNetworkProviderName] },
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Pallet's containerd unit: `pallet-control containerd-serve` as the root main process with null stdin,
|
|
80
|
+
* ready on the `READY=1` its native owner (a child of the main process) sends. Stopping the unit
|
|
81
|
+
* signals only `containerd-serve`, which stops containerd itself; every shim and workload keeps
|
|
82
|
+
* running and is reattached by the next containerd. containerd's exit fails the process and the
|
|
83
|
+
* service manager restarts it — Pallet never restarts containerd inside the process.
|
|
84
|
+
*/
|
|
85
|
+
export const createPalletContainerdServiceDefinition = (optionsArg: IPalletContainerdUnitOptions) => definition({
|
|
86
|
+
unitName: optionsArg.unitName,
|
|
87
|
+
description: 'serve.zone Pallet containerd',
|
|
88
|
+
executable: optionsArg.controlExecutable,
|
|
89
|
+
args: ['containerd-serve'],
|
|
90
|
+
workingDirectory: optionsArg.workingDirectory,
|
|
91
|
+
user: 'root',
|
|
92
|
+
group: 'root',
|
|
93
|
+
restart: 'always',
|
|
94
|
+
restartSeconds: 2,
|
|
95
|
+
killMode: 'process',
|
|
96
|
+
// Pallet's 30 s containerd grace plus the owner's joins; the contract's floor is 45 s.
|
|
97
|
+
timeoutStopSeconds: 60,
|
|
98
|
+
// containerd-serve waits up to 60 s for CRI readiness, then imports the pause image.
|
|
99
|
+
startup: { type: 'notify', notifyAccess: 'all', timeoutStartSeconds: 120 },
|
|
100
|
+
delegate: true,
|
|
101
|
+
limitNoFile: 'infinity',
|
|
102
|
+
tasksMax: 'infinity',
|
|
103
|
+
oomScoreAdjust: -999,
|
|
104
|
+
dependencies: {
|
|
105
|
+
defaultDependencies: true,
|
|
106
|
+
after: [optionsArg.guardUnitName],
|
|
107
|
+
before: [optionsArg.nodeUnitName],
|
|
108
|
+
requires: [optionsArg.guardUnitName],
|
|
109
|
+
wants: [],
|
|
110
|
+
conflicts: [],
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* The node unit: `pallet-control runtime-unit` as the root main process with null stdin. It runs the
|
|
116
|
+
* same node lifetime as `runtime-serve`, but standard input is not its parent's lifetime: SIGTERM or
|
|
117
|
+
* SIGINT stops it. `KillMode=mixed` signals only the main process, which joins every owner and child
|
|
118
|
+
* it started, and the service manager removes whatever remains of the unit's cgroup when the stop
|
|
119
|
+
* timeout ends, before any successor starts. A failed lifetime is restarted by the service manager,
|
|
120
|
+
* never inside the process.
|
|
121
|
+
*/
|
|
122
|
+
export const createPalletNodeServiceDefinition = (optionsArg: IPalletNodeUnitOptions) => definition({
|
|
123
|
+
unitName: optionsArg.unitName,
|
|
124
|
+
description: 'serve.zone Pallet node',
|
|
125
|
+
executable: optionsArg.controlExecutable,
|
|
126
|
+
args: ['runtime-unit'],
|
|
127
|
+
workingDirectory: optionsArg.workingDirectory,
|
|
128
|
+
user: 'root',
|
|
129
|
+
group: 'root',
|
|
130
|
+
restart: 'on-failure',
|
|
131
|
+
restartSeconds: 5,
|
|
132
|
+
killMode: 'mixed',
|
|
133
|
+
timeoutStopSeconds: palletNodeStopTimeoutSeconds,
|
|
134
|
+
dependencies: {
|
|
135
|
+
defaultDependencies: true,
|
|
136
|
+
after: [optionsArg.guardUnitName, optionsArg.containerdUnitName],
|
|
137
|
+
before: [],
|
|
138
|
+
requires: [optionsArg.guardUnitName],
|
|
139
|
+
wants: [optionsArg.containerdUnitName],
|
|
140
|
+
conflicts: [],
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Whether the service manager's own reading of the containerd unit, drop-ins included, is the
|
|
146
|
+
* contract. Admission and activation read the loaded unit rather than the file, so a drop-in that
|
|
147
|
+
* weakens the contract is refused whatever file produced it.
|
|
148
|
+
*/
|
|
149
|
+
export const palletContainerdServiceSettingsMatch = (settingsArg: plugins.smartdaemon.ISystemdServiceSettings,
|
|
150
|
+
unitNameArg: string): boolean =>
|
|
151
|
+
settingsArg.unitName === unitNameArg && settingsArg.type === 'notify' && settingsArg.notifyAccess === 'all' &&
|
|
152
|
+
settingsArg.restart === 'always' && typeof settingsArg.restartMicroseconds === 'number' &&
|
|
153
|
+
settingsArg.restartMicroseconds > 0 && settingsArg.restartMicroseconds <= 10_000_000 && settingsArg.killMode === 'process' &&
|
|
154
|
+
settingsArg.delegate && typeof settingsArg.timeoutStopMicroseconds === 'number' &&
|
|
155
|
+
settingsArg.timeoutStopMicroseconds >= 45_000_000 && settingsArg.limitNoFile === 'infinity' &&
|
|
156
|
+
settingsArg.limitNoFileSoft === 'infinity' && settingsArg.tasksMax === 'infinity' && settingsArg.oomScoreAdjust === -999;
|
|
157
|
+
|
|
158
|
+
/** The same reading of the node unit: no restart inside a stop, and a stop long enough to join. */
|
|
159
|
+
export const palletNodeServiceSettingsMatch = (settingsArg: plugins.smartdaemon.ISystemdServiceSettings,
|
|
160
|
+
unitNameArg: string): boolean =>
|
|
161
|
+
settingsArg.unitName === unitNameArg && settingsArg.type === 'exec' && settingsArg.killMode === 'mixed' &&
|
|
162
|
+
settingsArg.restart === 'on-failure' &&
|
|
163
|
+
typeof settingsArg.timeoutStopMicroseconds === 'number' &&
|
|
164
|
+
settingsArg.timeoutStopMicroseconds >= palletNodeStopTimeoutSeconds * 1_000_000 && !settingsArg.delegate &&
|
|
165
|
+
Object.keys(settingsArg.environment).length === 0;
|