@descryy/runtime-controller 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +6 -0
- package/dist/capability-registry.d.ts +0 -15
- package/dist/capability-registry.d.ts.map +1 -1
- package/dist/capability-registry.js +9 -19
- package/dist/capability-registry.js.map +1 -1
- package/dist/collector-version.d.ts +1 -8
- package/dist/collector-version.d.ts.map +1 -1
- package/dist/collector-version.js +1 -8
- package/dist/collector-version.js.map +1 -1
- package/dist/container-sandbox.d.ts +66 -150
- package/dist/container-sandbox.d.ts.map +1 -1
- package/dist/container-sandbox.js +62 -143
- package/dist/container-sandbox.js.map +1 -1
- package/dist/controller.d.ts +54 -87
- package/dist/controller.d.ts.map +1 -1
- package/dist/controller.js +77 -104
- package/dist/controller.js.map +1 -1
- package/dist/dependency-version-check.d.ts +19 -73
- package/dist/dependency-version-check.d.ts.map +1 -1
- package/dist/dependency-version-check.js +18 -67
- package/dist/dependency-version-check.js.map +1 -1
- package/dist/env.d.ts +4 -10
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +4 -10
- package/dist/env.js.map +1 -1
- package/dist/environment-metadata.d.ts +9 -17
- package/dist/environment-metadata.d.ts.map +1 -1
- package/dist/environment-metadata.js +12 -29
- package/dist/environment-metadata.js.map +1 -1
- package/dist/environment-version-check.d.ts +22 -65
- package/dist/environment-version-check.d.ts.map +1 -1
- package/dist/environment-version-check.js +24 -66
- package/dist/environment-version-check.js.map +1 -1
- package/dist/execution-safety.d.ts +54 -112
- package/dist/execution-safety.d.ts.map +1 -1
- package/dist/execution-safety.js +48 -102
- package/dist/execution-safety.js.map +1 -1
- package/dist/index.d.ts +0 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/orchestration.d.ts +24 -39
- package/dist/orchestration.d.ts.map +1 -1
- package/dist/orchestration.js +39 -75
- package/dist/orchestration.js.map +1 -1
- package/dist/process-collector.d.ts +8 -22
- package/dist/process-collector.d.ts.map +1 -1
- package/dist/process-collector.js +23 -55
- package/dist/process-collector.js.map +1 -1
- package/dist/process-manager.d.ts +45 -80
- package/dist/process-manager.d.ts.map +1 -1
- package/dist/process-manager.js +51 -101
- package/dist/process-manager.js.map +1 -1
- package/dist/readiness.d.ts +28 -70
- package/dist/readiness.d.ts.map +1 -1
- package/dist/readiness.js +73 -95
- package/dist/readiness.js.map +1 -1
- package/dist/sandbox.d.ts +60 -105
- package/dist/sandbox.d.ts.map +1 -1
- package/dist/sandbox.js +78 -121
- package/dist/sandbox.js.map +1 -1
- package/package.json +7 -2
|
@@ -1,153 +1,95 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* §21's execution boundary
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* boundary instead of leaving it absent, which is what §38's "arbitrary
|
|
8
|
-
* application code runs without a defined safety boundary" actually bans.
|
|
9
|
-
* Real isolation (containers/namespaces) is a separate architectural
|
|
10
|
-
* decision this module does not invent (plan §29's own instruction).
|
|
2
|
+
* §21/RT-070's execution boundary: resource limits and privilege reporting for a
|
|
3
|
+
* runtime declared trusted-local -- every spawned process runs with the invoking
|
|
4
|
+
* user's own OS privileges, no filesystem/network restriction. Names the boundary
|
|
5
|
+
* rather than leaving it absent (§38); real isolation (containers/namespaces) is a
|
|
6
|
+
* separate decision this module does not invent (§29).
|
|
11
7
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* is util-linux and absent on macOS, so it is reported as a capability,
|
|
17
|
-
* never assumed.
|
|
8
|
+
* Enforces for real, via the OS: CPU time, virtual memory, process count, through
|
|
9
|
+
* `prlimit` -- an exec wrapper, never a shell (a shell would undo RT-036's
|
|
10
|
+
* `tokenizeCommand` refusal of shell metacharacters). `prlimit` is util-linux, absent
|
|
11
|
+
* on macOS, so it's reported as a capability, never assumed.
|
|
18
12
|
*/
|
|
19
13
|
import type { CapabilityStatus, ResourceLimits } from "@descryy/runtime-contracts";
|
|
20
|
-
/**
|
|
21
|
-
* Whether `prlimit` is reachable on this platform's `PATH`. Takes `env` as
|
|
22
|
-
* a parameter (defaulting to `process.env`) rather than reading it
|
|
23
|
-
* internally so the "unavailable" branch is directly testable without
|
|
24
|
-
* mutating this process's own real environment or depending on running on
|
|
25
|
-
* a platform that genuinely lacks it.
|
|
26
|
-
*/
|
|
14
|
+
/** Whether `prlimit` is reachable on PATH. `env` is a parameter (default `process.env`) so the "unavailable" branch is testable without mutating the real environment. */
|
|
27
15
|
export declare function resourceLimitCapability(env?: NodeJS.ProcessEnv): CapabilityStatus;
|
|
28
16
|
/**
|
|
29
|
-
* RT-193 originally made this always `unavailable
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* every existing caller (`ExecutionController.run()`, this package's own
|
|
34
|
-
* tests) already imports, delegating rather than duplicating the check --
|
|
35
|
-
* exactly the seam RT-193's own comment anticipated ("if a real mechanism
|
|
36
|
-
* is ever built, this one function changes and every caller keeps working
|
|
37
|
-
* unmodified"). Still unconditionally `unavailable` on macOS/Windows, where
|
|
38
|
-
* nothing enforces it yet.
|
|
17
|
+
* RT-193 originally made this always `unavailable`. Now delegates to
|
|
18
|
+
* `networkIsolationCapability()` (`./sandbox.ts`), real on Linux via a bwrap network
|
|
19
|
+
* namespace -- kept as the stable name every caller already imports (the seam
|
|
20
|
+
* RT-193 anticipated). Still unconditionally `unavailable` on macOS/Windows.
|
|
39
21
|
*/
|
|
40
22
|
export declare function networkPolicyCapability(env?: NodeJS.ProcessEnv): CapabilityStatus;
|
|
41
23
|
/**
|
|
42
|
-
* Wraps `command`/`args` so the OS enforces `limits`, via `prlimit`.
|
|
43
|
-
*
|
|
44
|
-
* every execution before RT-070 keeps behaving exactly as before unless it
|
|
45
|
-
* opts in.
|
|
24
|
+
* Wraps `command`/`args` so the OS enforces `limits`, via `prlimit`. `undefined` or
|
|
25
|
+
* empty `limits` returns them unchanged -- opt-in only.
|
|
46
26
|
*
|
|
47
|
-
* **Throws rather than silently spawning unconstrained** when a limit was
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* allocate without bound, silently -- exactly the "sandbox that doesn't
|
|
52
|
-
* sandbox" shape §38 bans, one row up from this one.
|
|
27
|
+
* **Throws rather than silently spawning unconstrained** when a limit was requested
|
|
28
|
+
* and `prlimit` is unavailable (refuse-not-guess, per RT-036) -- the alternative is a
|
|
29
|
+
* caller asking for a memory cap and silently getting an unbounded process, the
|
|
30
|
+
* "sandbox that doesn't sandbox" shape §38 bans.
|
|
53
31
|
*/
|
|
54
32
|
export declare function applyResourceLimits(command: string, args: readonly string[], limits: ResourceLimits | undefined, env?: NodeJS.ProcessEnv): {
|
|
55
33
|
readonly command: string;
|
|
56
34
|
readonly args: readonly string[];
|
|
57
35
|
};
|
|
58
36
|
/**
|
|
59
|
-
* DEC-272
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* regardless of which privilege level was found; only the observed fact
|
|
63
|
-
* changes.
|
|
37
|
+
* DEC-272: the sandbox boundary (RT-070) must be stated to the user directly, not
|
|
38
|
+
* left as a silent doc gap. Fixed, not derived from `runningAsRoot` -- the boundary
|
|
39
|
+
* is the same regardless of privilege level found.
|
|
64
40
|
*
|
|
65
|
-
* **Scope
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* that actually got a `FilesystemPolicy`/`NetworkPolicy` applied to it is
|
|
73
|
-
* genuinely more contained than "the same as if you started it yourself"
|
|
74
|
-
* says. Using this constant unconditionally for that process would be a
|
|
75
|
-
* real disclosure-accuracy bug -- understating a boundary is not the safe
|
|
76
|
-
* direction to be wrong in, it just happens to be a less alarming one.
|
|
77
|
-
* `sandboxBoundaryDisclosureFor()` below is the mode-aware replacement: it
|
|
78
|
-
* returns this exact string when no policy was applied (attach-mode always,
|
|
79
|
-
* and any spawn that declared none -- unchanged from before this lane), and
|
|
80
|
-
* a real, specific description of what is and is not contained when a
|
|
81
|
-
* policy genuinely was. This constant is kept, unchanged, as that function's
|
|
82
|
-
* own no-policy-applied return value and as attach-mode's own disclosure,
|
|
83
|
-
* not deprecated -- attach-mode never has anything more accurate to say.
|
|
41
|
+
* **Scope: this is the unconditional-unisolated text, not a universal one.** Accurate
|
|
42
|
+
* for every execution before `sandbox.ts` existed; no longer true once spawn-mode got
|
|
43
|
+
* real bwrap-backed isolation (`applySandbox`) -- using this unconditionally for an
|
|
44
|
+
* isolated process would understate its boundary, which is not the safe direction to
|
|
45
|
+
* be wrong in. `sandboxBoundaryDisclosureFor()` below is the mode-aware replacement;
|
|
46
|
+
* this constant remains its no-policy-applied return value and attach-mode's own
|
|
47
|
+
* disclosure (attach-mode never has anything more accurate to say).
|
|
84
48
|
*/
|
|
85
49
|
export declare const SANDBOX_BOUNDARY_DISCLOSURE: string;
|
|
86
50
|
/**
|
|
87
|
-
* Whether a real
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* comment), so by the time a caller can observe a successfully spawned
|
|
92
|
-
* process, "declared" and "applied" are the same fact; this type exists so
|
|
93
|
-
* a caller states that fact explicitly rather than this function silently
|
|
94
|
-
* assuming it.
|
|
51
|
+
* Whether a real policy was actually enforced, not merely requested. `applySandbox`
|
|
52
|
+
* already throws rather than proceed unconstrained when a declared policy can't be
|
|
53
|
+
* enforced, so by the time a process is observed running, "declared" and "applied"
|
|
54
|
+
* are the same fact -- this type makes the caller state it explicitly.
|
|
95
55
|
*/
|
|
96
56
|
export interface AppliedIsolationPolicies {
|
|
97
57
|
readonly filesystemPolicyApplied: boolean;
|
|
98
58
|
readonly networkPolicyApplied: boolean;
|
|
99
59
|
}
|
|
100
60
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
* this with no argument at all is identical to the pre-existing constant,
|
|
104
|
-
* the same non-regression contract every other opt-in in this file
|
|
105
|
-
* (`applyResourceLimits`, `applySandbox`) already keeps.
|
|
61
|
+
* Mode-aware replacement for reading `SANDBOX_BOUNDARY_DISCLOSURE` unconditionally.
|
|
62
|
+
* Defaults to no-policy-applied, so a no-arg call matches the old constant exactly.
|
|
106
63
|
*
|
|
107
|
-
* **
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
* in this function. A caller in attach-mode should simply never pass
|
|
112
|
-
* anything but the default here, and the default's return value is this
|
|
113
|
-
* disclosure's original, unconditional "not isolated" text, unchanged.
|
|
64
|
+
* **Only ever true for spawn-mode.** Attach-mode has no path to produce
|
|
65
|
+
* `filesystemPolicyApplied`/`networkPolicyApplied: true` for a process it didn't
|
|
66
|
+
* spawn (structural, see `sandbox.ts`) -- attach-mode callers should never pass
|
|
67
|
+
* anything but the default.
|
|
114
68
|
*/
|
|
115
69
|
export declare function sandboxBoundaryDisclosureFor(policies?: AppliedIsolationPolicies): string;
|
|
116
70
|
/**
|
|
117
|
-
* Attach mode's
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
* `@descryy/runtime-contracts` for the interface-level statement this
|
|
122
|
-
* mirrors, and `sandbox.ts`'s own module doc for why attach-mode can never
|
|
123
|
-
* acquire the isolation `sandboxBoundaryDisclosureFor` describes for
|
|
124
|
-
* spawn-mode. Stated once, here, so every attach-mode caller surfaces the
|
|
125
|
-
* identical sentence rather than each writing its own paraphrase.
|
|
71
|
+
* Attach mode's contractual scope guarantee -- distinct from the sandbox-boundary
|
|
72
|
+
* disclosure above: this is what an attach-mode `Collector` is permitted to *do*, not
|
|
73
|
+
* what OS boundary wraps it. Mirrors `Collector` in `@descryy/runtime-contracts`.
|
|
74
|
+
* Stated once so every attach-mode caller surfaces the identical sentence.
|
|
126
75
|
*/
|
|
127
76
|
export declare const ATTACH_MODE_SCOPE_DISCLOSURE: string;
|
|
128
77
|
export interface PrivilegeReport {
|
|
129
|
-
/** Null when
|
|
78
|
+
/** Null when the platform has no uid concept (`process.getuid` undefined on Windows) -- distinct from `false`, a real answer. */
|
|
130
79
|
readonly runningAsRoot: boolean | null;
|
|
131
|
-
/** DEC-272: plain-language
|
|
80
|
+
/** DEC-272: plain-language sandbox boundary statement, carried on this result rather than a new return path. Always populated, independent of `runningAsRoot`. */
|
|
132
81
|
readonly disclosure: string;
|
|
133
82
|
}
|
|
134
83
|
/**
|
|
135
|
-
* Reports, never enforces. §21's
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
* privilege level becomes an observable fact instead of an invisible one,
|
|
140
|
-
* which is what nothing before RT-070 made it.
|
|
84
|
+
* Reports, never enforces. §21's policy for trusted-local (RT-070) is not "refuse to
|
|
85
|
+
* run as root" -- CI containers commonly do, and a hard refusal would turn a
|
|
86
|
+
* documented boundary into an undocumented outage. The privilege level just becomes
|
|
87
|
+
* observable instead of invisible.
|
|
141
88
|
*
|
|
142
|
-
* A required parameter, not
|
|
143
|
-
*
|
|
144
|
-
* (`
|
|
145
|
-
*
|
|
146
|
-
* "caller omitted the argument" -- both look identical to the function.
|
|
147
|
-
* `currentPrivilegeReport()` below is the zero-argument convenience wrapper
|
|
148
|
-
* real callers use; this is what makes both branches -- root, and no uid
|
|
149
|
-
* concept at all -- directly testable without this process actually
|
|
150
|
-
* needing to run as root or on Windows.
|
|
89
|
+
* A required parameter, not defaulted: `undefined` is the real value a no-uid-concept
|
|
90
|
+
* platform produces, and a default can't distinguish "explicitly undefined" from
|
|
91
|
+
* "omitted." `currentPrivilegeReport()` below is the convenience wrapper; this makes
|
|
92
|
+
* both branches testable without actually running as root or on Windows.
|
|
151
93
|
*/
|
|
152
94
|
export declare function privilegeReportFor(getuid: (() => number) | undefined): PrivilegeReport;
|
|
153
95
|
export declare function currentPrivilegeReport(): PrivilegeReport;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-safety.d.ts","sourceRoot":"","sources":["../src/execution-safety.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"execution-safety.d.ts","sourceRoot":"","sources":["../src/execution-safety.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAGnF,0KAA0K;AAC1K,wBAAgB,uBAAuB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,gBAAgB,CAU9F;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,gBAAgB,CAE9F;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,MAAM,EAAE,cAAc,GAAG,SAAS,EAClC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAchE;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,2BAA2B,QAGT,CAAC;AAEhC;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,uBAAuB,EAAE,OAAO,CAAC;IAC1C,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;CACxC;AAID;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,GAAE,wBAA8C,GAAG,MAAM,CAwB7G;AAED;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,QAKoC,CAAC;AAE9E,MAAM,WAAW,eAAe;IAC9B,iIAAiI;IACjI,QAAQ,CAAC,aAAa,EAAE,OAAO,GAAG,IAAI,CAAC;IACvC,kKAAkK;IAClK,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,GAAG,eAAe,CAGtF;AAED,wBAAgB,sBAAsB,IAAI,eAAe,CAExD"}
|
package/dist/execution-safety.js
CHANGED
|
@@ -1,30 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* §21's execution boundary
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* boundary instead of leaving it absent, which is what §38's "arbitrary
|
|
8
|
-
* application code runs without a defined safety boundary" actually bans.
|
|
9
|
-
* Real isolation (containers/namespaces) is a separate architectural
|
|
10
|
-
* decision this module does not invent (plan §29's own instruction).
|
|
2
|
+
* §21/RT-070's execution boundary: resource limits and privilege reporting for a
|
|
3
|
+
* runtime declared trusted-local -- every spawned process runs with the invoking
|
|
4
|
+
* user's own OS privileges, no filesystem/network restriction. Names the boundary
|
|
5
|
+
* rather than leaving it absent (§38); real isolation (containers/namespaces) is a
|
|
6
|
+
* separate decision this module does not invent (§29).
|
|
11
7
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* is util-linux and absent on macOS, so it is reported as a capability,
|
|
17
|
-
* never assumed.
|
|
8
|
+
* Enforces for real, via the OS: CPU time, virtual memory, process count, through
|
|
9
|
+
* `prlimit` -- an exec wrapper, never a shell (a shell would undo RT-036's
|
|
10
|
+
* `tokenizeCommand` refusal of shell metacharacters). `prlimit` is util-linux, absent
|
|
11
|
+
* on macOS, so it's reported as a capability, never assumed.
|
|
18
12
|
*/
|
|
19
13
|
import { execFileSync } from "node:child_process";
|
|
20
14
|
import { networkIsolationCapability } from "./sandbox.js";
|
|
21
|
-
/**
|
|
22
|
-
* Whether `prlimit` is reachable on this platform's `PATH`. Takes `env` as
|
|
23
|
-
* a parameter (defaulting to `process.env`) rather than reading it
|
|
24
|
-
* internally so the "unavailable" branch is directly testable without
|
|
25
|
-
* mutating this process's own real environment or depending on running on
|
|
26
|
-
* a platform that genuinely lacks it.
|
|
27
|
-
*/
|
|
15
|
+
/** Whether `prlimit` is reachable on PATH. `env` is a parameter (default `process.env`) so the "unavailable" branch is testable without mutating the real environment. */
|
|
28
16
|
export function resourceLimitCapability(env = process.env) {
|
|
29
17
|
try {
|
|
30
18
|
execFileSync("prlimit", ["--version"], { env, stdio: "ignore" });
|
|
@@ -38,32 +26,22 @@ export function resourceLimitCapability(env = process.env) {
|
|
|
38
26
|
}
|
|
39
27
|
}
|
|
40
28
|
/**
|
|
41
|
-
* RT-193 originally made this always `unavailable
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* every existing caller (`ExecutionController.run()`, this package's own
|
|
46
|
-
* tests) already imports, delegating rather than duplicating the check --
|
|
47
|
-
* exactly the seam RT-193's own comment anticipated ("if a real mechanism
|
|
48
|
-
* is ever built, this one function changes and every caller keeps working
|
|
49
|
-
* unmodified"). Still unconditionally `unavailable` on macOS/Windows, where
|
|
50
|
-
* nothing enforces it yet.
|
|
29
|
+
* RT-193 originally made this always `unavailable`. Now delegates to
|
|
30
|
+
* `networkIsolationCapability()` (`./sandbox.ts`), real on Linux via a bwrap network
|
|
31
|
+
* namespace -- kept as the stable name every caller already imports (the seam
|
|
32
|
+
* RT-193 anticipated). Still unconditionally `unavailable` on macOS/Windows.
|
|
51
33
|
*/
|
|
52
34
|
export function networkPolicyCapability(env = process.env) {
|
|
53
35
|
return networkIsolationCapability(env);
|
|
54
36
|
}
|
|
55
37
|
/**
|
|
56
|
-
* Wraps `command`/`args` so the OS enforces `limits`, via `prlimit`.
|
|
57
|
-
*
|
|
58
|
-
* every execution before RT-070 keeps behaving exactly as before unless it
|
|
59
|
-
* opts in.
|
|
38
|
+
* Wraps `command`/`args` so the OS enforces `limits`, via `prlimit`. `undefined` or
|
|
39
|
+
* empty `limits` returns them unchanged -- opt-in only.
|
|
60
40
|
*
|
|
61
|
-
* **Throws rather than silently spawning unconstrained** when a limit was
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* allocate without bound, silently -- exactly the "sandbox that doesn't
|
|
66
|
-
* sandbox" shape §38 bans, one row up from this one.
|
|
41
|
+
* **Throws rather than silently spawning unconstrained** when a limit was requested
|
|
42
|
+
* and `prlimit` is unavailable (refuse-not-guess, per RT-036) -- the alternative is a
|
|
43
|
+
* caller asking for a memory cap and silently getting an unbounded process, the
|
|
44
|
+
* "sandbox that doesn't sandbox" shape §38 bans.
|
|
67
45
|
*/
|
|
68
46
|
export function applyResourceLimits(command, args, limits, env = process.env) {
|
|
69
47
|
if (limits === undefined)
|
|
@@ -84,50 +62,30 @@ export function applyResourceLimits(command, args, limits, env = process.env) {
|
|
|
84
62
|
return { command: "prlimit", args: [...flags, "--", command, ...args] };
|
|
85
63
|
}
|
|
86
64
|
/**
|
|
87
|
-
* DEC-272
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* regardless of which privilege level was found; only the observed fact
|
|
91
|
-
* changes.
|
|
65
|
+
* DEC-272: the sandbox boundary (RT-070) must be stated to the user directly, not
|
|
66
|
+
* left as a silent doc gap. Fixed, not derived from `runningAsRoot` -- the boundary
|
|
67
|
+
* is the same regardless of privilege level found.
|
|
92
68
|
*
|
|
93
|
-
* **Scope
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
* that actually got a `FilesystemPolicy`/`NetworkPolicy` applied to it is
|
|
101
|
-
* genuinely more contained than "the same as if you started it yourself"
|
|
102
|
-
* says. Using this constant unconditionally for that process would be a
|
|
103
|
-
* real disclosure-accuracy bug -- understating a boundary is not the safe
|
|
104
|
-
* direction to be wrong in, it just happens to be a less alarming one.
|
|
105
|
-
* `sandboxBoundaryDisclosureFor()` below is the mode-aware replacement: it
|
|
106
|
-
* returns this exact string when no policy was applied (attach-mode always,
|
|
107
|
-
* and any spawn that declared none -- unchanged from before this lane), and
|
|
108
|
-
* a real, specific description of what is and is not contained when a
|
|
109
|
-
* policy genuinely was. This constant is kept, unchanged, as that function's
|
|
110
|
-
* own no-policy-applied return value and as attach-mode's own disclosure,
|
|
111
|
-
* not deprecated -- attach-mode never has anything more accurate to say.
|
|
69
|
+
* **Scope: this is the unconditional-unisolated text, not a universal one.** Accurate
|
|
70
|
+
* for every execution before `sandbox.ts` existed; no longer true once spawn-mode got
|
|
71
|
+
* real bwrap-backed isolation (`applySandbox`) -- using this unconditionally for an
|
|
72
|
+
* isolated process would understate its boundary, which is not the safe direction to
|
|
73
|
+
* be wrong in. `sandboxBoundaryDisclosureFor()` below is the mode-aware replacement;
|
|
74
|
+
* this constant remains its no-policy-applied return value and attach-mode's own
|
|
75
|
+
* disclosure (attach-mode never has anything more accurate to say).
|
|
112
76
|
*/
|
|
113
77
|
export const SANDBOX_BOUNDARY_DISCLOSURE = "This app runs with your own user permissions, the same as if you started it yourself. " +
|
|
114
78
|
"The filesystem and network are not isolated -- anything your own account could read, write, " +
|
|
115
79
|
"or reach, this run can too.";
|
|
116
80
|
const NO_POLICIES_APPLIED = { filesystemPolicyApplied: false, networkPolicyApplied: false };
|
|
117
81
|
/**
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
* this with no argument at all is identical to the pre-existing constant,
|
|
121
|
-
* the same non-regression contract every other opt-in in this file
|
|
122
|
-
* (`applyResourceLimits`, `applySandbox`) already keeps.
|
|
82
|
+
* Mode-aware replacement for reading `SANDBOX_BOUNDARY_DISCLOSURE` unconditionally.
|
|
83
|
+
* Defaults to no-policy-applied, so a no-arg call matches the old constant exactly.
|
|
123
84
|
*
|
|
124
|
-
* **
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* in this function. A caller in attach-mode should simply never pass
|
|
129
|
-
* anything but the default here, and the default's return value is this
|
|
130
|
-
* disclosure's original, unconditional "not isolated" text, unchanged.
|
|
85
|
+
* **Only ever true for spawn-mode.** Attach-mode has no path to produce
|
|
86
|
+
* `filesystemPolicyApplied`/`networkPolicyApplied: true` for a process it didn't
|
|
87
|
+
* spawn (structural, see `sandbox.ts`) -- attach-mode callers should never pass
|
|
88
|
+
* anything but the default.
|
|
131
89
|
*/
|
|
132
90
|
export function sandboxBoundaryDisclosureFor(policies = NO_POLICIES_APPLIED) {
|
|
133
91
|
const { filesystemPolicyApplied, networkPolicyApplied } = policies;
|
|
@@ -150,15 +108,10 @@ export function sandboxBoundaryDisclosureFor(policies = NO_POLICIES_APPLIED) {
|
|
|
150
108
|
"it can read, write, or reach anything your own account's filesystem could.");
|
|
151
109
|
}
|
|
152
110
|
/**
|
|
153
|
-
* Attach mode's
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
* `@descryy/runtime-contracts` for the interface-level statement this
|
|
158
|
-
* mirrors, and `sandbox.ts`'s own module doc for why attach-mode can never
|
|
159
|
-
* acquire the isolation `sandboxBoundaryDisclosureFor` describes for
|
|
160
|
-
* spawn-mode. Stated once, here, so every attach-mode caller surfaces the
|
|
161
|
-
* identical sentence rather than each writing its own paraphrase.
|
|
111
|
+
* Attach mode's contractual scope guarantee -- distinct from the sandbox-boundary
|
|
112
|
+
* disclosure above: this is what an attach-mode `Collector` is permitted to *do*, not
|
|
113
|
+
* what OS boundary wraps it. Mirrors `Collector` in `@descryy/runtime-contracts`.
|
|
114
|
+
* Stated once so every attach-mode caller surfaces the identical sentence.
|
|
162
115
|
*/
|
|
163
116
|
export const ATTACH_MODE_SCOPE_DISCLOSURE = "Attach mode observes an already-running process; it never executes code in it or applies changes to it. " +
|
|
164
117
|
"This is a permanent, documented architectural limitation, not a temporary gap -- there is no honest way to " +
|
|
@@ -166,22 +119,15 @@ export const ATTACH_MODE_SCOPE_DISCLOSURE = "Attach mode observes an already-run
|
|
|
166
119
|
"Respawn-and-supervise and the cgroup resource-limit move are real alternatives next to attach mode, not " +
|
|
167
120
|
"fixes to it; see their own documentation for what each actually gets you.";
|
|
168
121
|
/**
|
|
169
|
-
* Reports, never enforces. §21's
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
* privilege level becomes an observable fact instead of an invisible one,
|
|
174
|
-
* which is what nothing before RT-070 made it.
|
|
122
|
+
* Reports, never enforces. §21's policy for trusted-local (RT-070) is not "refuse to
|
|
123
|
+
* run as root" -- CI containers commonly do, and a hard refusal would turn a
|
|
124
|
+
* documented boundary into an undocumented outage. The privilege level just becomes
|
|
125
|
+
* observable instead of invisible.
|
|
175
126
|
*
|
|
176
|
-
* A required parameter, not
|
|
177
|
-
*
|
|
178
|
-
* (`
|
|
179
|
-
*
|
|
180
|
-
* "caller omitted the argument" -- both look identical to the function.
|
|
181
|
-
* `currentPrivilegeReport()` below is the zero-argument convenience wrapper
|
|
182
|
-
* real callers use; this is what makes both branches -- root, and no uid
|
|
183
|
-
* concept at all -- directly testable without this process actually
|
|
184
|
-
* needing to run as root or on Windows.
|
|
127
|
+
* A required parameter, not defaulted: `undefined` is the real value a no-uid-concept
|
|
128
|
+
* platform produces, and a default can't distinguish "explicitly undefined" from
|
|
129
|
+
* "omitted." `currentPrivilegeReport()` below is the convenience wrapper; this makes
|
|
130
|
+
* both branches testable without actually running as root or on Windows.
|
|
185
131
|
*/
|
|
186
132
|
export function privilegeReportFor(getuid) {
|
|
187
133
|
if (getuid === undefined)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-safety.js","sourceRoot":"","sources":["../src/execution-safety.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"execution-safety.js","sourceRoot":"","sources":["../src/execution-safety.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -20,16 +20,6 @@ export type { DependencyVersionMismatch, DependencyVersionCheckResult } from "./
|
|
|
20
20
|
export { checkDependencyVersions } from "./dependency-version-check.ts";
|
|
21
21
|
export type { DeclaredVersionSource, EnvironmentVersionCheckResult } from "./environment-version-check.ts";
|
|
22
22
|
export { DECLARED_VERSION_SOURCES, checkEnvironmentVersion, satisfiesDeclaredNodeVersion } from "./environment-version-check.ts";
|
|
23
|
-
/**
|
|
24
|
-
* RT-073: promoted from internal-only. `tokenizeCommand`'s POSIX-style
|
|
25
|
-
* "refuse rather than guess" tokenizer is exactly what `packages/test-runner`
|
|
26
|
-
* needs to validate a declared runner command before spawning it -- the
|
|
27
|
-
* same job it already does for `ServiceConfiguration.command` here.
|
|
28
|
-
* Re-implementing a second copy for one more caller would be the "two
|
|
29
|
-
* shapes that could drift" mistake this codebase has already named and
|
|
30
|
-
* avoided elsewhere (RT-068's `BrowserConfiguration`, RT-070's
|
|
31
|
-
* `ResourceLimits`).
|
|
32
|
-
*/
|
|
33
23
|
export type { CommandTokenization, ServicesValidation } from "./orchestration.ts";
|
|
34
24
|
export { tokenizeCommand, validateServicesConfiguration, substitutePortPlaceholders } from "./orchestration.ts";
|
|
35
25
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAEjD,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACvH,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE1F,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,wBAAwB,EACxB,cAAc,EACd,eAAe,EACf,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEtE,YAAY,EAAE,oBAAoB,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,YAAY,EAAE,+BAA+B,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AACxG,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAE5F,YAAY,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACvF,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACtB,2BAA2B,EAC3B,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EACL,6BAA6B,EAC7B,0BAA0B,EAC1B,8BAA8B,EAC9B,0BAA0B,EAC1B,YAAY,GACb,MAAM,cAAc,CAAC;AAEtB,YAAY,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EACL,0BAA0B,EAC1B,sCAAsC,EACtC,mCAAmC,EACnC,uCAAuC,EACvC,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAEvE,YAAY,EAAE,yBAAyB,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAC7G,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAExE,YAAY,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,MAAM,gCAAgC,CAAC;AAC3G,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAEjD,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACvH,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE1F,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,wBAAwB,EACxB,cAAc,EACd,eAAe,EACf,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEtE,YAAY,EAAE,oBAAoB,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,YAAY,EAAE,+BAA+B,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AACxG,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAE5F,YAAY,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACvF,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACtB,2BAA2B,EAC3B,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EACL,6BAA6B,EAC7B,0BAA0B,EAC1B,8BAA8B,EAC9B,0BAA0B,EAC1B,YAAY,GACb,MAAM,cAAc,CAAC;AAEtB,YAAY,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EACL,0BAA0B,EAC1B,sCAAsC,EACtC,mCAAmC,EACnC,uCAAuC,EACvC,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAEvE,YAAY,EAAE,yBAAyB,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAC7G,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAExE,YAAY,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,MAAM,gCAAgC,CAAC;AAC3G,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAKjI,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,6BAA6B,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAGjD,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAa1F,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAGtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAGhE,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAG5F,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACtB,2BAA2B,EAC3B,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,6BAA6B,EAC7B,0BAA0B,EAC1B,8BAA8B,EAC9B,0BAA0B,EAC1B,YAAY,GACb,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,0BAA0B,EAC1B,sCAAsC,EACtC,mCAAmC,EACnC,uCAAuC,EACvC,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAGvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAGxE,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAGjD,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAa1F,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAGtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAGhE,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAG5F,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACtB,2BAA2B,EAC3B,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,6BAA6B,EAC7B,0BAA0B,EAC1B,8BAA8B,EAC9B,0BAA0B,EAC1B,YAAY,GACb,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,0BAA0B,EAC1B,sCAAsC,EACtC,mCAAmC,EACnC,uCAAuC,EACvC,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAGvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAGxE,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAMjI,OAAO,EAAE,eAAe,EAAE,6BAA6B,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/orchestration.d.ts
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Turns a declarative `services` map (
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* mid-sequence with some services already running.
|
|
2
|
+
* Turns a declarative `services` map (§6, RT-028) into a concrete spawn order for
|
|
3
|
+
* `ExecutionController.run()` (RT-032). Pure and side-effect-free -- validated and
|
|
4
|
+
* ordered before anything is spawned, so a bad reference is refused atomically
|
|
5
|
+
* rather than discovered mid-sequence.
|
|
7
6
|
*
|
|
8
|
-
* Start order and port injection are
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* does not create an ordering guarantee; `name` must also appear in the
|
|
12
|
-
* referencing service's own `dependsOn`, or validation refuses.
|
|
7
|
+
* Start order and port injection are declared, never inferred (RT-023's "ask, don't
|
|
8
|
+
* guess"): a `${name.port}` reference alone doesn't create an ordering guarantee --
|
|
9
|
+
* `name` must also appear in the referencing service's `dependsOn`, or validation refuses.
|
|
13
10
|
*/
|
|
14
11
|
import type { ServiceConfiguration } from "@descryy/runtime-contracts";
|
|
15
12
|
export type ServicesValidation = {
|
|
@@ -20,23 +17,17 @@ export type ServicesValidation = {
|
|
|
20
17
|
readonly reason: string;
|
|
21
18
|
};
|
|
22
19
|
/**
|
|
23
|
-
* Validates a `services` map and returns a
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* 3. every `${name}.port` placeholder referenced in a service's own `env`
|
|
28
|
-
* has `name` in that same service's `dependsOn` — the placeholder does
|
|
29
|
-
* not itself create the ordering guarantee it depends on.
|
|
20
|
+
* Validates a `services` map and returns a topological spawn order. Checks, all
|
|
21
|
+
* before anything is spawned: every `dependsOn` names a real key; the `dependsOn`
|
|
22
|
+
* graph has no cycle; every `${name}.port` placeholder in a service's `env` has
|
|
23
|
+
* `name` in that service's own `dependsOn`.
|
|
30
24
|
*/
|
|
31
25
|
export declare function validateServicesConfiguration(services: Readonly<Record<string, ServiceConfiguration>>): ServicesValidation;
|
|
32
26
|
/**
|
|
33
|
-
* Replaces every `${name}.port` in `env`'s values with the resolved port
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* resolve is left untouched rather than silently dropped, so a caller that
|
|
38
|
-
* skipped validation sees an obviously-wrong literal `${...}` instead of a
|
|
39
|
-
* silently empty substitution.
|
|
27
|
+
* Replaces every `${name}.port` in `env`'s values with the resolved port for `name`.
|
|
28
|
+
* Assumes `validateServicesConfiguration` already confirmed the reference. An
|
|
29
|
+
* unresolvable reference is left untouched, not dropped -- a caller that skipped
|
|
30
|
+
* validation sees an obviously-wrong literal instead of a silent empty substitution.
|
|
40
31
|
*/
|
|
41
32
|
export declare function substitutePortPlaceholders(env: Readonly<Record<string, string>> | undefined, resolvedPorts: ReadonlyMap<string, number>): Record<string, string>;
|
|
42
33
|
export type CommandTokenization = {
|
|
@@ -48,23 +39,17 @@ export type CommandTokenization = {
|
|
|
48
39
|
readonly reason: string;
|
|
49
40
|
};
|
|
50
41
|
/**
|
|
51
|
-
* POSIX-style tokenizer for `ServiceConfiguration.command`: single quotes
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* separately
|
|
55
|
-
* so something has to split it, and doing that by whitespace alone breaks
|
|
56
|
-
* every path with a space in it — `"C:\Program Files\node.exe"` and
|
|
57
|
-
* `python3 -c "import app; app.main()"` both tokenized wrong before.
|
|
42
|
+
* POSIX-style tokenizer for `ServiceConfiguration.command`: single quotes (literal),
|
|
43
|
+
* double quotes (`\` escapes `"` and `\`), backslash escapes outside quotes. Needed
|
|
44
|
+
* because config carries one string (§6) but `spawnProcess` wants `command`/`args`
|
|
45
|
+
* separately, and plain whitespace-split breaks paths with spaces.
|
|
58
46
|
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* for input that cannot mean what it says is how a configuration error
|
|
63
|
-
* arrives disguised as an application failure.
|
|
47
|
+
* Refuses rather than guesses on an unterminated quote, trailing backslash, or
|
|
48
|
+
* unquoted shell operator -- a plausible-but-wrong tokenization would disguise a
|
|
49
|
+
* config error as an application failure.
|
|
64
50
|
*
|
|
65
|
-
* Globs and `~`
|
|
66
|
-
*
|
|
67
|
-
* are frequently intended literally.
|
|
51
|
+
* Globs and `~` pass through literally, unrefused -- exactly what happens with no
|
|
52
|
+
* shell, and frequently intended literally.
|
|
68
53
|
*/
|
|
69
54
|
export declare function tokenizeCommand(raw: string): CommandTokenization;
|
|
70
55
|
//# sourceMappingURL=orchestration.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestration.d.ts","sourceRoot":"","sources":["../src/orchestration.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"orchestration.d.ts","sourceRoot":"","sources":["../src/orchestration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAUvE,MAAM,MAAM,kBAAkB,GAC1B;IAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAC3D;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,GACvD,kBAAkB,CAyDpB;AAkCD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,EACjD,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACzC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CASxB;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GACjF;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAWpD;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,CA6EhE"}
|