paratix 0.9.0 → 0.12.2
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-YOSHYUST.js +19058 -0
- package/dist/chunk-YOSHYUST.js.map +1 -0
- package/dist/cli.js +5091 -224
- package/dist/cli.js.map +1 -1
- package/dist/{user-B9lkXr0X.d.ts → index-udpAybq3.d.ts} +653 -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 -42
- package/dist/modules/index.js +3 -2
- package/llm-guide.md +219 -38
- package/package.json +10 -8
- package/dist/chunk-47PTUZZR.js +0 -495
- package/dist/chunk-47PTUZZR.js.map +0 -1
- package/dist/chunk-7Y2RBVG4.js +0 -5891
- package/dist/chunk-7Y2RBVG4.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"`. */
|
|
@@ -382,6 +712,22 @@ type CronJobOptions = {
|
|
|
382
712
|
* idempotent and safely repeatable.
|
|
383
713
|
*/
|
|
384
714
|
declare const cron: {
|
|
715
|
+
/**
|
|
716
|
+
* Ensure a cron job is absent from a user's crontab.
|
|
717
|
+
*
|
|
718
|
+
* Removes the `# paratix: <name>` marker comment and the crontab line
|
|
719
|
+
* directly below it. If the marker is not found, the module reports `ok`
|
|
720
|
+
* without writing the crontab. When the crontab becomes empty after the
|
|
721
|
+
* removal, it is deleted entirely via `crontab -r`.
|
|
722
|
+
*
|
|
723
|
+
* Equivalent to `cron.job(user, name, { job: "<unused>", state: "absent" })`,
|
|
724
|
+
* but does not require a placeholder `job` argument.
|
|
725
|
+
*
|
|
726
|
+
* @param user - The target user whose crontab is managed.
|
|
727
|
+
* @param name - Unique identifier of the cron job marker to remove.
|
|
728
|
+
* @returns A Module that ensures the cron job entry is absent.
|
|
729
|
+
*/
|
|
730
|
+
absent(user: string, name: string): Module;
|
|
385
731
|
/**
|
|
386
732
|
* Ensure a cron job is present in (or absent from) a user's crontab.
|
|
387
733
|
*
|
|
@@ -395,6 +741,27 @@ declare const cron: {
|
|
|
395
741
|
* @param options - Job content and desired state.
|
|
396
742
|
* @param options.job - The crontab line to manage (e.g. `"0 * * * * /usr/bin/backup"`).
|
|
397
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
|
+
*
|
|
398
765
|
* @returns A Module that manages the cron job entry.
|
|
399
766
|
*/
|
|
400
767
|
job(user: string, name: string, options: CronJobOptions): Module;
|
|
@@ -408,6 +775,8 @@ type BaseDownloadOptions = {
|
|
|
408
775
|
allowInsecureHttp?: boolean;
|
|
409
776
|
/** Explicitly opt out of integrity verification for trusted sources. */
|
|
410
777
|
allowUnverifiedDownload?: boolean;
|
|
778
|
+
/** Maximum time to establish the curl connection, in milliseconds. */
|
|
779
|
+
connectTimeout?: number;
|
|
411
780
|
/** Group owner to set on the downloaded file via `chown`. */
|
|
412
781
|
group?: string;
|
|
413
782
|
/** File mode to set via `chmod` (e.g. `"0755"`). */
|
|
@@ -416,6 +785,8 @@ type BaseDownloadOptions = {
|
|
|
416
785
|
owner?: string;
|
|
417
786
|
/** Expected SHA-256 hex digest for integrity verification. */
|
|
418
787
|
sha256?: string;
|
|
788
|
+
/** Maximum time for the full curl transfer, in milliseconds. */
|
|
789
|
+
timeout?: number;
|
|
419
790
|
};
|
|
420
791
|
/**
|
|
421
792
|
* Modules for downloading files to remote servers via `curl`.
|
|
@@ -431,6 +802,13 @@ declare const download: {
|
|
|
431
802
|
* Idempotency follows the same rules as {@link download.url}: SHA-256
|
|
432
803
|
* comparison when a digest is given, otherwise file-existence check.
|
|
433
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
|
+
*
|
|
434
812
|
* @param destination - Absolute path on the remote server where the asset is saved.
|
|
435
813
|
* @param options - Repository coordinates and optional download settings.
|
|
436
814
|
* @param options.repo - GitHub repository in `owner/repo` format (e.g. `"hashicorp/terraform"`).
|
|
@@ -466,10 +844,13 @@ declare const download: {
|
|
|
466
844
|
* @param url - The URL to download from.
|
|
467
845
|
* @param options - Optional settings for ownership, permissions, and headers.
|
|
468
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.
|
|
469
849
|
* @param options.group - Group owner to set on the downloaded file via `chown`.
|
|
470
850
|
* @param options.mode - File mode to set via `chmod` (e.g. `"0755"`).
|
|
471
851
|
* @param options.owner - User owner to set on the downloaded file via `chown`.
|
|
472
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.
|
|
473
854
|
* @param options.allowUnverifiedDownload - Explicitly opt out of integrity verification.
|
|
474
855
|
* @param options.headers - Additional HTTP headers sent with the curl request.
|
|
475
856
|
* @returns A Module that manages the large file download.
|
|
@@ -477,8 +858,12 @@ declare const download: {
|
|
|
477
858
|
large(destination: string, url: string, options?: {
|
|
478
859
|
/** Allow unencrypted `http://` downloads explicitly. */
|
|
479
860
|
allowInsecureHttp?: boolean;
|
|
861
|
+
/** Allow sending sensitive headers over unencrypted `http://` explicitly. */
|
|
862
|
+
allowInsecureHttpHeaders?: boolean;
|
|
480
863
|
/** Explicitly opt out of integrity verification for trusted sources. */
|
|
481
864
|
allowUnverifiedDownload?: boolean;
|
|
865
|
+
/** Maximum time to establish the curl connection, in milliseconds. */
|
|
866
|
+
connectTimeout?: number;
|
|
482
867
|
/** Group owner to set on the downloaded file via `chown`. */
|
|
483
868
|
group?: string;
|
|
484
869
|
/** Additional HTTP headers sent with the curl request. */
|
|
@@ -489,6 +874,8 @@ declare const download: {
|
|
|
489
874
|
owner?: string;
|
|
490
875
|
/** Expected SHA-256 hex digest for integrity verification. */
|
|
491
876
|
sha256?: string;
|
|
877
|
+
/** Maximum time for the full curl transfer, in milliseconds. */
|
|
878
|
+
timeout?: number;
|
|
492
879
|
}): Module;
|
|
493
880
|
/**
|
|
494
881
|
* Download a file from a URL to the remote server via `curl -fsSL`.
|
|
@@ -497,15 +884,31 @@ declare const download: {
|
|
|
497
884
|
* provided), file existence (when no digest is given), or skipped entirely
|
|
498
885
|
* when `force` is `true`.
|
|
499
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
|
+
*
|
|
500
899
|
* @param destination - Absolute path on the remote server where the file is saved.
|
|
501
900
|
* @param url - The URL to download from.
|
|
502
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.
|
|
503
904
|
* @param options.allowUnverifiedDownload - Explicitly opt out of integrity verification.
|
|
504
905
|
* @returns A Module that manages the file download.
|
|
505
906
|
*/
|
|
506
907
|
url(destination: string, url: string, options?: {
|
|
507
908
|
/** Allow unencrypted `http://` downloads explicitly. */
|
|
508
909
|
allowInsecureHttp?: boolean;
|
|
910
|
+
/** Allow sending sensitive headers over unencrypted `http://` explicitly. */
|
|
911
|
+
allowInsecureHttpHeaders?: boolean;
|
|
509
912
|
/** Explicitly opt out of integrity verification for trusted sources. */
|
|
510
913
|
allowUnverifiedDownload?: boolean;
|
|
511
914
|
/** Force re-download even if the file already exists. */
|
|
@@ -555,9 +958,19 @@ declare function assemble(remotePath: string, fragments: string[], options?: {
|
|
|
555
958
|
* @returns A Module that ensures the block is present with the correct content.
|
|
556
959
|
*/
|
|
557
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
|
+
};
|
|
558
967
|
/**
|
|
559
968
|
* Set file or directory ownership and permissions on the remote host.
|
|
560
|
-
* 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.
|
|
561
974
|
*
|
|
562
975
|
* @param remotePath - Path to the file or directory on the remote host.
|
|
563
976
|
* @param options - Attributes to enforce.
|
|
@@ -566,14 +979,14 @@ declare function block(remotePath: string, options: BlockOptions): Module;
|
|
|
566
979
|
* @param options.owner - Optional owner name.
|
|
567
980
|
* @returns A Module that ensures the properties match.
|
|
568
981
|
*/
|
|
569
|
-
declare function properties(remotePath: string, options:
|
|
570
|
-
group?: string;
|
|
571
|
-
mode?: string;
|
|
572
|
-
owner?: string;
|
|
573
|
-
}): Module;
|
|
982
|
+
declare function properties(remotePath: string, options: PropertiesOptions): Module;
|
|
574
983
|
/**
|
|
575
984
|
* Replace all occurrences of a regex pattern in a remote file.
|
|
576
|
-
* `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"`).
|
|
577
990
|
* `apply` reads the file, performs the replacement in TypeScript and writes it back.
|
|
578
991
|
*
|
|
579
992
|
* @param remotePath - Path to the file on the remote host.
|
|
@@ -623,7 +1036,10 @@ declare const file: {
|
|
|
623
1036
|
* @param remotePath - Destination path on the remote host.
|
|
624
1037
|
* @param localPath - Source path on the local filesystem.
|
|
625
1038
|
* @param options - Optional file attributes.
|
|
626
|
-
* @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.
|
|
627
1043
|
* @param options.owner - Optional chown owner string (e.g. `"www-data:www-data"`).
|
|
628
1044
|
* @returns A Module that copies the file to the remote host.
|
|
629
1045
|
*/
|
|
@@ -650,7 +1066,7 @@ declare const file: {
|
|
|
650
1066
|
* with the new `line` value instead of appending.
|
|
651
1067
|
*
|
|
652
1068
|
* @param remotePath - Path to the file on the remote host.
|
|
653
|
-
* @param line - The exact line content to ensure is present.
|
|
1069
|
+
* @param line - The exact single-line content to ensure is present.
|
|
654
1070
|
* @param options - Optional match configuration.
|
|
655
1071
|
* @param options.match - A regex pattern; when matched, the line is replaced rather than appended.
|
|
656
1072
|
* @returns A Module that ensures the line is present.
|
|
@@ -690,8 +1106,8 @@ declare const git: {
|
|
|
690
1106
|
*
|
|
691
1107
|
* If the destination directory does not yet contain a `.git` folder, the
|
|
692
1108
|
* repository is cloned from scratch. If it already exists, the repository is
|
|
693
|
-
* updated instead (fetch + checkout + reset). When no `ref` is specified,
|
|
694
|
-
*
|
|
1109
|
+
* updated instead (fetch + checkout + reset). When no `ref` is specified,
|
|
1110
|
+
* the existing clone is reset to the current remote default branch HEAD.
|
|
695
1111
|
*
|
|
696
1112
|
* @param repo - The repository URL to clone.
|
|
697
1113
|
* @param destination - The destination path on the remote host.
|
|
@@ -716,7 +1132,9 @@ declare const group: {
|
|
|
716
1132
|
*/
|
|
717
1133
|
absent(name: string): Module;
|
|
718
1134
|
/**
|
|
719
|
-
* 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.
|
|
720
1138
|
*
|
|
721
1139
|
* @param name - The group name.
|
|
722
1140
|
* @param options - Optional group configuration.
|
|
@@ -767,11 +1185,10 @@ declare const mount: {
|
|
|
767
1185
|
* Ensure a filesystem is mounted at the given path. Creates the mountpoint
|
|
768
1186
|
* directory if it does not exist. Optionally persists the mount in `/etc/fstab`.
|
|
769
1187
|
*
|
|
770
|
-
* The check phase verifies that the mountpoint is active (via `findmnt`)
|
|
771
|
-
*
|
|
772
|
-
*
|
|
773
|
-
*
|
|
774
|
-
* 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.
|
|
775
1192
|
*
|
|
776
1193
|
* @param options - Configuration for the mount.
|
|
777
1194
|
* @param options.fstype - The filesystem type (e.g. `"ext4"`, `"tmpfs"`, `"nfs"`).
|
|
@@ -842,17 +1259,23 @@ declare const net: {
|
|
|
842
1259
|
*
|
|
843
1260
|
* @param url - The URL to request.
|
|
844
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.
|
|
845
1263
|
* @param options.body - Expected string in the response body.
|
|
1264
|
+
* @param options.connectTimeout - Maximum time to establish the curl connection, in milliseconds.
|
|
846
1265
|
* @param options.headers - Additional HTTP headers.
|
|
847
1266
|
* @param options.method - HTTP method (default: `"GET"`).
|
|
848
1267
|
* @param options.status - Expected HTTP status code (default: `200`).
|
|
1268
|
+
* @param options.timeout - Maximum time for the full curl request, in milliseconds.
|
|
849
1269
|
* @returns A Module that checks the HTTP endpoint.
|
|
850
1270
|
*/
|
|
851
1271
|
request(url: string, options?: {
|
|
1272
|
+
allowInsecureHttpHeaders?: boolean;
|
|
852
1273
|
body?: string;
|
|
1274
|
+
connectTimeout?: number;
|
|
853
1275
|
headers?: Record<string, string>;
|
|
854
1276
|
method?: string;
|
|
855
1277
|
status?: number;
|
|
1278
|
+
timeout?: number;
|
|
856
1279
|
}): Module;
|
|
857
1280
|
/**
|
|
858
1281
|
* Manage /etc/resolv.conf (nameservers and search domains).
|
|
@@ -896,7 +1319,7 @@ declare const op: {
|
|
|
896
1319
|
/**
|
|
897
1320
|
* Resolve 1Password secret references into environment values.
|
|
898
1321
|
*
|
|
899
|
-
* Regular references are resolved
|
|
1322
|
+
* Regular references are resolved via `op read`.
|
|
900
1323
|
* References ending in `/one-time-password` or `/otp` are resolved individually
|
|
901
1324
|
* via `op read` and returned as lazy functions that compute a fresh TOTP code
|
|
902
1325
|
* on each call.
|
|
@@ -1024,6 +1447,28 @@ declare const quadlet: {
|
|
|
1024
1447
|
updateImage(options: QuadletImageUpdateOptions): Module;
|
|
1025
1448
|
};
|
|
1026
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
|
+
|
|
1027
1472
|
/**
|
|
1028
1473
|
* Options for the {@link releaseUpgrade.upgrade} module.
|
|
1029
1474
|
*/
|
|
@@ -1038,8 +1483,20 @@ type ReleaseUpgradeOptions = {
|
|
|
1038
1483
|
* post-upgrade reboot. Useful when the server's IP address may change
|
|
1039
1484
|
* (e.g. DHCP or cloud environments). The resolved value is emitted as
|
|
1040
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.
|
|
1041
1496
|
*/
|
|
1042
|
-
|
|
1497
|
+
resolveHostTimeoutMs?: number;
|
|
1498
|
+
/** Override the per-step command timeout (ms). Default: 30 minutes. */
|
|
1499
|
+
timeout?: number;
|
|
1043
1500
|
};
|
|
1044
1501
|
/**
|
|
1045
1502
|
* Modules for upgrading the operating system to the next major release.
|
|
@@ -1114,6 +1571,8 @@ type SyncOptions = {
|
|
|
1114
1571
|
* (not recommended for production).
|
|
1115
1572
|
*/
|
|
1116
1573
|
strictHostKeyChecking?: "accept-new" | "no" | "off" | "yes";
|
|
1574
|
+
/** Maximum runtime for a single rsync process in milliseconds. */
|
|
1575
|
+
timeout?: number;
|
|
1117
1576
|
};
|
|
1118
1577
|
/**
|
|
1119
1578
|
* Modules for synchronizing files to a remote host using rsync.
|
|
@@ -1230,7 +1689,12 @@ type KnownHostsOptions = {
|
|
|
1230
1689
|
expectedFingerprint?: string;
|
|
1231
1690
|
port?: number;
|
|
1232
1691
|
publicKey?: string;
|
|
1233
|
-
state?:
|
|
1692
|
+
state?: KnownHostsState;
|
|
1693
|
+
};
|
|
1694
|
+
type KnownHostsState = "absent" | "present";
|
|
1695
|
+
type AuthorizedKeysState = "absent" | "present";
|
|
1696
|
+
type AuthorizedKeysOptions = {
|
|
1697
|
+
state?: AuthorizedKeysState;
|
|
1234
1698
|
};
|
|
1235
1699
|
/**
|
|
1236
1700
|
* Modules for managing SSH client-side resources such as known hosts
|
|
@@ -1250,14 +1714,12 @@ declare const ssh: {
|
|
|
1250
1714
|
* @param options.state - Whether the key should be `"present"` or `"absent"`. Defaults to `"present"`.
|
|
1251
1715
|
* @returns A Module that manages the authorized key entry.
|
|
1252
1716
|
*/
|
|
1253
|
-
authorizedKeys(user: string, key: string, options?:
|
|
1254
|
-
state?: "absent" | "present";
|
|
1255
|
-
}): Module;
|
|
1717
|
+
authorizedKeys(user: string, key: string, options?: AuthorizedKeysOptions): Module;
|
|
1256
1718
|
/**
|
|
1257
1719
|
* Ensure a host is present in (or absent from) the connecting user's `~/.ssh/known_hosts`.
|
|
1258
1720
|
*
|
|
1259
1721
|
* When `state` is `"present"` (the default), the host's public keys are fetched
|
|
1260
|
-
* via `ssh-keyscan` and
|
|
1722
|
+
* via `ssh-keyscan` and written to `~/.ssh/known_hosts`. When `state` is
|
|
1261
1723
|
* `"absent"`, the host entry is removed via `ssh-keygen -R`.
|
|
1262
1724
|
*
|
|
1263
1725
|
* @param host - The hostname or IP address to manage.
|
|
@@ -1294,6 +1756,61 @@ declare const sshd: {
|
|
|
1294
1756
|
port(targetPort: number): Module;
|
|
1295
1757
|
};
|
|
1296
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
|
+
};
|
|
1297
1814
|
/**
|
|
1298
1815
|
* Modules for managing kernel parameters via sysctl on the remote host.
|
|
1299
1816
|
*/
|
|
@@ -1302,21 +1819,24 @@ declare const sysctl: {
|
|
|
1302
1819
|
* Set a sysctl kernel parameter and persist it across reboots.
|
|
1303
1820
|
*
|
|
1304
1821
|
* The live value is applied immediately via `sysctl -w` and a configuration
|
|
1305
|
-
* file is written to `/etc/sysctl.d/99-paratix-<sanitized-key>.conf`
|
|
1306
|
-
* persistence.
|
|
1822
|
+
* file is written to `/etc/sysctl.d/99-paratix-<sanitized-key>-<hash>.conf`
|
|
1823
|
+
* for persistence.
|
|
1307
1824
|
*
|
|
1308
|
-
* When `state` is `"absent"`, the persistence file is removed
|
|
1309
|
-
* 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.
|
|
1310
1830
|
*
|
|
1311
1831
|
* @param key - The sysctl key (e.g. "net.ipv4.ip_forward").
|
|
1312
1832
|
* @param value - The desired value (e.g. "1").
|
|
1313
1833
|
* @param options - Optional settings.
|
|
1314
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"`.
|
|
1315
1837
|
* @returns A Module that manages the sysctl parameter.
|
|
1316
1838
|
*/
|
|
1317
|
-
set(key: string, value: string, options?:
|
|
1318
|
-
state?: "absent" | "present";
|
|
1319
|
-
}): Module;
|
|
1839
|
+
set(key: string, value: string, options?: SysctlSetOptions): Module;
|
|
1320
1840
|
};
|
|
1321
1841
|
|
|
1322
1842
|
/**
|
|
@@ -1326,8 +1846,19 @@ type RebootOptions = {
|
|
|
1326
1846
|
/**
|
|
1327
1847
|
* Optional async function to resolve the new host address after a reboot.
|
|
1328
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.
|
|
1329
1860
|
*/
|
|
1330
|
-
|
|
1861
|
+
resolveHostTimeoutMs?: number;
|
|
1331
1862
|
};
|
|
1332
1863
|
/**
|
|
1333
1864
|
* Modules for managing system-level operations.
|
|
@@ -1405,6 +1936,74 @@ declare const systemd: {
|
|
|
1405
1936
|
unmasked(name: string): Module;
|
|
1406
1937
|
};
|
|
1407
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
|
+
|
|
1408
2007
|
/**
|
|
1409
2008
|
* Modules for managing the UFW (Uncomplicated Firewall) on Debian/Ubuntu hosts.
|
|
1410
2009
|
*/
|
|
@@ -1435,6 +2034,7 @@ declare const ufw: {
|
|
|
1435
2034
|
type UserOptions = {
|
|
1436
2035
|
groups?: string[];
|
|
1437
2036
|
home?: string;
|
|
2037
|
+
homeMode?: string;
|
|
1438
2038
|
password?: string;
|
|
1439
2039
|
shell?: string;
|
|
1440
2040
|
uid?: number;
|
|
@@ -1458,16 +2058,33 @@ declare const user: {
|
|
|
1458
2058
|
* Ensure a user account exists. Creates the account if absent, or runs
|
|
1459
2059
|
* `usermod` to update attributes if the user already exists.
|
|
1460
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
|
+
*
|
|
1461
2076
|
* @param name - The username.
|
|
1462
2077
|
* @param options - Optional user account configuration.
|
|
1463
2078
|
* @param options.uid - Desired numeric UID.
|
|
1464
2079
|
* @param options.shell - Login shell path (e.g. `"/bin/bash"`).
|
|
1465
2080
|
* @param options.home - Home directory path.
|
|
1466
|
-
* @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).
|
|
1467
2084
|
* @param options.password - Pre-hashed password (e.g. SHA-512 `$6$...`) set via `chpasswd -e`.
|
|
1468
2085
|
* @returns A Module that ensures the user account is present.
|
|
1469
2086
|
*/
|
|
1470
2087
|
present(name: string, options?: UserOptions): Module;
|
|
1471
2088
|
};
|
|
1472
2089
|
|
|
1473
|
-
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 };
|