paratix 0.10.0 → 0.12.3
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/README.md +7 -1
- package/dist/chunk-ZXRWWALU.js +19071 -0
- package/dist/chunk-ZXRWWALU.js.map +1 -0
- package/dist/cli.js +5091 -224
- package/dist/cli.js.map +1 -1
- package/dist/{user-CJDqZC8n.d.ts → index-udpAybq3.d.ts} +637 -36
- package/dist/index.d.ts +51 -7
- package/dist/index.js +965 -73
- package/dist/index.js.map +1 -1
- package/dist/modules/index.d.ts +1 -119
- package/dist/modules/index.js +1 -2
- package/llm-guide.md +176 -35
- package/package.json +10 -8
- package/dist/chunk-47PTUZZR.js +0 -495
- package/dist/chunk-47PTUZZR.js.map +0 -1
- package/dist/chunk-M7GETOJ5.js +0 -6237
- package/dist/chunk-M7GETOJ5.js.map +0 -1
- package/dist/chunk-NRDLYHJL.js +0 -1866
- package/dist/chunk-NRDLYHJL.js.map +0 -1
- package/dist/cli.d.ts +0 -62
- package/dist/types-Cl2Muw1x.d.ts +0 -254
|
@@ -1,4 +1,319 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* A scalar env value, or a lazy function that returns one.
|
|
3
|
+
* Functions may be async, allowing secrets to be fetched on demand.
|
|
4
|
+
*/
|
|
5
|
+
type EnvironmentValue = (() => boolean | number | string) | (() => Promise<boolean | number | string>) | boolean | number | string;
|
|
6
|
+
/** A key-value map of environment values available to modules and templates. */
|
|
7
|
+
type Environment = Record<string, EnvironmentValue>;
|
|
8
|
+
/** Environment values that can be emitted through the typed meta system. */
|
|
9
|
+
type MetaEnvironmentValue = EnvironmentValue;
|
|
10
|
+
/** Generic meta entry that propagates a value into the downstream environment. */
|
|
11
|
+
type EnvironmentMetaEntry = {
|
|
12
|
+
kind: "env";
|
|
13
|
+
name: string;
|
|
14
|
+
resolve: () => Promise<boolean | number | string>;
|
|
15
|
+
valueType: "boolean" | "number" | "string";
|
|
16
|
+
valueTypeExplicit?: boolean;
|
|
17
|
+
};
|
|
18
|
+
/** Runner control-plane meta entry emitted when sshd changed its listen port. */
|
|
19
|
+
type SshdPortMetaEntry = {
|
|
20
|
+
kind: "sshd.port";
|
|
21
|
+
port: number;
|
|
22
|
+
};
|
|
23
|
+
/** Runner control-plane meta entry emitted when the target host changed. */
|
|
24
|
+
type SystemHostMetaEntry = {
|
|
25
|
+
host: string;
|
|
26
|
+
kind: "system.host";
|
|
27
|
+
};
|
|
28
|
+
/** Runner control-plane meta entry emitted when a reboot should trigger reconnect logic. */
|
|
29
|
+
type SystemRebootMetaEntry = {
|
|
30
|
+
kind: "system.reboot";
|
|
31
|
+
};
|
|
32
|
+
/** Any meta entry that modules may emit. */
|
|
33
|
+
type ModuleMetaEntry = EnvironmentMetaEntry | SshdPortMetaEntry | SystemHostMetaEntry | SystemRebootMetaEntry;
|
|
34
|
+
/** Check result indicating the module's desired state is not yet present. */
|
|
35
|
+
declare const NEEDS_APPLY: "needs-apply";
|
|
36
|
+
/** Execution status emitted by a module apply step. */
|
|
37
|
+
type ModuleStatus = "changed" | "failed" | "ok" | "skipped";
|
|
38
|
+
/** The outcome of a module's apply step. */
|
|
39
|
+
type ModuleResult = {
|
|
40
|
+
/**
|
|
41
|
+
* Optional internal dry-run detail shown instead of the generic `(dry-run)`
|
|
42
|
+
* suffix when a module performed custom dry-run verification.
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
45
|
+
_dryRunDetail?: string;
|
|
46
|
+
/**
|
|
47
|
+
* Optional internal control-plane marker that tells the current scope to
|
|
48
|
+
* execute all pending signals immediately at this point in the run.
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
51
|
+
_flushSignals?: true;
|
|
52
|
+
/**
|
|
53
|
+
* Optional internal control-plane marker that tells the runner to stop the
|
|
54
|
+
* current run successfully after this module completed.
|
|
55
|
+
* @internal
|
|
56
|
+
*/
|
|
57
|
+
_stopRun?: true;
|
|
58
|
+
/** Optional short detail appended to the printed module status line. */
|
|
59
|
+
detail?: string;
|
|
60
|
+
/**
|
|
61
|
+
* Optional multi-line unified-diff string rendered below the module status
|
|
62
|
+
* line when the runner was started with the `--diff` CLI flag (or with
|
|
63
|
+
* the runner option `diff`). Modules that participate in diff output produce
|
|
64
|
+
* the string in their `_applyDryRun` hook and mark themselves with
|
|
65
|
+
* `_dryRunDiffProducer: true`. The runner never modifies the string; the
|
|
66
|
+
* output layer applies registered-secret masking and terminal sanitizing
|
|
67
|
+
* before printing each line.
|
|
68
|
+
*
|
|
69
|
+
* Renders independently of `_dryRunDetail` — both fields may be set at the
|
|
70
|
+
* same time, and the runner shows both (detail inline next to the status,
|
|
71
|
+
* diff in a block beneath it).
|
|
72
|
+
*/
|
|
73
|
+
diff?: string;
|
|
74
|
+
/** Optional error details consumed by the runner for centralized CLI output. */
|
|
75
|
+
error?: Error;
|
|
76
|
+
/** Optional typed meta entries for env propagation and runner control-plane updates. */
|
|
77
|
+
meta?: ModuleMetaEntry[];
|
|
78
|
+
/** Execution status of the module. */
|
|
79
|
+
status: ModuleStatus;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Internal orchestration step shape shared between runner and recipe execution.
|
|
83
|
+
* Contains the merged downstream environment after a single apply step.
|
|
84
|
+
* @internal
|
|
85
|
+
*/
|
|
86
|
+
type OrchestrationStep = {
|
|
87
|
+
/** @internal */
|
|
88
|
+
_flushSignals?: true;
|
|
89
|
+
/** @internal */
|
|
90
|
+
_stopRun?: true;
|
|
91
|
+
env: Environment;
|
|
92
|
+
meta?: ModuleMetaEntry[];
|
|
93
|
+
status: ModuleStatus;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Optional internal apply hooks used by composite modules to expose child
|
|
97
|
+
* orchestration steps to their surrounding runner scope.
|
|
98
|
+
* @internal
|
|
99
|
+
*/
|
|
100
|
+
type ModuleApplyOptions = {
|
|
101
|
+
onChildStep?: (step: OrchestrationStep) => Promise<void>;
|
|
102
|
+
shutdownSignal?: () => null | ShutdownSignal;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Shutdown signal names observed by Paratix orchestration hooks.
|
|
106
|
+
*
|
|
107
|
+
* This intentionally mirrors Node's process signal strings without referencing
|
|
108
|
+
* the ambient `NodeJS` namespace, so published declarations remain usable in
|
|
109
|
+
* consumers that do not install `@types/node`.
|
|
110
|
+
*/
|
|
111
|
+
type ShutdownSignal = "SIGABRT" | "SIGALRM" | "SIGBREAK" | "SIGBUS" | "SIGCHLD" | "SIGCONT" | "SIGFPE" | "SIGHUP" | "SIGILL" | "SIGINFO" | "SIGINT" | "SIGIO" | "SIGIOT" | "SIGKILL" | "SIGLOST" | "SIGPIPE" | "SIGPOLL" | "SIGPROF" | "SIGPWR" | "SIGQUIT" | "SIGSEGV" | "SIGSTKFLT" | "SIGSTOP" | "SIGSYS" | "SIGTERM" | "SIGTRAP" | "SIGTSTP" | "SIGTTIN" | "SIGTTOU" | "SIGUNUSED" | "SIGURG" | "SIGUSR1" | "SIGUSR2" | "SIGVTALRM" | "SIGWINCH" | "SIGXCPU" | "SIGXFSZ";
|
|
112
|
+
/**
|
|
113
|
+
* A single idempotent unit of work that can be checked and applied.
|
|
114
|
+
* Modules form the building blocks of a server recipe.
|
|
115
|
+
*/
|
|
116
|
+
type Module = {
|
|
117
|
+
/**
|
|
118
|
+
* Optional internal dry-run apply hook for modules that need custom dry-run
|
|
119
|
+
* execution semantics beyond the generic blocker/meta-producer markers.
|
|
120
|
+
* @internal
|
|
121
|
+
*/
|
|
122
|
+
_applyDryRun?: (ssh: null | SshConnection, environment: Environment, options?: ModuleApplyOptions) => Promise<ModuleResult>;
|
|
123
|
+
/**
|
|
124
|
+
* Internal marker for modules that must still execute their apply step in dry-run mode
|
|
125
|
+
* because they act as run blockers rather than mutating state.
|
|
126
|
+
* @internal
|
|
127
|
+
*/
|
|
128
|
+
_dryRunBlocker?: true;
|
|
129
|
+
/**
|
|
130
|
+
* Internal marker for modules that can produce a {@link ModuleResult.diff}
|
|
131
|
+
* during dry-run by running their `_applyDryRun` hook. The runner only
|
|
132
|
+
* dispatches `_applyDryRun` for diff production when the user passed the
|
|
133
|
+
* `--diff` CLI flag (i.e. the runner option `diff` is `true`); otherwise the
|
|
134
|
+
* generic `(dry-run)` suffix is shown without any extra remote round-trips.
|
|
135
|
+
* @internal
|
|
136
|
+
*/
|
|
137
|
+
_dryRunDiffProducer?: true;
|
|
138
|
+
/**
|
|
139
|
+
* Internal marker for non-mutating modules whose apply step emits meta that must
|
|
140
|
+
* still be materialized during dry-run so downstream modules see the same environment.
|
|
141
|
+
* @internal
|
|
142
|
+
*/
|
|
143
|
+
_dryRunMetaProducer?: true;
|
|
144
|
+
/**
|
|
145
|
+
* Internal marker for composite modules that can expose child orchestration
|
|
146
|
+
* steps to the surrounding runner scope.
|
|
147
|
+
* @internal
|
|
148
|
+
*/
|
|
149
|
+
_supportsChildStepHook?: true;
|
|
150
|
+
/**
|
|
151
|
+
* Enforce the desired state.
|
|
152
|
+
* @returns A {@link ModuleResult} describing what happened.
|
|
153
|
+
*/
|
|
154
|
+
apply: (ssh: null | SshConnection, environment: Environment, options?: ModuleApplyOptions) => Promise<ModuleResult>;
|
|
155
|
+
/**
|
|
156
|
+
* Determine whether the module needs to run.
|
|
157
|
+
* @returns `"ok"` if the desired state is already present, `"needs-apply"` otherwise.
|
|
158
|
+
*/
|
|
159
|
+
check: (ssh: null | SshConnection, environment: Environment) => Promise<"needs-apply" | "ok">;
|
|
160
|
+
/**
|
|
161
|
+
* When true the module runs locally instead of over SSH.
|
|
162
|
+
* The `ssh` parameter will be `null` in check/apply.
|
|
163
|
+
*/
|
|
164
|
+
local?: boolean;
|
|
165
|
+
/** Human-readable name shown in the run output. */
|
|
166
|
+
name: string;
|
|
167
|
+
};
|
|
168
|
+
/** Raw output from a remote or local command execution. */
|
|
169
|
+
type ExecResult = {
|
|
170
|
+
/** Exit code of the process. */
|
|
171
|
+
code: number;
|
|
172
|
+
/** Captured standard error. */
|
|
173
|
+
stderr: string;
|
|
174
|
+
/** Captured standard output. */
|
|
175
|
+
stdout: string;
|
|
176
|
+
};
|
|
177
|
+
/** Options that control how a command is executed. */
|
|
178
|
+
type ExecOptions = {
|
|
179
|
+
/** Additional environment variables to inject into the process. */
|
|
180
|
+
env?: Record<string, string>;
|
|
181
|
+
/** Return a result even when the exit code is non-zero instead of throwing. */
|
|
182
|
+
ignoreExitCode?: boolean;
|
|
183
|
+
/**
|
|
184
|
+
* Optional payload written to the remote command's stdin before EOF is
|
|
185
|
+
* signalled. Used to pass secret material (password hashes, signed URLs,
|
|
186
|
+
* Authorization headers) to a remote tool without exposing it on the
|
|
187
|
+
* command line, where it would otherwise leak into `/var/log/auth.log`,
|
|
188
|
+
* `ps -ef`, or `/proc/<pid>/cmdline`.
|
|
189
|
+
*/
|
|
190
|
+
input?: string;
|
|
191
|
+
/**
|
|
192
|
+
* Maximum number of UTF-8 bytes captured per output stream for `stdout` and
|
|
193
|
+
* `stderr`. Live output still streams fully; only the stored ExecResult and
|
|
194
|
+
* CommandError output are capped.
|
|
195
|
+
*/
|
|
196
|
+
maxOutputBytes?: number;
|
|
197
|
+
/** Strings to mask in error messages (e.g. tokens, passwords). */
|
|
198
|
+
secrets?: string[];
|
|
199
|
+
/** Suppress stdout/stderr from the console while running. */
|
|
200
|
+
silent?: boolean;
|
|
201
|
+
/** Abort the command after this many milliseconds. */
|
|
202
|
+
timeout?: number;
|
|
203
|
+
};
|
|
204
|
+
/**
|
|
205
|
+
* Abstraction over an active SSH session.
|
|
206
|
+
* All methods that accept a `command` string run it on the remote host.
|
|
207
|
+
*/
|
|
208
|
+
type SshConnection = {
|
|
209
|
+
/** Register an additional port that was opened on the remote host. Returns `true` when added. */
|
|
210
|
+
addPort: (port: number) => boolean;
|
|
211
|
+
/** Close the SSH connection and free resources. */
|
|
212
|
+
disconnect: () => void;
|
|
213
|
+
/** Download a remote file to the local filesystem. */
|
|
214
|
+
downloadFile: (remotePath: string, localPath: string) => Promise<void>;
|
|
215
|
+
/** Run a command and return the full result including exit code and output. */
|
|
216
|
+
exec: (command: string, options?: ExecOptions) => Promise<ExecResult>;
|
|
217
|
+
/** Return `true` if the remote path exists. */
|
|
218
|
+
exists: (remotePath: string) => Promise<boolean>;
|
|
219
|
+
/**
|
|
220
|
+
* Return the low-level connection parameters for this session.
|
|
221
|
+
* `privateKeyPath` and `agentSocket` reflect the authentication method that
|
|
222
|
+
* was actually used for the current session. `privateKeyPath` is returned as
|
|
223
|
+
* an expanded filesystem path.
|
|
224
|
+
*/
|
|
225
|
+
getConnectionInfo: () => {
|
|
226
|
+
agentSocket?: string;
|
|
227
|
+
authMethod?: "agent" | "password" | "privateKey";
|
|
228
|
+
configuredPorts: number[];
|
|
229
|
+
host: string;
|
|
230
|
+
port: number;
|
|
231
|
+
privateKeyPath?: string;
|
|
232
|
+
user: string;
|
|
233
|
+
verifiedHostPublicKey?: string;
|
|
234
|
+
};
|
|
235
|
+
/** Run a command and return stdout split into lines. */
|
|
236
|
+
lines: (command: string) => Promise<string[]>;
|
|
237
|
+
/** Run a command and return trimmed stdout. */
|
|
238
|
+
output: (command: string) => Promise<string>;
|
|
239
|
+
/** Probe whether passwordless sudo works; prompt interactively if not and cache the password. */
|
|
240
|
+
probeSudo: () => Promise<void>;
|
|
241
|
+
/** Read the full contents of a remote file as a string. */
|
|
242
|
+
readFile: (remotePath: string) => Promise<string>;
|
|
243
|
+
/** Reconnect the SSH session using the current host and registered port candidates. */
|
|
244
|
+
reconnect: () => Promise<void>;
|
|
245
|
+
/** Remove a previously registered port from the reconnect candidate list. */
|
|
246
|
+
removePort: (port: number) => void;
|
|
247
|
+
/** Return the SHA-256 hex digest of a remote file, or `null` if not found. */
|
|
248
|
+
sha256: (remotePath: string) => Promise<null | string>;
|
|
249
|
+
/** Run a command and return `true` if the exit code is zero. */
|
|
250
|
+
test: (command: string) => Promise<boolean>;
|
|
251
|
+
/** Update the target host address (e.g. after a reboot with new IP). */
|
|
252
|
+
updateHost: (host: string) => void;
|
|
253
|
+
/** Upload a local file to the remote host via SFTP. */
|
|
254
|
+
uploadFile: (localPath: string, remotePath: string, options?: {
|
|
255
|
+
mode?: string;
|
|
256
|
+
}) => Promise<void>;
|
|
257
|
+
/** Write a string to a remote file, creating or overwriting it. */
|
|
258
|
+
writeFile: (remotePath: string, content: string, options: {
|
|
259
|
+
mode: string;
|
|
260
|
+
}) => Promise<void>;
|
|
261
|
+
};
|
|
262
|
+
/** SSH connection parameters for a server. */
|
|
263
|
+
type SshConfig = {
|
|
264
|
+
/** Forward the local SSH agent to the remote host. */
|
|
265
|
+
agentForward?: boolean;
|
|
266
|
+
/** Expected SHA256 host fingerprint used as a pinned trust anchor. */
|
|
267
|
+
expectedHostFingerprint?: string;
|
|
268
|
+
/** Expected OpenSSH public key (`"<algorithm> <base64>"`) used as a pinned trust anchor. */
|
|
269
|
+
expectedHostPublicKey?: string;
|
|
270
|
+
/** Maximum number of reconnection attempts before giving up. */
|
|
271
|
+
maxReconnectAttempts?: number;
|
|
272
|
+
/** Fall back to password authentication if key auth fails. */
|
|
273
|
+
passwordFallback?: boolean;
|
|
274
|
+
/** Ordered list of candidate ports -- the runner tries each until one connects. */
|
|
275
|
+
ports: number[];
|
|
276
|
+
/**
|
|
277
|
+
* Absolute path to the private key file used for authentication.
|
|
278
|
+
* When omitted, the SSH agent referenced by `SSH_AUTH_SOCK` is used instead.
|
|
279
|
+
* Exactly one of `privateKey` or a running SSH agent must be available.
|
|
280
|
+
*/
|
|
281
|
+
privateKey?: string;
|
|
282
|
+
/** Maximum time in milliseconds to spend attempting reconnection before giving up. */
|
|
283
|
+
reconnectTimeout?: number;
|
|
284
|
+
/**
|
|
285
|
+
* Host key verification strategy.
|
|
286
|
+
* - `"accept-new"` — explicit TOFU opt-in: accept unknown keys and append them to `~/.ssh/known_hosts`.
|
|
287
|
+
* - `"yes"` — reject unknown keys; only connect when the key is already in `known_hosts`.
|
|
288
|
+
* - `"no"` — skip host key verification entirely.
|
|
289
|
+
*
|
|
290
|
+
* When omitted, Paratix now defaults to `"yes"`. To connect to a new host
|
|
291
|
+
* safely without TOFU, set `expectedHostFingerprint` or `expectedHostPublicKey`.
|
|
292
|
+
*/
|
|
293
|
+
strictHostKeyChecking?: "accept-new" | "no" | "yes";
|
|
294
|
+
/** Password used for `sudo` escalation on the remote host. */
|
|
295
|
+
sudoPassword?: string;
|
|
296
|
+
/** Username to authenticate as. */
|
|
297
|
+
user: string;
|
|
298
|
+
};
|
|
299
|
+
/** Top-level definition of a server and the modules to run on it. */
|
|
300
|
+
type ServerDefinition = {
|
|
301
|
+
/** Server-level env values merged with global env before running modules. */
|
|
302
|
+
env?: Environment;
|
|
303
|
+
/** Hostname or IP address. */
|
|
304
|
+
host: string;
|
|
305
|
+
/** Display name for the server. */
|
|
306
|
+
name: string;
|
|
307
|
+
/** Ordered list of modules (or recipes) to apply. */
|
|
308
|
+
run: Module[];
|
|
309
|
+
/**
|
|
310
|
+
* Modules triggered as signals after the run completes with status `"changed"`.
|
|
311
|
+
* Typically used for service reloads or notifications.
|
|
312
|
+
*/
|
|
313
|
+
signals?: Module[];
|
|
314
|
+
/** SSH connection parameters. */
|
|
315
|
+
ssh: SshConfig;
|
|
316
|
+
};
|
|
2
317
|
|
|
3
318
|
/** Per-call overrides for package operations that can take a long time. */
|
|
4
319
|
type UpgradeOptions = {
|
|
@@ -217,7 +532,7 @@ declare const archive: {
|
|
|
217
532
|
* @param source - Path to the archive (remote path, or local path when upload is true).
|
|
218
533
|
* @param destination - The destination directory on the remote host.
|
|
219
534
|
* @param options - Optional settings.
|
|
220
|
-
* @param options.owner -
|
|
535
|
+
* @param options.owner - Set ownership on extracted archive members after extraction.
|
|
221
536
|
* @param options.upload - Upload a local file to the remote host before extracting.
|
|
222
537
|
* @returns A Module that manages the archive extraction.
|
|
223
538
|
*/
|
|
@@ -238,6 +553,11 @@ declare const command: {
|
|
|
238
553
|
* with a shell expression that exits `0` when the desired state is already
|
|
239
554
|
* present -- in that case the command is skipped.
|
|
240
555
|
*
|
|
556
|
+
* Security: `cmd` and `options.check` are executed verbatim by the remote shell.
|
|
557
|
+
* Never interpolate untrusted input into these strings. NUL, CR, and LF are
|
|
558
|
+
* rejected up front because they can split or corrupt the line-based protocol
|
|
559
|
+
* between the orchestrator and the remote shell.
|
|
560
|
+
*
|
|
241
561
|
* @param cmd - The shell command to execute.
|
|
242
562
|
* @param options - Optional configuration for the command.
|
|
243
563
|
* @param options.check - An optional shell expression used as the idempotency guard.
|
|
@@ -369,6 +689,16 @@ declare const compose: {
|
|
|
369
689
|
|
|
370
690
|
/** Options for `cron.job`. */
|
|
371
691
|
type CronJobOptions = {
|
|
692
|
+
/**
|
|
693
|
+
* R-0000697: opt-in to splicing the marker in front of an existing
|
|
694
|
+
* crontab line that exactly matches `job` when no marker is present.
|
|
695
|
+
* Without this flag, `state="present"` appends a fresh marker + job
|
|
696
|
+
* and never silently adopts an identical user-authored line. Set this
|
|
697
|
+
* to `true` only when knowingly recovering from a `cron.absent` on a
|
|
698
|
+
* legacy marker that left the original job line as an orphan
|
|
699
|
+
* (R-0000567/R-0000676). Defaults to `false`.
|
|
700
|
+
*/
|
|
701
|
+
adoptOrphans?: boolean;
|
|
372
702
|
/** The crontab line to manage (e.g. `"0 * * * * /usr/bin/backup"`). */
|
|
373
703
|
job: string;
|
|
374
704
|
/** Whether the job should be `"present"` or `"absent"`. Defaults to `"present"`. */
|
|
@@ -411,6 +741,27 @@ declare const cron: {
|
|
|
411
741
|
* @param options - Job content and desired state.
|
|
412
742
|
* @param options.job - The crontab line to manage (e.g. `"0 * * * * /usr/bin/backup"`).
|
|
413
743
|
* @param options.state - Whether the job should be `"present"` or `"absent"`. Defaults to `"present"`.
|
|
744
|
+
* @param options.adoptOrphans - R-0000697: opt-in to splicing the marker
|
|
745
|
+
* in front of an existing crontab line that exactly matches `job` when
|
|
746
|
+
* no marker is present. Defaults to `false`. Set to `true` only when
|
|
747
|
+
* knowingly recovering from a `cron.absent` on a legacy marker.
|
|
748
|
+
*
|
|
749
|
+
* R-0000804: concurrency semantics.
|
|
750
|
+
*
|
|
751
|
+
* Each `cron.job` / `cron.absent` apply is serialised by the per-user
|
|
752
|
+
* mutex `crontab-<user>` (see `crontabMutexLockName`). All cron modules
|
|
753
|
+
* targeting the same user therefore share the same flag-lock directory:
|
|
754
|
+
* only one apply can hold the mutex at a time and writers never
|
|
755
|
+
* interleave their `crontab -u <user> -` calls.
|
|
756
|
+
*
|
|
757
|
+
* `check` does NOT take the mutex — it issues a plain `crontab -u <user>
|
|
758
|
+
* -l` and inspects the output, which is safe because cron's own crontab
|
|
759
|
+
* file is read atomically. As a result, `check` may briefly observe a
|
|
760
|
+
* snapshot that does not yet reflect a concurrent apply on the same
|
|
761
|
+
* user. The verdict in that case is `NEEDS_APPLY`, and the subsequent
|
|
762
|
+
* apply re-runs under the mutex against the current crontab state, so a
|
|
763
|
+
* stale `check` cannot cause a divergent write.
|
|
764
|
+
*
|
|
414
765
|
* @returns A Module that manages the cron job entry.
|
|
415
766
|
*/
|
|
416
767
|
job(user: string, name: string, options: CronJobOptions): Module;
|
|
@@ -424,6 +775,8 @@ type BaseDownloadOptions = {
|
|
|
424
775
|
allowInsecureHttp?: boolean;
|
|
425
776
|
/** Explicitly opt out of integrity verification for trusted sources. */
|
|
426
777
|
allowUnverifiedDownload?: boolean;
|
|
778
|
+
/** Maximum time to establish the curl connection, in milliseconds. */
|
|
779
|
+
connectTimeout?: number;
|
|
427
780
|
/** Group owner to set on the downloaded file via `chown`. */
|
|
428
781
|
group?: string;
|
|
429
782
|
/** File mode to set via `chmod` (e.g. `"0755"`). */
|
|
@@ -432,6 +785,8 @@ type BaseDownloadOptions = {
|
|
|
432
785
|
owner?: string;
|
|
433
786
|
/** Expected SHA-256 hex digest for integrity verification. */
|
|
434
787
|
sha256?: string;
|
|
788
|
+
/** Maximum time for the full curl transfer, in milliseconds. */
|
|
789
|
+
timeout?: number;
|
|
435
790
|
};
|
|
436
791
|
/**
|
|
437
792
|
* Modules for downloading files to remote servers via `curl`.
|
|
@@ -447,6 +802,13 @@ declare const download: {
|
|
|
447
802
|
* Idempotency follows the same rules as {@link download.url}: SHA-256
|
|
448
803
|
* comparison when a digest is given, otherwise file-existence check.
|
|
449
804
|
*
|
|
805
|
+
* R-0000805: same caveat as `download.url` — `allowUnverifiedDownload`
|
|
806
|
+
* stores the post-download sha256 in a read-only sibling marker
|
|
807
|
+
* (`<destination>.sha256`, mode 0o444) to detect later tampering, but a
|
|
808
|
+
* root-equivalent attacker can replace both the payload and the marker
|
|
809
|
+
* together. Prefer providing an explicit `sha256` from the GitHub
|
|
810
|
+
* release notes whenever it is available.
|
|
811
|
+
*
|
|
450
812
|
* @param destination - Absolute path on the remote server where the asset is saved.
|
|
451
813
|
* @param options - Repository coordinates and optional download settings.
|
|
452
814
|
* @param options.repo - GitHub repository in `owner/repo` format (e.g. `"hashicorp/terraform"`).
|
|
@@ -482,10 +844,13 @@ declare const download: {
|
|
|
482
844
|
* @param url - The URL to download from.
|
|
483
845
|
* @param options - Optional settings for ownership, permissions, and headers.
|
|
484
846
|
* @param options.allowInsecureHttp - Allow unencrypted `http://` downloads explicitly.
|
|
847
|
+
* @param options.allowInsecureHttpHeaders - Allow sending sensitive headers over unencrypted `http://` explicitly.
|
|
848
|
+
* @param options.connectTimeout - Maximum time to establish the curl connection, in milliseconds.
|
|
485
849
|
* @param options.group - Group owner to set on the downloaded file via `chown`.
|
|
486
850
|
* @param options.mode - File mode to set via `chmod` (e.g. `"0755"`).
|
|
487
851
|
* @param options.owner - User owner to set on the downloaded file via `chown`.
|
|
488
852
|
* @param options.sha256 - Expected SHA-256 hex digest for integrity verification.
|
|
853
|
+
* @param options.timeout - Maximum time for the full curl transfer, in milliseconds.
|
|
489
854
|
* @param options.allowUnverifiedDownload - Explicitly opt out of integrity verification.
|
|
490
855
|
* @param options.headers - Additional HTTP headers sent with the curl request.
|
|
491
856
|
* @returns A Module that manages the large file download.
|
|
@@ -493,8 +858,12 @@ declare const download: {
|
|
|
493
858
|
large(destination: string, url: string, options?: {
|
|
494
859
|
/** Allow unencrypted `http://` downloads explicitly. */
|
|
495
860
|
allowInsecureHttp?: boolean;
|
|
861
|
+
/** Allow sending sensitive headers over unencrypted `http://` explicitly. */
|
|
862
|
+
allowInsecureHttpHeaders?: boolean;
|
|
496
863
|
/** Explicitly opt out of integrity verification for trusted sources. */
|
|
497
864
|
allowUnverifiedDownload?: boolean;
|
|
865
|
+
/** Maximum time to establish the curl connection, in milliseconds. */
|
|
866
|
+
connectTimeout?: number;
|
|
498
867
|
/** Group owner to set on the downloaded file via `chown`. */
|
|
499
868
|
group?: string;
|
|
500
869
|
/** Additional HTTP headers sent with the curl request. */
|
|
@@ -505,6 +874,8 @@ declare const download: {
|
|
|
505
874
|
owner?: string;
|
|
506
875
|
/** Expected SHA-256 hex digest for integrity verification. */
|
|
507
876
|
sha256?: string;
|
|
877
|
+
/** Maximum time for the full curl transfer, in milliseconds. */
|
|
878
|
+
timeout?: number;
|
|
508
879
|
}): Module;
|
|
509
880
|
/**
|
|
510
881
|
* Download a file from a URL to the remote server via `curl -fsSL`.
|
|
@@ -513,15 +884,31 @@ declare const download: {
|
|
|
513
884
|
* provided), file existence (when no digest is given), or skipped entirely
|
|
514
885
|
* when `force` is `true`.
|
|
515
886
|
*
|
|
887
|
+
* R-0000805: when `allowUnverifiedDownload: true` is set, paratix stores
|
|
888
|
+
* the sha256 of the downloaded payload in a sibling marker file
|
|
889
|
+
* `<destination>.sha256` (mode 0o444) and re-verifies the destination
|
|
890
|
+
* against the marker on subsequent runs. The marker is a tampering
|
|
891
|
+
* detector, not a tampering preventer: an attacker with write access to
|
|
892
|
+
* the destination directory and root privileges can swap both the
|
|
893
|
+
* payload and the marker simultaneously, and the next `check` will then
|
|
894
|
+
* conclude the file is "in sync". The read-only mode raises the bar for
|
|
895
|
+
* an unprivileged attacker but does not substitute for a verified
|
|
896
|
+
* `sha256` digest. Provide `sha256` whenever an authoritative digest is
|
|
897
|
+
* known.
|
|
898
|
+
*
|
|
516
899
|
* @param destination - Absolute path on the remote server where the file is saved.
|
|
517
900
|
* @param url - The URL to download from.
|
|
518
901
|
* @param options - Optional settings for integrity, ownership, and headers.
|
|
902
|
+
* @param options.allowInsecureHttp - Allow unencrypted `http://` downloads explicitly.
|
|
903
|
+
* @param options.allowInsecureHttpHeaders - Allow sending sensitive headers over unencrypted `http://` explicitly.
|
|
519
904
|
* @param options.allowUnverifiedDownload - Explicitly opt out of integrity verification.
|
|
520
905
|
* @returns A Module that manages the file download.
|
|
521
906
|
*/
|
|
522
907
|
url(destination: string, url: string, options?: {
|
|
523
908
|
/** Allow unencrypted `http://` downloads explicitly. */
|
|
524
909
|
allowInsecureHttp?: boolean;
|
|
910
|
+
/** Allow sending sensitive headers over unencrypted `http://` explicitly. */
|
|
911
|
+
allowInsecureHttpHeaders?: boolean;
|
|
525
912
|
/** Explicitly opt out of integrity verification for trusted sources. */
|
|
526
913
|
allowUnverifiedDownload?: boolean;
|
|
527
914
|
/** Force re-download even if the file already exists. */
|
|
@@ -571,9 +958,19 @@ declare function assemble(remotePath: string, fragments: string[], options?: {
|
|
|
571
958
|
* @returns A Module that ensures the block is present with the correct content.
|
|
572
959
|
*/
|
|
573
960
|
declare function block(remotePath: string, options: BlockOptions): Module;
|
|
961
|
+
/** Desired settings passed by the caller. */
|
|
962
|
+
type PropertiesOptions = {
|
|
963
|
+
group?: string;
|
|
964
|
+
mode?: string;
|
|
965
|
+
owner?: string;
|
|
966
|
+
};
|
|
574
967
|
/**
|
|
575
968
|
* Set file or directory ownership and permissions on the remote host.
|
|
576
|
-
* Only the attributes specified in `options` are checked and applied.
|
|
969
|
+
* Only the attributes specified in `options` are checked and applied. Drift
|
|
970
|
+
* is detected via `stat -c '%a %U %G'` so `apply` only invokes the relevant
|
|
971
|
+
* `chmod`/`chown`/`chgrp` for fields that actually differ from the desired
|
|
972
|
+
* state. When all desired fields already match, `apply` returns `status: "ok"`
|
|
973
|
+
* instead of falsely reporting a change.
|
|
577
974
|
*
|
|
578
975
|
* @param remotePath - Path to the file or directory on the remote host.
|
|
579
976
|
* @param options - Attributes to enforce.
|
|
@@ -582,14 +979,14 @@ declare function block(remotePath: string, options: BlockOptions): Module;
|
|
|
582
979
|
* @param options.owner - Optional owner name.
|
|
583
980
|
* @returns A Module that ensures the properties match.
|
|
584
981
|
*/
|
|
585
|
-
declare function properties(remotePath: string, options:
|
|
586
|
-
group?: string;
|
|
587
|
-
mode?: string;
|
|
588
|
-
owner?: string;
|
|
589
|
-
}): Module;
|
|
982
|
+
declare function properties(remotePath: string, options: PropertiesOptions): Module;
|
|
590
983
|
/**
|
|
591
984
|
* Replace all occurrences of a regex pattern in a remote file.
|
|
592
|
-
* `check`
|
|
985
|
+
* `check` reads the file, applies the same replacement that `apply` would
|
|
986
|
+
* perform, and reports `needs-apply` only when the resulting content differs
|
|
987
|
+
* from the current content. This makes the module idempotent for cases where
|
|
988
|
+
* the replacement string still matches the pattern (e.g. pattern `"foo"` and
|
|
989
|
+
* replacement `"foobar"`).
|
|
593
990
|
* `apply` reads the file, performs the replacement in TypeScript and writes it back.
|
|
594
991
|
*
|
|
595
992
|
* @param remotePath - Path to the file on the remote host.
|
|
@@ -639,7 +1036,10 @@ declare const file: {
|
|
|
639
1036
|
* @param remotePath - Destination path on the remote host.
|
|
640
1037
|
* @param localPath - Source path on the local filesystem.
|
|
641
1038
|
* @param options - Optional file attributes.
|
|
642
|
-
* @param options.mode - Optional chmod mode string (e.g. `"0644"`).
|
|
1039
|
+
* @param options.mode - Optional chmod mode string (e.g. `"0644"`). When omitted,
|
|
1040
|
+
* the file is created with the documented default `"0644"`
|
|
1041
|
+
* (`"0644"`) instead of inheriting whatever default `ssh.uploadFile` happens
|
|
1042
|
+
* to choose for its temp file.
|
|
643
1043
|
* @param options.owner - Optional chown owner string (e.g. `"www-data:www-data"`).
|
|
644
1044
|
* @returns A Module that copies the file to the remote host.
|
|
645
1045
|
*/
|
|
@@ -666,7 +1066,7 @@ declare const file: {
|
|
|
666
1066
|
* with the new `line` value instead of appending.
|
|
667
1067
|
*
|
|
668
1068
|
* @param remotePath - Path to the file on the remote host.
|
|
669
|
-
* @param line - The exact line content to ensure is present.
|
|
1069
|
+
* @param line - The exact single-line content to ensure is present.
|
|
670
1070
|
* @param options - Optional match configuration.
|
|
671
1071
|
* @param options.match - A regex pattern; when matched, the line is replaced rather than appended.
|
|
672
1072
|
* @returns A Module that ensures the line is present.
|
|
@@ -706,8 +1106,8 @@ declare const git: {
|
|
|
706
1106
|
*
|
|
707
1107
|
* If the destination directory does not yet contain a `.git` folder, the
|
|
708
1108
|
* repository is cloned from scratch. If it already exists, the repository is
|
|
709
|
-
* updated instead (fetch + checkout + reset). When no `ref` is specified,
|
|
710
|
-
*
|
|
1109
|
+
* updated instead (fetch + checkout + reset). When no `ref` is specified,
|
|
1110
|
+
* the existing clone is reset to the current remote default branch HEAD.
|
|
711
1111
|
*
|
|
712
1112
|
* @param repo - The repository URL to clone.
|
|
713
1113
|
* @param destination - The destination path on the remote host.
|
|
@@ -732,7 +1132,9 @@ declare const group: {
|
|
|
732
1132
|
*/
|
|
733
1133
|
absent(name: string): Module;
|
|
734
1134
|
/**
|
|
735
|
-
* Ensure a group exists. Creates it via `groupadd` if absent.
|
|
1135
|
+
* Ensure a group exists. Creates it via `groupadd` if absent. When the
|
|
1136
|
+
* group already exists but its GID differs from `options.gid`, the GID
|
|
1137
|
+
* is healed via `groupmod -g <gid>` so the drift becomes recoverable.
|
|
736
1138
|
*
|
|
737
1139
|
* @param name - The group name.
|
|
738
1140
|
* @param options - Optional group configuration.
|
|
@@ -783,11 +1185,10 @@ declare const mount: {
|
|
|
783
1185
|
* Ensure a filesystem is mounted at the given path. Creates the mountpoint
|
|
784
1186
|
* directory if it does not exist. Optionally persists the mount in `/etc/fstab`.
|
|
785
1187
|
*
|
|
786
|
-
* The check phase verifies that the mountpoint is active (via `findmnt`)
|
|
787
|
-
*
|
|
788
|
-
*
|
|
789
|
-
*
|
|
790
|
-
* when the mountpoint is absent entirely.
|
|
1188
|
+
* The check phase verifies that the mountpoint is active (via `findmnt`), that
|
|
1189
|
+
* its live source / filesystem type / normalized options match the desired
|
|
1190
|
+
* values, and, when `persist` is `true`, that the fstab entry matches the
|
|
1191
|
+
* desired line exactly.
|
|
791
1192
|
*
|
|
792
1193
|
* @param options - Configuration for the mount.
|
|
793
1194
|
* @param options.fstype - The filesystem type (e.g. `"ext4"`, `"tmpfs"`, `"nfs"`).
|
|
@@ -858,17 +1259,23 @@ declare const net: {
|
|
|
858
1259
|
*
|
|
859
1260
|
* @param url - The URL to request.
|
|
860
1261
|
* @param options - Optional request settings.
|
|
1262
|
+
* @param options.allowInsecureHttpHeaders - When `true`, allow sending sensitive headers (e.g. `Authorization`, `Cookie`) over plaintext `http://`. Default `false` rejects such combinations to prevent credential leakage.
|
|
861
1263
|
* @param options.body - Expected string in the response body.
|
|
1264
|
+
* @param options.connectTimeout - Maximum time to establish the curl connection, in milliseconds.
|
|
862
1265
|
* @param options.headers - Additional HTTP headers.
|
|
863
1266
|
* @param options.method - HTTP method (default: `"GET"`).
|
|
864
1267
|
* @param options.status - Expected HTTP status code (default: `200`).
|
|
1268
|
+
* @param options.timeout - Maximum time for the full curl request, in milliseconds.
|
|
865
1269
|
* @returns A Module that checks the HTTP endpoint.
|
|
866
1270
|
*/
|
|
867
1271
|
request(url: string, options?: {
|
|
1272
|
+
allowInsecureHttpHeaders?: boolean;
|
|
868
1273
|
body?: string;
|
|
1274
|
+
connectTimeout?: number;
|
|
869
1275
|
headers?: Record<string, string>;
|
|
870
1276
|
method?: string;
|
|
871
1277
|
status?: number;
|
|
1278
|
+
timeout?: number;
|
|
872
1279
|
}): Module;
|
|
873
1280
|
/**
|
|
874
1281
|
* Manage /etc/resolv.conf (nameservers and search domains).
|
|
@@ -912,7 +1319,7 @@ declare const op: {
|
|
|
912
1319
|
/**
|
|
913
1320
|
* Resolve 1Password secret references into environment values.
|
|
914
1321
|
*
|
|
915
|
-
* Regular references are resolved
|
|
1322
|
+
* Regular references are resolved via `op read`.
|
|
916
1323
|
* References ending in `/one-time-password` or `/otp` are resolved individually
|
|
917
1324
|
* via `op read` and returned as lazy functions that compute a fresh TOTP code
|
|
918
1325
|
* on each call.
|
|
@@ -1040,6 +1447,28 @@ declare const quadlet: {
|
|
|
1040
1447
|
updateImage(options: QuadletImageUpdateOptions): Module;
|
|
1041
1448
|
};
|
|
1042
1449
|
|
|
1450
|
+
/**
|
|
1451
|
+
* Shared helper for the `resolveHost` callback used by reboot-style modules
|
|
1452
|
+
* (`system.reboot`, `releaseUpgrade.upgrade`). Wraps the caller-supplied
|
|
1453
|
+
* resolver in a wall-clock timeout so a hanging DNS/cloud lookup cannot
|
|
1454
|
+
* stall the entire playbook indefinitely.
|
|
1455
|
+
*
|
|
1456
|
+
* R-0000243: previously the resolver was awaited unconditionally — a stuck
|
|
1457
|
+
* cloud-metadata or DNS request would keep the module pending forever
|
|
1458
|
+
* because the runner has no inherent timeout for module callbacks.
|
|
1459
|
+
*/
|
|
1460
|
+
|
|
1461
|
+
/**
|
|
1462
|
+
* R-0000575: callable shape for `resolveHost`. The optional `AbortSignal`
|
|
1463
|
+
* argument lets callers like `resolveHostWithTimeout` signal cancellation
|
|
1464
|
+
* when the wall-clock timeout elapses, so a long-running DNS/cloud lookup
|
|
1465
|
+
* can drop its in-flight work instead of running to completion in the
|
|
1466
|
+
* background. The argument is optional to keep existing zero-arg callbacks
|
|
1467
|
+
* source-compatible — callers that don't care can keep their current
|
|
1468
|
+
* signature.
|
|
1469
|
+
*/
|
|
1470
|
+
type ResolveHostCallback = (signal?: AbortSignal) => Promise<string>;
|
|
1471
|
+
|
|
1043
1472
|
/**
|
|
1044
1473
|
* Options for the {@link releaseUpgrade.upgrade} module.
|
|
1045
1474
|
*/
|
|
@@ -1054,8 +1483,20 @@ type ReleaseUpgradeOptions = {
|
|
|
1054
1483
|
* post-upgrade reboot. Useful when the server's IP address may change
|
|
1055
1484
|
* (e.g. DHCP or cloud environments). The resolved value is emitted as
|
|
1056
1485
|
* `system.host` meta so the runner can reconnect to the correct address.
|
|
1486
|
+
*
|
|
1487
|
+
* R-0000575: the callback receives an `AbortSignal` that fires when the
|
|
1488
|
+
* configured timeout elapses. Honoring the signal lets DNS/cloud lookups
|
|
1489
|
+
* abort their in-flight work promptly.
|
|
1490
|
+
*/
|
|
1491
|
+
resolveHost?: ResolveHostCallback;
|
|
1492
|
+
/**
|
|
1493
|
+
* Wall-clock timeout (ms) applied to {@link ReleaseUpgradeOptions.resolveHost}.
|
|
1494
|
+
* Defaults to 30 seconds (R-0000243) so a hanging DNS/cloud lookup cannot
|
|
1495
|
+
* stall the playbook indefinitely.
|
|
1057
1496
|
*/
|
|
1058
|
-
|
|
1497
|
+
resolveHostTimeoutMs?: number;
|
|
1498
|
+
/** Override the per-step command timeout (ms). Default: 30 minutes. */
|
|
1499
|
+
timeout?: number;
|
|
1059
1500
|
};
|
|
1060
1501
|
/**
|
|
1061
1502
|
* Modules for upgrading the operating system to the next major release.
|
|
@@ -1130,6 +1571,8 @@ type SyncOptions = {
|
|
|
1130
1571
|
* (not recommended for production).
|
|
1131
1572
|
*/
|
|
1132
1573
|
strictHostKeyChecking?: "accept-new" | "no" | "off" | "yes";
|
|
1574
|
+
/** Maximum runtime for a single rsync process in milliseconds. */
|
|
1575
|
+
timeout?: number;
|
|
1133
1576
|
};
|
|
1134
1577
|
/**
|
|
1135
1578
|
* Modules for synchronizing files to a remote host using rsync.
|
|
@@ -1246,7 +1689,12 @@ type KnownHostsOptions = {
|
|
|
1246
1689
|
expectedFingerprint?: string;
|
|
1247
1690
|
port?: number;
|
|
1248
1691
|
publicKey?: string;
|
|
1249
|
-
state?:
|
|
1692
|
+
state?: KnownHostsState;
|
|
1693
|
+
};
|
|
1694
|
+
type KnownHostsState = "absent" | "present";
|
|
1695
|
+
type AuthorizedKeysState = "absent" | "present";
|
|
1696
|
+
type AuthorizedKeysOptions = {
|
|
1697
|
+
state?: AuthorizedKeysState;
|
|
1250
1698
|
};
|
|
1251
1699
|
/**
|
|
1252
1700
|
* Modules for managing SSH client-side resources such as known hosts
|
|
@@ -1266,14 +1714,12 @@ declare const ssh: {
|
|
|
1266
1714
|
* @param options.state - Whether the key should be `"present"` or `"absent"`. Defaults to `"present"`.
|
|
1267
1715
|
* @returns A Module that manages the authorized key entry.
|
|
1268
1716
|
*/
|
|
1269
|
-
authorizedKeys(user: string, key: string, options?:
|
|
1270
|
-
state?: "absent" | "present";
|
|
1271
|
-
}): Module;
|
|
1717
|
+
authorizedKeys(user: string, key: string, options?: AuthorizedKeysOptions): Module;
|
|
1272
1718
|
/**
|
|
1273
1719
|
* Ensure a host is present in (or absent from) the connecting user's `~/.ssh/known_hosts`.
|
|
1274
1720
|
*
|
|
1275
1721
|
* When `state` is `"present"` (the default), the host's public keys are fetched
|
|
1276
|
-
* via `ssh-keyscan` and
|
|
1722
|
+
* via `ssh-keyscan` and written to `~/.ssh/known_hosts`. When `state` is
|
|
1277
1723
|
* `"absent"`, the host entry is removed via `ssh-keygen -R`.
|
|
1278
1724
|
*
|
|
1279
1725
|
* @param host - The hostname or IP address to manage.
|
|
@@ -1310,6 +1756,61 @@ declare const sshd: {
|
|
|
1310
1756
|
port(targetPort: number): Module;
|
|
1311
1757
|
};
|
|
1312
1758
|
|
|
1759
|
+
/**
|
|
1760
|
+
* Modules for managing swap files and common swap-related kernel tuning.
|
|
1761
|
+
*/
|
|
1762
|
+
declare const swap: {
|
|
1763
|
+
/**
|
|
1764
|
+
* Ensure a file-backed swap area exists, is activated, and is persisted in `/etc/fstab`.
|
|
1765
|
+
*
|
|
1766
|
+
* @param options - Configuration for the swap file.
|
|
1767
|
+
* @param options.mode - File mode applied to the swap file. Defaults to `0600`.
|
|
1768
|
+
* @param options.path - Absolute path to the swap file, e.g. `/swapfile`.
|
|
1769
|
+
* @param options.priority - Optional swap priority written into the fstab entry.
|
|
1770
|
+
* @param options.size - Desired file size as bytes or a shell-friendly size string such as `2G`.
|
|
1771
|
+
* @param options.state - Whether the swap file should be `present` (default) or `absent`.
|
|
1772
|
+
* @returns A Module that manages the swap file lifecycle.
|
|
1773
|
+
*/
|
|
1774
|
+
file(options: {
|
|
1775
|
+
mode?: string;
|
|
1776
|
+
path: string;
|
|
1777
|
+
priority?: number;
|
|
1778
|
+
size: number | string;
|
|
1779
|
+
state?: "absent" | "present";
|
|
1780
|
+
}): Module;
|
|
1781
|
+
/**
|
|
1782
|
+
* Persist `vm.swappiness`.
|
|
1783
|
+
*
|
|
1784
|
+
* @param value - Desired swappiness value.
|
|
1785
|
+
* @returns A Module that manages `vm.swappiness`.
|
|
1786
|
+
*/
|
|
1787
|
+
swappiness(value: number): Module;
|
|
1788
|
+
/**
|
|
1789
|
+
* Persist `vm.vfs_cache_pressure`.
|
|
1790
|
+
*
|
|
1791
|
+
* @param value - Desired VFS cache pressure value.
|
|
1792
|
+
* @returns A Module that manages `vm.vfs_cache_pressure`.
|
|
1793
|
+
*/
|
|
1794
|
+
vfsCachePressure(value: number): Module;
|
|
1795
|
+
};
|
|
1796
|
+
|
|
1797
|
+
/**
|
|
1798
|
+
* Options for {@link sysctl.set}.
|
|
1799
|
+
*/
|
|
1800
|
+
type SysctlSetOptions = {
|
|
1801
|
+
/**
|
|
1802
|
+
* When `state` is `"absent"`, optionally restore this live runtime value
|
|
1803
|
+
* after removing the persistence file. Without `resetValue`, only the
|
|
1804
|
+
* persistence file is removed and the live kernel value remains unchanged
|
|
1805
|
+
* until the next reboot.
|
|
1806
|
+
*
|
|
1807
|
+
* Use this for security-relevant parameters (e.g. resetting
|
|
1808
|
+
* `net.ipv4.ip_forward` to `"0"`) where leaving the live value in place
|
|
1809
|
+
* would silently violate the desired absent state.
|
|
1810
|
+
*/
|
|
1811
|
+
resetValue?: string;
|
|
1812
|
+
state?: "absent" | "present";
|
|
1813
|
+
};
|
|
1313
1814
|
/**
|
|
1314
1815
|
* Modules for managing kernel parameters via sysctl on the remote host.
|
|
1315
1816
|
*/
|
|
@@ -1318,21 +1819,24 @@ declare const sysctl: {
|
|
|
1318
1819
|
* Set a sysctl kernel parameter and persist it across reboots.
|
|
1319
1820
|
*
|
|
1320
1821
|
* The live value is applied immediately via `sysctl -w` and a configuration
|
|
1321
|
-
* file is written to `/etc/sysctl.d/99-paratix-<sanitized-key>.conf`
|
|
1322
|
-
* persistence.
|
|
1822
|
+
* file is written to `/etc/sysctl.d/99-paratix-<sanitized-key>-<hash>.conf`
|
|
1823
|
+
* for persistence.
|
|
1323
1824
|
*
|
|
1324
|
-
* When `state` is `"absent"`, the persistence file is removed
|
|
1325
|
-
* value is not reverted (a reboot will restore the default).
|
|
1825
|
+
* When `state` is `"absent"`, the persistence file is removed. By default
|
|
1826
|
+
* the live value is not reverted (a reboot will restore the default). Pass
|
|
1827
|
+
* `resetValue` to additionally write the desired runtime value back to the
|
|
1828
|
+
* kernel via `sysctl -w` so the absent state converges on the live system
|
|
1829
|
+
* as well.
|
|
1326
1830
|
*
|
|
1327
1831
|
* @param key - The sysctl key (e.g. "net.ipv4.ip_forward").
|
|
1328
1832
|
* @param value - The desired value (e.g. "1").
|
|
1329
1833
|
* @param options - Optional settings.
|
|
1330
1834
|
* @param options.state - Whether the parameter should be "present" (default) or "absent".
|
|
1835
|
+
* @param options.resetValue - Live runtime value to restore when `state` is `"absent"`.
|
|
1836
|
+
* Ignored when `state` is `"present"`.
|
|
1331
1837
|
* @returns A Module that manages the sysctl parameter.
|
|
1332
1838
|
*/
|
|
1333
|
-
set(key: string, value: string, options?:
|
|
1334
|
-
state?: "absent" | "present";
|
|
1335
|
-
}): Module;
|
|
1839
|
+
set(key: string, value: string, options?: SysctlSetOptions): Module;
|
|
1336
1840
|
};
|
|
1337
1841
|
|
|
1338
1842
|
/**
|
|
@@ -1342,8 +1846,19 @@ type RebootOptions = {
|
|
|
1342
1846
|
/**
|
|
1343
1847
|
* Optional async function to resolve the new host address after a reboot.
|
|
1344
1848
|
* Useful when the server's IP address may change (e.g. DHCP or cloud environments).
|
|
1849
|
+
*
|
|
1850
|
+
* R-0000575: the callback receives an `AbortSignal` that fires when the
|
|
1851
|
+
* configured timeout elapses. Honoring the signal lets DNS/cloud lookups
|
|
1852
|
+
* abort their in-flight work promptly.
|
|
1853
|
+
*/
|
|
1854
|
+
resolveHost?: ResolveHostCallback;
|
|
1855
|
+
/**
|
|
1856
|
+
* Wall-clock timeout (ms) applied to {@link RebootOptions.resolveHost}.
|
|
1857
|
+
* Defaults to 30 seconds. Mirrors R-0000243 in
|
|
1858
|
+
* {@link import("./releaseUpgrade.js")} so a stuck resolver cannot stall
|
|
1859
|
+
* the runner indefinitely.
|
|
1345
1860
|
*/
|
|
1346
|
-
|
|
1861
|
+
resolveHostTimeoutMs?: number;
|
|
1347
1862
|
};
|
|
1348
1863
|
/**
|
|
1349
1864
|
* Modules for managing system-level operations.
|
|
@@ -1421,6 +1936,74 @@ declare const systemd: {
|
|
|
1421
1936
|
unmasked(name: string): Module;
|
|
1422
1937
|
};
|
|
1423
1938
|
|
|
1939
|
+
/** Options for `timer.scheduled`. */
|
|
1940
|
+
type TimerScheduledOptions = {
|
|
1941
|
+
/** Optional `AccuracySec=` for the `[Timer]` section. */
|
|
1942
|
+
accuracySec?: number | string;
|
|
1943
|
+
/** Description used in both unit `[Unit]` sections. Defaults to `Paratix scheduled task: <name>`. */
|
|
1944
|
+
description?: string;
|
|
1945
|
+
/** Extra environment variables rendered as `Environment=KEY=VAL` lines in `[Service]`. */
|
|
1946
|
+
environment?: Record<string, string>;
|
|
1947
|
+
/** The single command line written as `ExecStart=` in the generated `.service`. */
|
|
1948
|
+
exec: string;
|
|
1949
|
+
/** Optional `Group=` for the `[Service]` section. */
|
|
1950
|
+
group?: string;
|
|
1951
|
+
/** Calendar specification(s) written as one or more `OnCalendar=` lines. */
|
|
1952
|
+
onCalendar: string | string[];
|
|
1953
|
+
/** Whether `Persistent=true` is written into the `[Timer]` section. Defaults to `true`. */
|
|
1954
|
+
persistent?: boolean;
|
|
1955
|
+
/** Optional `RandomizedDelaySec=` for the `[Timer]` section. */
|
|
1956
|
+
randomizedDelaySec?: number | string;
|
|
1957
|
+
/** Whether the timer should be `"present"` or `"absent"`. Defaults to `"present"`. */
|
|
1958
|
+
state?: "absent" | "present";
|
|
1959
|
+
/** Optional `User=` for the `[Service]` section. */
|
|
1960
|
+
user?: string;
|
|
1961
|
+
/** Optional `WorkingDirectory=` for the `[Service]` section. */
|
|
1962
|
+
workingDirectory?: string;
|
|
1963
|
+
};
|
|
1964
|
+
|
|
1965
|
+
declare const timer: {
|
|
1966
|
+
/**
|
|
1967
|
+
* Ensure a systemd timer-driven scheduled task does not exist.
|
|
1968
|
+
*
|
|
1969
|
+
* Disables and stops `<name>.timer`, removes both `<name>.service` and
|
|
1970
|
+
* `<name>.timer` from `/etc/systemd/system/`, and reloads systemd. The
|
|
1971
|
+
* `disable --now` step also removes the timer's `wants/` symlink. Failure
|
|
1972
|
+
* to disable a unit that does not exist is ignored, so this method is
|
|
1973
|
+
* safe to apply repeatedly.
|
|
1974
|
+
*
|
|
1975
|
+
* Behaves like `timer.scheduled(name, { exec: "<unused>", onCalendar: "<unused>", state: "absent" })`,
|
|
1976
|
+
* but does not require placeholder values for `exec` or `onCalendar` and
|
|
1977
|
+
* reports failures with a `timer.absent` prefix instead of `timer.scheduled`.
|
|
1978
|
+
*
|
|
1979
|
+
* @param name - Base unit name without extension. Must match
|
|
1980
|
+
* `^[A-Za-z0-9_\-]+$`.
|
|
1981
|
+
* @returns A Module that ensures the timer-driven scheduled task is absent.
|
|
1982
|
+
*/
|
|
1983
|
+
absent(name: string): Module;
|
|
1984
|
+
/**
|
|
1985
|
+
* Ensure a systemd timer-driven scheduled task is present (or absent).
|
|
1986
|
+
*
|
|
1987
|
+
* Generates `<name>.service` (`Type=oneshot`, no `[Install]` section since
|
|
1988
|
+
* it is triggered exclusively by the timer) and `<name>.timer` under
|
|
1989
|
+
* `/etc/systemd/system/`, reloads systemd, and runs
|
|
1990
|
+
* `systemctl enable --now <name>.timer`. When the timer unit content
|
|
1991
|
+
* changed, the timer is restarted so a new `OnCalendar=` schedule is picked
|
|
1992
|
+
* up immediately. With `state: "absent"`, the timer is disabled and
|
|
1993
|
+
* stopped, both unit files are removed, and systemd is reloaded.
|
|
1994
|
+
*
|
|
1995
|
+
* Validation of `exec`, `description`, `user`, `group`, `workingDirectory`,
|
|
1996
|
+
* `environment` and `onCalendar` only runs when `state` is `"present"`,
|
|
1997
|
+
* so callers can pass placeholder values when removing a timer.
|
|
1998
|
+
*
|
|
1999
|
+
* @param name - Base unit name without extension. Used as `<name>.service`
|
|
2000
|
+
* and `<name>.timer`. Must match `^[A-Za-z0-9_\-]+$`.
|
|
2001
|
+
* @param options - Schedule, command, optional service hardening, and state.
|
|
2002
|
+
* @returns A Module that manages the timer-driven scheduled task.
|
|
2003
|
+
*/
|
|
2004
|
+
scheduled(name: string, options: TimerScheduledOptions): Module;
|
|
2005
|
+
};
|
|
2006
|
+
|
|
1424
2007
|
/**
|
|
1425
2008
|
* Modules for managing the UFW (Uncomplicated Firewall) on Debian/Ubuntu hosts.
|
|
1426
2009
|
*/
|
|
@@ -1451,6 +2034,7 @@ declare const ufw: {
|
|
|
1451
2034
|
type UserOptions = {
|
|
1452
2035
|
groups?: string[];
|
|
1453
2036
|
home?: string;
|
|
2037
|
+
homeMode?: string;
|
|
1454
2038
|
password?: string;
|
|
1455
2039
|
shell?: string;
|
|
1456
2040
|
uid?: number;
|
|
@@ -1474,16 +2058,33 @@ declare const user: {
|
|
|
1474
2058
|
* Ensure a user account exists. Creates the account if absent, or runs
|
|
1475
2059
|
* `usermod` to update attributes if the user already exists.
|
|
1476
2060
|
*
|
|
2061
|
+
* Supplementary group membership is additive: when `options.groups` is set
|
|
2062
|
+
* and the user already exists, `usermod --append --groups <list>` is used so
|
|
2063
|
+
* preexisting memberships not managed by Paratix (e.g. `sudo`, `docker`,
|
|
2064
|
+
* manually added groups) are preserved across re-applies. The `groups`
|
|
2065
|
+
* option therefore expresses "ensure the user is a member of these groups",
|
|
2066
|
+
* not "the user must be a member of exactly these supplementary groups".
|
|
2067
|
+
*
|
|
2068
|
+
* When `home` is provided, `usermod --move-home` migrates the existing
|
|
2069
|
+
* contents to the new path (instead of leaving the user pointing at an
|
|
2070
|
+
* empty directory with the old contents stranded on disk). The home
|
|
2071
|
+
* directory's permission bits are then enforced via `chmod`; the default
|
|
2072
|
+
* mode is `0700` so dot-files in a freshly created home cannot be read
|
|
2073
|
+
* by other local accounts even on hosts where `/etc/login.defs` sets
|
|
2074
|
+
* `HOME_MODE=0755`.
|
|
2075
|
+
*
|
|
1477
2076
|
* @param name - The username.
|
|
1478
2077
|
* @param options - Optional user account configuration.
|
|
1479
2078
|
* @param options.uid - Desired numeric UID.
|
|
1480
2079
|
* @param options.shell - Login shell path (e.g. `"/bin/bash"`).
|
|
1481
2080
|
* @param options.home - Home directory path.
|
|
1482
|
-
* @param options.
|
|
2081
|
+
* @param options.homeMode - Octal permission bits for the home directory
|
|
2082
|
+
* (e.g. `"0700"`, `"750"`). Requires `home`. Defaults to `"0700"`.
|
|
2083
|
+
* @param options.groups - Supplementary groups to add the user to (additive).
|
|
1483
2084
|
* @param options.password - Pre-hashed password (e.g. SHA-512 `$6$...`) set via `chpasswd -e`.
|
|
1484
2085
|
* @returns A Module that ensures the user account is present.
|
|
1485
2086
|
*/
|
|
1486
2087
|
present(name: string, options?: UserOptions): Module;
|
|
1487
2088
|
};
|
|
1488
2089
|
|
|
1489
|
-
export { type
|
|
2090
|
+
export { op as A, pkg as B, quadlet as C, releaseUpgrade as D, type Environment as E, rsync as F, script as G, service as H, ssh as I, sshd as J, swap as K, sysctl as L, type Module as M, NEEDS_APPLY as N, type OrchestrationStep as O, system as P, systemd as Q, timer as R, type SshdPortMetaEntry as S, ufw as T, user as U, type UpgradeOptions as V, type ModuleMetaEntry as a, type MetaEnvironmentValue as b, type EnvironmentMetaEntry as c, type SystemHostMetaEntry as d, type SystemRebootMetaEntry as e, type ModuleResult as f, type ExecResult as g, type ModuleStatus as h, type SshConnection as i, type ShutdownSignal as j, type ServerDefinition as k, type EnvironmentValue as l, type ExecOptions as m, type SshConfig as n, apt as o, archive as p, command as q, compose as r, cron as s, download as t, file as u, git as v, group as w, hostname as x, mount as y, net as z };
|