@mastra/docker 0.9.2 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +35 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +35 -7
- package/dist/index.js.map +1 -1
- package/dist/sandbox/process-manager.d.ts.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { isDeepStrictEqual, promisify } from "util";
|
|
|
3
3
|
import { MastraSandbox, ProcessHandle, SandboxAbortError, SandboxError, SandboxNotReadyError, SandboxProcessManager, validateSandboxFileMode } from "@mastra/core/workspace";
|
|
4
4
|
import Docker from "dockerode";
|
|
5
5
|
import { pack } from "tar-stream";
|
|
6
|
+
import { StringDecoder } from "string_decoder";
|
|
6
7
|
import posixPath from "path/posix";
|
|
7
8
|
import { Server, ServerCredentials } from "@grpc/grpc-js";
|
|
8
9
|
import { createHash } from "crypto";
|
|
@@ -89,6 +90,8 @@ ret=$?
|
|
|
89
90
|
rm -f "$1" 2>/dev/null
|
|
90
91
|
exit $ret
|
|
91
92
|
`;
|
|
93
|
+
/** KILL_SCRIPT exit code when no PGID file was readable or it was empty. */
|
|
94
|
+
const NO_PGID_EXIT_CODE = 3;
|
|
92
95
|
/**
|
|
93
96
|
* Kill script: read the recorded PGID and SIGKILL the whole process group.
|
|
94
97
|
* A negative PID targets the kernel-owned process group, so descendants that
|
|
@@ -104,11 +107,12 @@ i=0
|
|
|
104
107
|
while [ ! -r "$f" ] && [ "$i" -lt 40 ]; do sleep 0.05; i=$((i + 1)); done
|
|
105
108
|
# If the PGID was never recorded (file absent/unreadable after the wait, or
|
|
106
109
|
# empty), we have no group to signal or verify — report failure rather than
|
|
107
|
-
# falsely claiming the tree was terminated.
|
|
108
|
-
|
|
110
|
+
# falsely claiming the tree was terminated. Exit code 3 marks this case so
|
|
111
|
+
# kill() can tell it apart from a failed termination (exit 1).
|
|
112
|
+
[ -r "$f" ] || exit 3
|
|
109
113
|
pgid=$(cat "$f" 2>/dev/null)
|
|
110
114
|
rm -f "$f" 2>/dev/null
|
|
111
|
-
[ -n "$pgid" ] || exit
|
|
115
|
+
[ -n "$pgid" ] || exit 3
|
|
112
116
|
kill -STOP -"$pgid" 2>/dev/null
|
|
113
117
|
kill -KILL -"$pgid" 2>/dev/null
|
|
114
118
|
# Fallback for images without setsid: the leader is not a group leader, so also
|
|
@@ -285,7 +289,13 @@ var DockerProcessHandle = class extends ProcessHandle {
|
|
|
285
289
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
286
290
|
killInfo = await killExec.inspect();
|
|
287
291
|
}
|
|
288
|
-
if (killInfo.ExitCode !== 0)
|
|
292
|
+
if (killInfo.ExitCode !== 0) {
|
|
293
|
+
if (killInfo.ExitCode === NO_PGID_EXIT_CODE) {
|
|
294
|
+
const selfInfo = await this._exec.inspect().catch(() => void 0);
|
|
295
|
+
if (selfInfo && !selfInfo.Running) return false;
|
|
296
|
+
}
|
|
297
|
+
throw new Error(`kill helper exited with code ${killInfo.ExitCode}`);
|
|
298
|
+
}
|
|
289
299
|
this._killed = true;
|
|
290
300
|
this._destroyStream();
|
|
291
301
|
return true;
|
|
@@ -374,6 +384,8 @@ var DockerProcessManager = class extends SandboxProcessManager {
|
|
|
374
384
|
handle._setExecStream(stream);
|
|
375
385
|
const waitPromise = new Promise((resolve) => {
|
|
376
386
|
const buffer = [];
|
|
387
|
+
const stdoutDecoder = new StringDecoder("utf8");
|
|
388
|
+
const stderrDecoder = new StringDecoder("utf8");
|
|
377
389
|
stream.on("data", (chunk) => {
|
|
378
390
|
buffer.push(chunk);
|
|
379
391
|
let combined = Buffer.concat(buffer);
|
|
@@ -385,17 +397,32 @@ var DockerProcessManager = class extends SandboxProcessManager {
|
|
|
385
397
|
buffer.push(combined);
|
|
386
398
|
break;
|
|
387
399
|
}
|
|
388
|
-
const payload = combined.subarray(8, 8 + size)
|
|
389
|
-
if (type === 1)
|
|
390
|
-
|
|
400
|
+
const payload = combined.subarray(8, 8 + size);
|
|
401
|
+
if (type === 1) {
|
|
402
|
+
const text = stdoutDecoder.write(payload);
|
|
403
|
+
if (text) handle.emitStdout(text);
|
|
404
|
+
} else if (type === 2) {
|
|
405
|
+
const text = stderrDecoder.write(payload);
|
|
406
|
+
if (text) handle.emitStderr(text);
|
|
407
|
+
}
|
|
391
408
|
combined = combined.subarray(8 + size);
|
|
392
409
|
}
|
|
393
410
|
if (combined.length > 0 && buffer.length === 0) buffer.push(combined);
|
|
394
411
|
});
|
|
412
|
+
let decodersFlushed = false;
|
|
413
|
+
const flushDecoders = () => {
|
|
414
|
+
if (decodersFlushed) return;
|
|
415
|
+
decodersFlushed = true;
|
|
416
|
+
const stdoutRest = stdoutDecoder.end();
|
|
417
|
+
if (stdoutRest) handle.emitStdout(stdoutRest);
|
|
418
|
+
const stderrRest = stderrDecoder.end();
|
|
419
|
+
if (stderrRest) handle.emitStderr(stderrRest);
|
|
420
|
+
};
|
|
395
421
|
let settled = false;
|
|
396
422
|
const settle = (exitCode, metadata = {}) => {
|
|
397
423
|
if (settled) return;
|
|
398
424
|
settled = true;
|
|
425
|
+
flushDecoders();
|
|
399
426
|
handle._setExitCode(exitCode);
|
|
400
427
|
resolve({
|
|
401
428
|
success: exitCode === 0,
|
|
@@ -453,6 +480,7 @@ var DockerProcessManager = class extends SandboxProcessManager {
|
|
|
453
480
|
settleTerminated();
|
|
454
481
|
return;
|
|
455
482
|
}
|
|
483
|
+
flushDecoders();
|
|
456
484
|
settle(1, { stderr: handle.stderr || "Stream error" });
|
|
457
485
|
});
|
|
458
486
|
});
|