@stigmer/cli 3.15.0 → 3.15.1
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/commands/internal-daemon.d.ts.map +1 -1
- package/commands/internal-daemon.js +2 -9
- package/commands/internal-daemon.js.map +1 -1
- package/commands/up.d.ts.map +1 -1
- package/commands/up.js +37 -8
- package/commands/up.js.map +1 -1
- package/local/artifact.d.ts +13 -3
- package/local/artifact.d.ts.map +1 -1
- package/local/artifact.js +31 -10
- package/local/artifact.js.map +1 -1
- package/local/daemon/components.d.ts.map +1 -1
- package/local/daemon/components.js +2 -0
- package/local/daemon/components.js.map +1 -1
- package/local/daemon/host.d.ts +8 -0
- package/local/daemon/host.d.ts.map +1 -1
- package/local/daemon/host.js +42 -1
- package/local/daemon/host.js.map +1 -1
- package/local/daemon/index.d.ts +3 -3
- package/local/daemon/index.d.ts.map +1 -1
- package/local/daemon/index.js +2 -2
- package/local/daemon/index.js.map +1 -1
- package/local/daemon/launch.d.ts +29 -1
- package/local/daemon/launch.d.ts.map +1 -1
- package/local/daemon/launch.js +73 -23
- package/local/daemon/launch.js.map +1 -1
- package/local/daemon/process.d.ts +16 -2
- package/local/daemon/process.d.ts.map +1 -1
- package/local/daemon/process.js +16 -2
- package/local/daemon/process.js.map +1 -1
- package/local/daemon/types.d.ts +2 -0
- package/local/daemon/types.d.ts.map +1 -1
- package/local/paths.d.ts +14 -4
- package/local/paths.d.ts.map +1 -1
- package/local/paths.js +17 -4
- package/local/paths.js.map +1 -1
- package/local/runtime/runner.d.ts +4 -0
- package/local/runtime/runner.d.ts.map +1 -1
- package/local/runtime/runner.js +10 -6
- package/local/runtime/runner.js.map +1 -1
- package/local/runtime/server.d.ts +5 -0
- package/local/runtime/server.d.ts.map +1 -1
- package/local/runtime/server.js +13 -8
- package/local/runtime/server.js.map +1 -1
- package/local/seedpack/content.d.ts +4 -0
- package/local/seedpack/content.d.ts.map +1 -1
- package/local/seedpack/content.js +11 -11
- package/local/seedpack/content.js.map +1 -1
- package/local/state/lock.d.ts +3 -2
- package/local/state/lock.d.ts.map +1 -1
- package/local/state/lock.js +23 -9
- package/local/state/lock.js.map +1 -1
- package/local/state/proc.d.ts +13 -0
- package/local/state/proc.d.ts.map +1 -1
- package/local/state/proc.js +15 -0
- package/local/state/proc.js.map +1 -1
- package/local/temporal/download.d.ts +7 -1
- package/local/temporal/download.d.ts.map +1 -1
- package/local/temporal/download.js +21 -11
- package/local/temporal/download.js.map +1 -1
- package/local/temporal/index.d.ts +3 -3
- package/local/temporal/index.d.ts.map +1 -1
- package/local/temporal/index.js +2 -2
- package/local/temporal/index.js.map +1 -1
- package/local/temporal/inspect.d.ts +10 -3
- package/local/temporal/inspect.d.ts.map +1 -1
- package/local/temporal/inspect.js +52 -13
- package/local/temporal/inspect.js.map +1 -1
- package/local/temporal/manager.d.ts +16 -4
- package/local/temporal/manager.d.ts.map +1 -1
- package/local/temporal/manager.js +19 -6
- package/local/temporal/manager.js.map +1 -1
- package/package.json +5 -5
- package/src/commands/internal-daemon.ts +2 -10
- package/src/commands/up.ts +52 -8
- package/src/local/artifact.test.ts +27 -1
- package/src/local/artifact.ts +35 -13
- package/src/local/daemon/components.ts +2 -0
- package/src/local/daemon/daemon.integration.test.ts +33 -0
- package/src/local/daemon/host.ts +50 -1
- package/src/local/daemon/index.ts +3 -3
- package/src/local/daemon/launch.test.ts +136 -0
- package/src/local/daemon/launch.ts +108 -27
- package/src/local/daemon/process.ts +31 -4
- package/src/local/daemon/supervisor.test.ts +1 -1
- package/src/local/daemon/types.ts +2 -0
- package/src/local/paths.ts +17 -4
- package/src/local/runtime/runner.ts +10 -6
- package/src/local/runtime/runtime.test.ts +15 -0
- package/src/local/runtime/server.test.ts +37 -0
- package/src/local/runtime/server.ts +17 -12
- package/src/local/seedpack/content.test.ts +21 -0
- package/src/local/seedpack/content.ts +15 -16
- package/src/local/state/lock.ts +24 -9
- package/src/local/state/proc.ts +16 -0
- package/src/local/state/state.test.ts +25 -1
- package/src/local/temporal/download.test.ts +79 -11
- package/src/local/temporal/download.ts +24 -11
- package/src/local/temporal/index.ts +11 -3
- package/src/local/temporal/inspect.test.ts +83 -0
- package/src/local/temporal/inspect.ts +60 -12
- package/src/local/temporal/manager.test.ts +34 -1
- package/src/local/temporal/manager.ts +22 -8
|
@@ -27,6 +27,7 @@ import { ExitCode } from "../../errors/exit-codes.js";
|
|
|
27
27
|
import { log } from "../../logger.js";
|
|
28
28
|
import { VERSION } from "../../version.js";
|
|
29
29
|
import { runtimesDir } from "../paths.js";
|
|
30
|
+
import { isAcquirableRelease } from "../runtime/runtimes-install.js";
|
|
30
31
|
const SEEDPACK_PACKAGE = "@stigmer/seedpack";
|
|
31
32
|
/**
|
|
32
33
|
* The canonical seedpack entries, in apply-safe order. Kept in sync with
|
|
@@ -61,20 +62,24 @@ export function resolveSeedpackContent(opts = {}) {
|
|
|
61
62
|
* ~/.stigmer/runtimes/<version>/ (idempotent) and return its package directory.
|
|
62
63
|
* The version is pinned to the CLI's own version so system content stays in
|
|
63
64
|
* lockstep with the control plane it bootstraps.
|
|
65
|
+
*
|
|
66
|
+
* Presence beats acquirability (the server acquirer's rule, stated in
|
|
67
|
+
* runtime/server.ts): installed content is used whatever its version string;
|
|
68
|
+
* only an install we would have to perform is refused for a non-release build.
|
|
64
69
|
*/
|
|
65
70
|
export function acquireSeedpack(opts = {}) {
|
|
66
71
|
const home = opts.home ?? homedir();
|
|
67
72
|
const version = opts.version ?? VERSION;
|
|
68
|
-
if (!isAcquirableRelease(version)) {
|
|
69
|
-
throw new CliExitError(`cannot acquire ${SEEDPACK_PACKAGE} for a non-release build (${version})`, ExitCode.General, [
|
|
70
|
-
"Run from the repo (the seedpack/ tree is used directly in dev).",
|
|
71
|
-
"On-demand acquisition is only available for published releases.",
|
|
72
|
-
]);
|
|
73
|
-
}
|
|
74
73
|
const installDir = join(runtimesDir(home), version);
|
|
75
74
|
const pkgDir = join(installDir, "node_modules", "@stigmer", "seedpack");
|
|
76
75
|
const marker = join(pkgDir, "stigmer.yaml");
|
|
77
76
|
if (!existsSync(marker)) {
|
|
77
|
+
if (!isAcquirableRelease(version)) {
|
|
78
|
+
throw new CliExitError(`cannot acquire ${SEEDPACK_PACKAGE} for a non-release build (${version})`, ExitCode.General, [
|
|
79
|
+
"Run from the repo (the seedpack/ tree is used directly in dev).",
|
|
80
|
+
"On-demand acquisition is only available for published releases.",
|
|
81
|
+
]);
|
|
82
|
+
}
|
|
78
83
|
log.info(`acquiring ${SEEDPACK_PACKAGE}`, { version, dir: installDir });
|
|
79
84
|
mkdirSync(installDir, { recursive: true });
|
|
80
85
|
// A stable package.json root keeps the install deterministic. npm install is
|
|
@@ -185,11 +190,6 @@ export function writeMarker(markerDir, hash) {
|
|
|
185
190
|
function toPosix(p) {
|
|
186
191
|
return sep === posix.sep ? p : p.split(sep).join(posix.sep);
|
|
187
192
|
}
|
|
188
|
-
// A source build reports "0.0.0-dev" and the dev channel stamps "<v>-dev.<stamp>";
|
|
189
|
-
// neither publishes a matching @stigmer/seedpack, so they are not acquirable.
|
|
190
|
-
function isAcquirableRelease(version) {
|
|
191
|
-
return !version.includes("-dev");
|
|
192
|
-
}
|
|
193
193
|
// Walk up from this module to a repo root containing seedpack/stigmer.yaml.
|
|
194
194
|
function repoSeedpackDir() {
|
|
195
195
|
let dir = dirname(fileURLToPath(import.meta.url));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../../src/local/seedpack/content.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,EAAE;AACF,wEAAwE;AACxE,2EAA2E;AAC3E,+EAA+E;AAC/E,4EAA4E;AAC5E,qEAAqE;AACrE,EAAE;AACF,2DAA2D;AAC3D,sDAAsD;AACtD,iFAAiF;AACjF,oDAAoD;AACpD,uCAAuC;AACvC,EAAE;AACF,iFAAiF;AACjF,6EAA6E;AAC7E,8EAA8E;AAC9E,kFAAkF;AAElF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,MAAM,EACN,UAAU,EACV,SAAS,EACT,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../../src/local/seedpack/content.ts"],"names":[],"mappings":"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"}
|
package/local/state/lock.d.ts
CHANGED
|
@@ -5,8 +5,9 @@ export interface FileLock {
|
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
7
|
* Try to acquire the lock at `path`. Returns a FileLock on success, or null if
|
|
8
|
-
* the lock is held by a live process
|
|
9
|
-
*
|
|
8
|
+
* the lock is held by a live process (this one included — a second acquire
|
|
9
|
+
* while we hold it fails). A lock left behind by a dead process, or by a past
|
|
10
|
+
* process that had our pid, is reclaimed automatically.
|
|
10
11
|
*/
|
|
11
12
|
export declare function acquireLock(path: string): FileLock | null;
|
|
12
13
|
//# sourceMappingURL=lock.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../../src/local/state/lock.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../../src/local/state/lock.ts"],"names":[],"mappings":"AAiBA,0DAA0D;AAC1D,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,IAAI,IAAI,CAAC;CACjB;AAQD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAkBzD"}
|
package/local/state/lock.js
CHANGED
|
@@ -4,25 +4,37 @@
|
|
|
4
4
|
// lock and whose contents are the owning PID. Creation uses the "wx" flag
|
|
5
5
|
// (O_CREAT | O_EXCL), which is atomic on POSIX and Windows, so two racing
|
|
6
6
|
// acquirers cannot both win. If the file already exists we read the owner PID:
|
|
7
|
-
// a
|
|
8
|
-
//
|
|
9
|
-
//
|
|
7
|
+
// a live peer means the lock is genuinely held; a dead owner means a stale
|
|
8
|
+
// lock we may reclaim; an owner PID that is OUR OWN is held only if this
|
|
9
|
+
// process is actually holding it (tracked in-process), otherwise it is a
|
|
10
|
+
// leftover from a previous life of the PID (see isOtherLiveProcess) and stale.
|
|
11
|
+
// This guards the Temporal dev server against double-start the way the Go
|
|
12
|
+
// CLI's flock does, without a native dependency.
|
|
10
13
|
import { closeSync, mkdirSync, openSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
11
14
|
import { dirname } from "node:path";
|
|
12
|
-
import {
|
|
15
|
+
import { isOtherLiveProcess } from "./proc.js";
|
|
16
|
+
// Lock paths this process currently holds. A lock file naming OUR pid is
|
|
17
|
+
// genuinely held only if it is in here; otherwise it is a leftover from a
|
|
18
|
+
// previous life of the pid (a restarted container, a rebooted laptop) and is
|
|
19
|
+
// reclaimed like any other stale lock.
|
|
20
|
+
const heldInProcess = new Set();
|
|
13
21
|
/**
|
|
14
22
|
* Try to acquire the lock at `path`. Returns a FileLock on success, or null if
|
|
15
|
-
* the lock is held by a live process
|
|
16
|
-
*
|
|
23
|
+
* the lock is held by a live process (this one included — a second acquire
|
|
24
|
+
* while we hold it fails). A lock left behind by a dead process, or by a past
|
|
25
|
+
* process that had our pid, is reclaimed automatically.
|
|
17
26
|
*/
|
|
18
27
|
export function acquireLock(path) {
|
|
19
28
|
mkdirSync(dirname(path), { recursive: true });
|
|
29
|
+
if (heldInProcess.has(path))
|
|
30
|
+
return null; // held right here, by us
|
|
20
31
|
if (tryCreate(path))
|
|
21
32
|
return makeLock(path);
|
|
22
|
-
// The lock file exists. Reclaim it only if its owner is gone
|
|
33
|
+
// The lock file exists. Reclaim it only if its owner is gone, or is our own
|
|
34
|
+
// pid from a previous life (we just established we are not holding it).
|
|
23
35
|
const owner = readOwner(path);
|
|
24
|
-
if (owner !== null &&
|
|
25
|
-
return null; // genuinely held by a live
|
|
36
|
+
if (owner !== null && isOtherLiveProcess(owner)) {
|
|
37
|
+
return null; // genuinely held by a live peer
|
|
26
38
|
}
|
|
27
39
|
// Stale (or unreadable) lock: remove and retry exactly once. A failure on the
|
|
28
40
|
// retry means another process raced us to it — treat the lock as held.
|
|
@@ -53,6 +65,7 @@ function readOwner(path) {
|
|
|
53
65
|
}
|
|
54
66
|
}
|
|
55
67
|
function makeLock(path) {
|
|
68
|
+
heldInProcess.add(path);
|
|
56
69
|
let released = false;
|
|
57
70
|
return {
|
|
58
71
|
path,
|
|
@@ -60,6 +73,7 @@ function makeLock(path) {
|
|
|
60
73
|
if (released)
|
|
61
74
|
return;
|
|
62
75
|
released = true;
|
|
76
|
+
heldInProcess.delete(path);
|
|
63
77
|
// Only remove the file if we still own it, so we never delete a lock a
|
|
64
78
|
// different process acquired after ours was (somehow) gone.
|
|
65
79
|
if (readOwner(path) === process.pid)
|
package/local/state/lock.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../../../src/local/state/lock.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,EAAE;AACF,6EAA6E;AAC7E,0EAA0E;AAC1E,0EAA0E;AAC1E,+EAA+E;AAC/E,
|
|
1
|
+
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../../../src/local/state/lock.ts"],"names":[],"mappings":"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"}
|
package/local/state/proc.d.ts
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
/** Report whether a process with the given PID currently exists. */
|
|
2
2
|
export declare function isProcessAlive(pid: number): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Report whether `pid` names a live process OTHER than this one — the question
|
|
5
|
+
* every stale-state reader (a PID file, a lock file's owner) actually asks.
|
|
6
|
+
*
|
|
7
|
+
* A recorded PID equal to our own can never be a live peer: we did not write it
|
|
8
|
+
* in this life, so it is a leftover from a previous process that happened to
|
|
9
|
+
* get the same number. That happens deterministically in a container (every
|
|
10
|
+
* start is a fresh PID namespace, so the daemon lands on the same low PID it
|
|
11
|
+
* had before the unclean stop) and occasionally on a laptop after a reboot.
|
|
12
|
+
* Treating such a PID as "alive" makes a launcher SIGTERM itself or refuse a
|
|
13
|
+
* lock it could never have been holding.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isOtherLiveProcess(pid: number): boolean;
|
|
3
16
|
/** Send a signal to a single process. Returns false if the process is gone. */
|
|
4
17
|
export declare function killProcess(pid: number, signal?: NodeJS.Signals): boolean;
|
|
5
18
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proc.d.ts","sourceRoot":"","sources":["../../../src/local/state/proc.ts"],"names":[],"mappings":"AASA,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CASnD;AAED,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,OAAmB,GAAG,OAAO,CAOpF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,OAAmB,GAAG,OAAO,CASzF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAc7D"}
|
|
1
|
+
{"version":3,"file":"proc.d.ts","sourceRoot":"","sources":["../../../src/local/state/proc.ts"],"names":[],"mappings":"AASA,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CASnD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,OAAmB,GAAG,OAAO,CAOpF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,OAAmB,GAAG,OAAO,CASzF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAc7D"}
|
package/local/state/proc.js
CHANGED
|
@@ -18,6 +18,21 @@ export function isProcessAlive(pid) {
|
|
|
18
18
|
return err.code === "EPERM";
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Report whether `pid` names a live process OTHER than this one — the question
|
|
23
|
+
* every stale-state reader (a PID file, a lock file's owner) actually asks.
|
|
24
|
+
*
|
|
25
|
+
* A recorded PID equal to our own can never be a live peer: we did not write it
|
|
26
|
+
* in this life, so it is a leftover from a previous process that happened to
|
|
27
|
+
* get the same number. That happens deterministically in a container (every
|
|
28
|
+
* start is a fresh PID namespace, so the daemon lands on the same low PID it
|
|
29
|
+
* had before the unclean stop) and occasionally on a laptop after a reboot.
|
|
30
|
+
* Treating such a PID as "alive" makes a launcher SIGTERM itself or refuse a
|
|
31
|
+
* lock it could never have been holding.
|
|
32
|
+
*/
|
|
33
|
+
export function isOtherLiveProcess(pid) {
|
|
34
|
+
return pid !== process.pid && isProcessAlive(pid);
|
|
35
|
+
}
|
|
21
36
|
/** Send a signal to a single process. Returns false if the process is gone. */
|
|
22
37
|
export function killProcess(pid, signal = "SIGTERM") {
|
|
23
38
|
try {
|
package/local/state/proc.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proc.js","sourceRoot":"","sources":["../../../src/local/state/proc.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,EAAE;AACF,+EAA+E;AAC/E,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAE7E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,oEAAoE;AACpE,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACrD,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,6EAA6E;QAC7E,OAAQ,GAA6B,CAAC,IAAI,KAAK,OAAO,CAAC;IACzD,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,SAAyB,SAAS;IACzE,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW,EAAE,SAAyB,SAAS;IAC9E,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACrD,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,6EAA6E;QAC7E,OAAO,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAClC,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,EAAE,cAAc,CAAC,EAAE;YACtE,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACxE,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAClD,OAAO,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AACvD,CAAC"}
|
|
1
|
+
{"version":3,"file":"proc.js","sourceRoot":"","sources":["../../../src/local/state/proc.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,EAAE;AACF,+EAA+E;AAC/E,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAE7E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,oEAAoE;AACpE,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACrD,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,6EAA6E;QAC7E,OAAQ,GAA6B,CAAC,IAAI,KAAK,OAAO,CAAC;IACzD,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,OAAO,GAAG,KAAK,OAAO,CAAC,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC;AACpD,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,SAAyB,SAAS;IACzE,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW,EAAE,SAAyB,SAAS;IAC9E,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACrD,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,6EAA6E;QAC7E,OAAO,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAClC,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,EAAE,cAAc,CAAC,EAAE;YACtE,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACxE,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAClD,OAAO,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AACvD,CAAC"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { extractTarEntry } from "../artifact.js";
|
|
2
2
|
/** Default Temporal CLI version (matches the Go CLI's `DefaultTemporalVersion`). */
|
|
3
3
|
export declare const DEFAULT_TEMPORAL_VERSION = "1.5.1";
|
|
4
|
+
/** The release's `sha256sum`-format digest file, one line per published asset. */
|
|
5
|
+
export declare const TEMPORAL_CHECKSUMS_FILE = "checksums.txt";
|
|
4
6
|
export interface TemporalDownloadTarget {
|
|
5
7
|
/** Temporal CLI version, e.g. "1.5.1". */
|
|
6
8
|
version: string;
|
|
@@ -13,7 +15,11 @@ export interface TemporalDownloadTarget {
|
|
|
13
15
|
/** Override the fetch implementation (tests). */
|
|
14
16
|
fetchImpl?: typeof fetch;
|
|
15
17
|
}
|
|
16
|
-
/**
|
|
18
|
+
/** The release asset name for a version on a platform, as Temporal publishes it. */
|
|
19
|
+
export declare function temporalArchiveName(version: string, platform: NodeJS.Platform, arch: string): string;
|
|
20
|
+
/** The GitHub release download URL for one asset of a version. */
|
|
21
|
+
export declare function temporalReleaseAssetUrl(version: string, asset: string): string;
|
|
22
|
+
/** Download, verify and install the Temporal CLI binary to `binPath`. */
|
|
17
23
|
export declare function downloadTemporalCli(target: TemporalDownloadTarget): Promise<void>;
|
|
18
24
|
/** True if a Temporal binary is already present at `binPath`. */
|
|
19
25
|
export declare function isTemporalInstalled(binPath: string): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../../src/local/temporal/download.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../../src/local/temporal/download.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,oFAAoF;AACpF,eAAO,MAAM,wBAAwB,UAAU,CAAC;AAEhD,kFAAkF;AAClF,eAAO,MAAM,uBAAuB,kBAAkB,CAAC;AAEvD,MAAM,WAAW,sBAAsB;IACrC,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,oFAAoF;AACpF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpG;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE9E;AAED,yEAAyE;AACzE,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAWvF;AAED,iEAAiE;AACjE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE5D"}
|
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
//
|
|
3
3
|
// `up` needs a `temporal` binary and the upstream release is a small, public,
|
|
4
4
|
// stable artifact. The fetch/gunzip/untar/write mechanics are shared with the
|
|
5
|
-
//
|
|
6
|
-
// asset-naming and the default version.
|
|
5
|
+
// other release downloaders in `../artifact.ts`; this module only owns
|
|
6
|
+
// Temporal's asset-naming and the default version.
|
|
7
7
|
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
8
|
+
// Every download is verified against the release's `checksums.txt` (the
|
|
9
|
+
// `sha256sum` file Temporal publishes beside its archives) before the binary is
|
|
10
|
+
// written: the integrity guarantee is the published digest, not merely HTTPS
|
|
11
|
+
// plus GitHub's release immutability. The same code path stages the binary the
|
|
12
|
+
// all-in-one image bakes, so one pin and one verification serve every channel.
|
|
11
13
|
import { existsSync } from "node:fs";
|
|
12
14
|
import { fetchTarballBinary, mapReleaseArch, mapReleaseOs } from "../artifact.js";
|
|
13
15
|
// Re-exported so existing consumers (temporal/index.ts, download.test.ts) keep
|
|
@@ -15,14 +17,22 @@ import { fetchTarballBinary, mapReleaseArch, mapReleaseOs } from "../artifact.js
|
|
|
15
17
|
export { extractTarEntry } from "../artifact.js";
|
|
16
18
|
/** Default Temporal CLI version (matches the Go CLI's `DefaultTemporalVersion`). */
|
|
17
19
|
export const DEFAULT_TEMPORAL_VERSION = "1.5.1";
|
|
18
|
-
/**
|
|
20
|
+
/** The release's `sha256sum`-format digest file, one line per published asset. */
|
|
21
|
+
export const TEMPORAL_CHECKSUMS_FILE = "checksums.txt";
|
|
22
|
+
/** The release asset name for a version on a platform, as Temporal publishes it. */
|
|
23
|
+
export function temporalArchiveName(version, platform, arch) {
|
|
24
|
+
return `temporal_cli_${version}_${mapReleaseOs(platform)}_${mapReleaseArch(arch)}.tar.gz`;
|
|
25
|
+
}
|
|
26
|
+
/** The GitHub release download URL for one asset of a version. */
|
|
27
|
+
export function temporalReleaseAssetUrl(version, asset) {
|
|
28
|
+
return `https://github.com/temporalio/cli/releases/download/v${version}/${asset}`;
|
|
29
|
+
}
|
|
30
|
+
/** Download, verify and install the Temporal CLI binary to `binPath`. */
|
|
19
31
|
export async function downloadTemporalCli(target) {
|
|
20
|
-
const
|
|
21
|
-
const goarch = mapReleaseArch(target.arch ?? process.arch);
|
|
22
|
-
const archive = `temporal_cli_${target.version}_${goos}_${goarch}.tar.gz`;
|
|
23
|
-
const url = `https://github.com/temporalio/cli/releases/download/v${target.version}/${archive}`;
|
|
32
|
+
const archive = temporalArchiveName(target.version, target.platform ?? process.platform, target.arch ?? process.arch);
|
|
24
33
|
await fetchTarballBinary({
|
|
25
|
-
url,
|
|
34
|
+
url: temporalReleaseAssetUrl(target.version, archive),
|
|
35
|
+
checksumUrl: temporalReleaseAssetUrl(target.version, TEMPORAL_CHECKSUMS_FILE),
|
|
26
36
|
entryName: "temporal",
|
|
27
37
|
binPath: target.binPath,
|
|
28
38
|
label: "Temporal CLI",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download.js","sourceRoot":"","sources":["../../../src/local/temporal/download.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,EAAE;AACF,8EAA8E;AAC9E,8EAA8E;AAC9E,
|
|
1
|
+
{"version":3,"file":"download.js","sourceRoot":"","sources":["../../../src/local/temporal/download.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,EAAE;AACF,8EAA8E;AAC9E,8EAA8E;AAC9E,uEAAuE;AACvE,mDAAmD;AACnD,EAAE;AACF,wEAAwE;AACxE,gFAAgF;AAChF,6EAA6E;AAC7E,+EAA+E;AAC/E,+EAA+E;AAE/E,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAElF,+EAA+E;AAC/E,sCAAsC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,oFAAoF;AACpF,MAAM,CAAC,MAAM,wBAAwB,GAAG,OAAO,CAAC;AAEhD,kFAAkF;AAClF,MAAM,CAAC,MAAM,uBAAuB,GAAG,eAAe,CAAC;AAevD,oFAAoF;AACpF,MAAM,UAAU,mBAAmB,CAAC,OAAe,EAAE,QAAyB,EAAE,IAAY;IAC1F,OAAO,gBAAgB,OAAO,IAAI,YAAY,CAAC,QAAQ,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC;AAC5F,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,uBAAuB,CAAC,OAAe,EAAE,KAAa;IACpE,OAAO,wDAAwD,OAAO,IAAI,KAAK,EAAE,CAAC;AACpF,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,MAA8B;IACtE,MAAM,OAAO,GAAG,mBAAmB,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtH,MAAM,kBAAkB,CAAC;QACvB,GAAG,EAAE,uBAAuB,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC;QACrD,WAAW,EAAE,uBAAuB,CAAC,MAAM,CAAC,OAAO,EAAE,uBAAuB,CAAC;QAC7E,SAAS,EAAE,UAAU;QACrB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,KAAK,EAAE,cAAc;QACrB,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC,CAAC;AACL,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { DEFAULT_TEMPORAL_VERSION, downloadTemporalCli, extractTarEntry, isTemporalInstalled } from "./download.js";
|
|
2
|
-
export { isLikelyTemporal, processCommandLine } from "./inspect.js";
|
|
3
|
-
export { TemporalManager, type TemporalManagerOptions } from "./manager.js";
|
|
1
|
+
export { DEFAULT_TEMPORAL_VERSION, TEMPORAL_CHECKSUMS_FILE, downloadTemporalCli, extractTarEntry, isTemporalInstalled, temporalArchiveName, temporalReleaseAssetUrl, } from "./download.js";
|
|
2
|
+
export { isLikelyTemporal, processCommandLine, type ProcessInspectOptions } from "./inspect.js";
|
|
3
|
+
export { TEMPORAL_BIN_ENV, TemporalManager, type TemporalManagerOptions } from "./manager.js";
|
|
4
4
|
export { type SupervisedTarget, type SupervisorOptions, TemporalSupervisor } from "./supervisor.js";
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/local/temporal/index.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/local/temporal/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,KAAK,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAChG,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAC9F,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/local/temporal/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Public surface of the Temporal subsystem.
|
|
2
|
-
export { DEFAULT_TEMPORAL_VERSION, downloadTemporalCli, extractTarEntry, isTemporalInstalled } from "./download.js";
|
|
2
|
+
export { DEFAULT_TEMPORAL_VERSION, TEMPORAL_CHECKSUMS_FILE, downloadTemporalCli, extractTarEntry, isTemporalInstalled, temporalArchiveName, temporalReleaseAssetUrl, } from "./download.js";
|
|
3
3
|
export { isLikelyTemporal, processCommandLine } from "./inspect.js";
|
|
4
|
-
export { TemporalManager } from "./manager.js";
|
|
4
|
+
export { TEMPORAL_BIN_ENV, TemporalManager } from "./manager.js";
|
|
5
5
|
export { TemporalSupervisor } from "./supervisor.js";
|
|
6
6
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/local/temporal/index.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAE5C,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/local/temporal/index.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAE5C,OAAO,EACL,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAA8B,MAAM,cAAc,CAAC;AAChG,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAA+B,MAAM,cAAc,CAAC;AAC9F,OAAO,EAAiD,kBAAkB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export interface ProcessInspectOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Root of a procfs tree to read `<pid>/cmdline` from. Defaults to `/proc` on
|
|
4
|
+
* Linux and to none elsewhere; tests point it at a fixture directory.
|
|
5
|
+
*/
|
|
6
|
+
procRoot?: string | null;
|
|
7
|
+
}
|
|
8
|
+
/** Full command line of a process, or null if it cannot be read. */
|
|
9
|
+
export declare function processCommandLine(pid: number, options?: ProcessInspectOptions): string | null;
|
|
3
10
|
/**
|
|
4
11
|
* Heuristically confirm that `pid` is the Temporal server we manage: its command
|
|
5
12
|
* line mentions "temporal" and either our binary path or a "server" subcommand.
|
|
6
13
|
*/
|
|
7
|
-
export declare function isLikelyTemporal(pid: number, binPath: string): boolean;
|
|
14
|
+
export declare function isLikelyTemporal(pid: number, binPath: string, options?: ProcessInspectOptions): boolean;
|
|
8
15
|
//# sourceMappingURL=inspect.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../../src/local/temporal/inspect.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../../src/local/temporal/inspect.ts"],"names":[],"mappings":"AA2BA,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,oEAAoE;AACpE,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,GAAG,MAAM,GAAG,IAAI,CAOlG;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAM3G"}
|
|
@@ -3,26 +3,41 @@
|
|
|
3
3
|
// A PID file can outlive the process it named; the OS may then assign that PID
|
|
4
4
|
// to something unrelated. Before trusting a PID as "our Temporal", we confirm
|
|
5
5
|
// the live process's command line actually looks like the Temporal dev server.
|
|
6
|
-
//
|
|
6
|
+
//
|
|
7
|
+
// Two readers, in order. On Linux the kernel publishes every process's command
|
|
8
|
+
// line at /proc/<pid>/cmdline (NUL-separated argv), which needs no external
|
|
9
|
+
// program — the reader that works inside a minimal container. Everywhere else
|
|
10
|
+
// (and on a Linux where /proc is unreadable) we shell out to `ps`, the
|
|
11
|
+
// POSIX-portable answer. Returns null on any uncertainty; callers treat null
|
|
12
|
+
// as "not Temporal", which is the safe direction for a PID-reuse guard.
|
|
13
|
+
//
|
|
14
|
+
// Why the /proc reader exists: `node:22-slim` and its kin ship no `ps`. With
|
|
15
|
+
// `ps` as the only reader, every liveness probe answered "not Temporal", the
|
|
16
|
+
// supervisor restarted a healthy dev server every tick, and each restart spawned
|
|
17
|
+
// a second process that failed to bind while the first kept the port. A
|
|
18
|
+
// dependency on a userland tool is the wrong shape for a liveness check that
|
|
19
|
+
// the kernel can answer directly.
|
|
7
20
|
import { execFileSync } from "node:child_process";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
21
|
+
import { readFileSync } from "node:fs";
|
|
22
|
+
import { join } from "node:path";
|
|
23
|
+
/** Where the kernel publishes process metadata on Linux; null where it does not. */
|
|
24
|
+
const DEFAULT_PROC_ROOT = process.platform === "linux" ? "/proc" : null;
|
|
25
|
+
/** Full command line of a process, or null if it cannot be read. */
|
|
26
|
+
export function processCommandLine(pid, options = {}) {
|
|
27
|
+
const procRoot = options.procRoot === undefined ? DEFAULT_PROC_ROOT : options.procRoot;
|
|
28
|
+
if (procRoot !== null) {
|
|
29
|
+
const fromProc = readProcCmdline(procRoot, pid);
|
|
30
|
+
if (fromProc !== null)
|
|
31
|
+
return fromProc;
|
|
18
32
|
}
|
|
33
|
+
return psCommandLine(pid);
|
|
19
34
|
}
|
|
20
35
|
/**
|
|
21
36
|
* Heuristically confirm that `pid` is the Temporal server we manage: its command
|
|
22
37
|
* line mentions "temporal" and either our binary path or a "server" subcommand.
|
|
23
38
|
*/
|
|
24
|
-
export function isLikelyTemporal(pid, binPath) {
|
|
25
|
-
const cmd = processCommandLine(pid);
|
|
39
|
+
export function isLikelyTemporal(pid, binPath, options = {}) {
|
|
40
|
+
const cmd = processCommandLine(pid, options);
|
|
26
41
|
if (cmd === null)
|
|
27
42
|
return false;
|
|
28
43
|
const lower = cmd.toLowerCase();
|
|
@@ -30,4 +45,28 @@ export function isLikelyTemporal(pid, binPath) {
|
|
|
30
45
|
return false;
|
|
31
46
|
return cmd.includes(binPath) || lower.includes("server");
|
|
32
47
|
}
|
|
48
|
+
// /proc/<pid>/cmdline is argv joined by NUL bytes (with a trailing NUL). An
|
|
49
|
+
// empty file means a zombie or a kernel thread — nothing we can name, so null
|
|
50
|
+
// lets the caller fall through to `ps`.
|
|
51
|
+
function readProcCmdline(procRoot, pid) {
|
|
52
|
+
try {
|
|
53
|
+
const raw = readFileSync(join(procRoot, String(pid), "cmdline"), "utf8");
|
|
54
|
+
const argv = raw.split("\0").filter((arg) => arg !== "");
|
|
55
|
+
return argv.length === 0 ? null : argv.join(" ");
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function psCommandLine(pid) {
|
|
62
|
+
try {
|
|
63
|
+
return execFileSync("ps", ["-p", String(pid), "-o", "command="], {
|
|
64
|
+
encoding: "utf8",
|
|
65
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
66
|
+
}).trim();
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
33
72
|
//# sourceMappingURL=inspect.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inspect.js","sourceRoot":"","sources":["../../../src/local/temporal/inspect.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,+EAA+E;AAC/E,8EAA8E;AAC9E,+EAA+E;AAC/E,
|
|
1
|
+
{"version":3,"file":"inspect.js","sourceRoot":"","sources":["../../../src/local/temporal/inspect.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,+EAA+E;AAC/E,8EAA8E;AAC9E,+EAA+E;AAC/E,EAAE;AACF,+EAA+E;AAC/E,4EAA4E;AAC5E,8EAA8E;AAC9E,uEAAuE;AACvE,6EAA6E;AAC7E,wEAAwE;AACxE,EAAE;AACF,6EAA6E;AAC7E,6EAA6E;AAC7E,iFAAiF;AACjF,wEAAwE;AACxE,6EAA6E;AAC7E,kCAAkC;AAElC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,oFAAoF;AACpF,MAAM,iBAAiB,GAAkB,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAUvF,oEAAoE;AACpE,MAAM,UAAU,kBAAkB,CAAC,GAAW,EAAE,UAAiC,EAAE;IACjF,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;IACvF,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAChD,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,QAAQ,CAAC;IACzC,CAAC;IACD,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW,EAAE,OAAe,EAAE,UAAiC,EAAE;IAChG,MAAM,GAAG,GAAG,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC7C,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC/B,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAChC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9C,OAAO,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC3D,CAAC;AAED,4EAA4E;AAC5E,8EAA8E;AAC9E,wCAAwC;AACxC,SAAS,eAAe,CAAC,QAAgB,EAAE,GAAW;IACpD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;QACzE,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;QACzD,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,GAAW;IAChC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE;YAC/D,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC,CAAC,CAAC,IAAI,EAAE,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Env var naming a pre-installed `temporal` binary to use instead of the one
|
|
3
|
+
* the CLI downloads into ~/.stigmer/bin — the STIGMER_NODE_BIN precedent. The
|
|
4
|
+
* all-in-one image bakes the binary read-only off its data volume and points
|
|
5
|
+
* here; `ensureInstalled` then has nothing to download.
|
|
6
|
+
*/
|
|
7
|
+
export declare const TEMPORAL_BIN_ENV = "STIGMER_TEMPORAL_BIN";
|
|
1
8
|
export interface TemporalManagerOptions {
|
|
2
|
-
/** Path to the temporal binary (~/.stigmer/bin/temporal). */
|
|
9
|
+
/** Path to the temporal binary (~/.stigmer/bin/temporal, or STIGMER_TEMPORAL_BIN). */
|
|
3
10
|
binPath: string;
|
|
4
11
|
/** Temporal dev-server data directory (~/.stigmer/temporal-data). */
|
|
5
12
|
dataDir: string;
|
|
@@ -14,7 +21,8 @@ export interface TemporalManagerOptions {
|
|
|
14
21
|
uiPort?: number;
|
|
15
22
|
}
|
|
16
23
|
export declare class TemporalManager {
|
|
17
|
-
|
|
24
|
+
/** The `temporal` binary this manager runs (downloaded, or pre-installed via STIGMER_TEMPORAL_BIN). */
|
|
25
|
+
readonly binPath: string;
|
|
18
26
|
private readonly dataDir;
|
|
19
27
|
private readonly logFile;
|
|
20
28
|
private readonly pidFile;
|
|
@@ -24,8 +32,12 @@ export declare class TemporalManager {
|
|
|
24
32
|
private readonly uiPort;
|
|
25
33
|
private lock;
|
|
26
34
|
constructor(options: TemporalManagerOptions);
|
|
27
|
-
/**
|
|
28
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Build a manager from the standard ~/.stigmer layout. The binary alone may
|
|
37
|
+
* be relocated through STIGMER_TEMPORAL_BIN; the dev server's data, log,
|
|
38
|
+
* PID and lock stay under the home, because they are state, not software.
|
|
39
|
+
*/
|
|
40
|
+
static forHome(home?: string, env?: NodeJS.ProcessEnv): TemporalManager;
|
|
29
41
|
/** host:port of the Temporal frontend. */
|
|
30
42
|
get address(): string;
|
|
31
43
|
/** PID of the running dev server, or null. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/local/temporal/manager.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,sBAAsB;IACrC,
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/local/temporal/manager.ts"],"names":[],"mappings":"AA6BA;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,yBAAyB,CAAC;AAEvD,MAAM,WAAW,sBAAsB;IACrC,sFAAsF;IACtF,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,eAAe;IAC1B,uGAAuG;IACvG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,IAAI,CAAyB;gBAEzB,OAAO,EAAE,sBAAsB;IAW3C;;;;OAIG;IACH,MAAM,CAAC,OAAO,CAAC,IAAI,GAAE,MAAkB,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,eAAe;IAW/F,0CAA0C;IAC1C,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,8CAA8C;IAC9C,MAAM,IAAI,MAAM,GAAG,IAAI;IAIvB,0EAA0E;IACpE,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAUtC;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkD5B,kFAAkF;IAC5E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B3B,gFAAgF;IAC1E,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAQnC,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,qBAAqB;CAc9B"}
|
|
@@ -18,13 +18,21 @@ import { binDir, logDir, temporalDataDir, temporalLockFile, temporalPidFile } fr
|
|
|
18
18
|
import { TEMPORAL_PORT, TEMPORAL_UI_PORT } from "../constants.js";
|
|
19
19
|
import { acquireLock } from "../state/lock.js";
|
|
20
20
|
import { readPidFile, removePidFile, writePidFile } from "../state/pidfile.js";
|
|
21
|
-
import { findProcessByPort,
|
|
21
|
+
import { findProcessByPort, isOtherLiveProcess, killProcessGroup } from "../state/proc.js";
|
|
22
22
|
import { DEFAULT_TEMPORAL_VERSION, downloadTemporalCli, isTemporalInstalled } from "./download.js";
|
|
23
23
|
import { isLikelyTemporal } from "./inspect.js";
|
|
24
24
|
const READY_TIMEOUT_MS = 10_000;
|
|
25
25
|
const STOP_POLL_MS = 500;
|
|
26
26
|
const STOP_TIMEOUT_MS = 10_000;
|
|
27
|
+
/**
|
|
28
|
+
* Env var naming a pre-installed `temporal` binary to use instead of the one
|
|
29
|
+
* the CLI downloads into ~/.stigmer/bin — the STIGMER_NODE_BIN precedent. The
|
|
30
|
+
* all-in-one image bakes the binary read-only off its data volume and points
|
|
31
|
+
* here; `ensureInstalled` then has nothing to download.
|
|
32
|
+
*/
|
|
33
|
+
export const TEMPORAL_BIN_ENV = "STIGMER_TEMPORAL_BIN";
|
|
27
34
|
export class TemporalManager {
|
|
35
|
+
/** The `temporal` binary this manager runs (downloaded, or pre-installed via STIGMER_TEMPORAL_BIN). */
|
|
28
36
|
binPath;
|
|
29
37
|
dataDir;
|
|
30
38
|
logFile;
|
|
@@ -44,10 +52,15 @@ export class TemporalManager {
|
|
|
44
52
|
this.port = options.port ?? TEMPORAL_PORT;
|
|
45
53
|
this.uiPort = options.uiPort ?? TEMPORAL_UI_PORT;
|
|
46
54
|
}
|
|
47
|
-
/**
|
|
48
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Build a manager from the standard ~/.stigmer layout. The binary alone may
|
|
57
|
+
* be relocated through STIGMER_TEMPORAL_BIN; the dev server's data, log,
|
|
58
|
+
* PID and lock stay under the home, because they are state, not software.
|
|
59
|
+
*/
|
|
60
|
+
static forHome(home = homedir(), env = process.env) {
|
|
61
|
+
const binOverride = env[TEMPORAL_BIN_ENV];
|
|
49
62
|
return new TemporalManager({
|
|
50
|
-
binPath: join(binDir(home), "temporal"),
|
|
63
|
+
binPath: binOverride !== undefined && binOverride !== "" ? binOverride : join(binDir(home), "temporal"),
|
|
51
64
|
dataDir: temporalDataDir(home),
|
|
52
65
|
logFile: join(logDir(home), "temporal.log"),
|
|
53
66
|
pidFile: temporalPidFile(home),
|
|
@@ -150,7 +163,7 @@ export class TemporalManager {
|
|
|
150
163
|
const pid = this.getPid();
|
|
151
164
|
if (pid === null)
|
|
152
165
|
return false;
|
|
153
|
-
if (!
|
|
166
|
+
if (!isOtherLiveProcess(pid))
|
|
154
167
|
return false;
|
|
155
168
|
if (!isLikelyTemporal(pid, this.binPath))
|
|
156
169
|
return false;
|
|
@@ -190,7 +203,7 @@ export class TemporalManager {
|
|
|
190
203
|
cleanupStaleProcesses() {
|
|
191
204
|
const pid = this.getPid();
|
|
192
205
|
if (pid !== null) {
|
|
193
|
-
if (!
|
|
206
|
+
if (!isOtherLiveProcess(pid) || !isLikelyTemporal(pid, this.binPath)) {
|
|
194
207
|
removePidFile(this.pidFile);
|
|
195
208
|
}
|
|
196
209
|
return;
|