@multiplayer-app/sandbox 7.0.5 → 7.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/cli.js +45 -23
- package/dist/cli.js.map +3 -3
- package/dist/executor/qemu-executor.d.ts +2 -2
- package/dist/executor/qemu-executor.d.ts.map +1 -1
- package/dist/index.js +45 -23
- package/dist/index.js.map +3 -3
- package/package.json +3 -3
|
@@ -8,8 +8,8 @@ export interface QemuConfig {
|
|
|
8
8
|
kernelPath?: string;
|
|
9
9
|
initrdPath?: string;
|
|
10
10
|
vmDataPath?: string;
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
portRangeStart?: number;
|
|
12
|
+
portRangeEnd?: number;
|
|
13
13
|
vncBasePort?: number;
|
|
14
14
|
serialBasePort?: number;
|
|
15
15
|
accel?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qemu-executor.d.ts","sourceRoot":"","sources":["../../src/executor/qemu-executor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"qemu-executor.d.ts","sourceRoot":"","sources":["../../src/executor/qemu-executor.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -58,7 +58,7 @@ var import_os2 = __toESM(require("os"));
|
|
|
58
58
|
var import_path2 = __toESM(require("path"));
|
|
59
59
|
|
|
60
60
|
// package.json
|
|
61
|
-
var version = "7.0.
|
|
61
|
+
var version = "7.0.6";
|
|
62
62
|
|
|
63
63
|
// src/images.ts
|
|
64
64
|
var import_fs = __toESM(require("fs"));
|
|
@@ -646,6 +646,7 @@ var MockExecutor = class {
|
|
|
646
646
|
|
|
647
647
|
// src/executor/qemu-executor.ts
|
|
648
648
|
var import_child_process2 = require("child_process");
|
|
649
|
+
var import_http2 = __toESM(require("http"));
|
|
649
650
|
var import_net = __toESM(require("net"));
|
|
650
651
|
var import_path4 = __toESM(require("path"));
|
|
651
652
|
var import_promises3 = __toESM(require("fs/promises"));
|
|
@@ -681,8 +682,8 @@ var QemuExecutor = class {
|
|
|
681
682
|
this.usedSerialPorts = /* @__PURE__ */ new Set();
|
|
682
683
|
this.bin = config.bin ?? "qemu-system-aarch64";
|
|
683
684
|
this.vmDataPath = config.vmDataPath ?? import_path4.default.join(import_os6.default.tmpdir(), "qemu-vms");
|
|
684
|
-
this.httpPortStart = config.
|
|
685
|
-
this.httpPortEnd = config.
|
|
685
|
+
this.httpPortStart = config.portRangeStart ?? 9e3;
|
|
686
|
+
this.httpPortEnd = config.portRangeEnd ?? 9099;
|
|
686
687
|
this.vncBasePort = config.vncBasePort ?? 5900;
|
|
687
688
|
this.serialBasePort = config.serialBasePort ?? 8e3;
|
|
688
689
|
this.accel = config.accel ?? "hvf";
|
|
@@ -834,6 +835,7 @@ var QemuExecutor = class {
|
|
|
834
835
|
this.vms.set(spec.vmId, vm);
|
|
835
836
|
if (runMode === "job") vm.serialBuffer = connectSerialBuffer(serialPort);
|
|
836
837
|
await waitForQmp(qmpSocketPath);
|
|
838
|
+
if (runMode !== "job") await waitForHttp("127.0.0.1", hostPort);
|
|
837
839
|
src_default.info({ vmId: spec.vmId, hostPort, vncPort, serialPort, runMode }, "qemu vm ready");
|
|
838
840
|
return handle;
|
|
839
841
|
}
|
|
@@ -983,9 +985,9 @@ var QemuExecutor = class {
|
|
|
983
985
|
async proxyHttp(vmId, request) {
|
|
984
986
|
const vm = this.vms.get(vmId);
|
|
985
987
|
if (!vm?.handle.running) throw new Error(`vm ${vmId} is not running`);
|
|
986
|
-
const { default:
|
|
988
|
+
const { default: http9 } = await import("http");
|
|
987
989
|
return new Promise((resolve, reject) => {
|
|
988
|
-
const req =
|
|
990
|
+
const req = http9.request(
|
|
989
991
|
{
|
|
990
992
|
host: "127.0.0.1",
|
|
991
993
|
port: vm.hostPort,
|
|
@@ -1059,6 +1061,26 @@ function waitForQmp(socketPath, timeoutMs = 3e4) {
|
|
|
1059
1061
|
attempt();
|
|
1060
1062
|
});
|
|
1061
1063
|
}
|
|
1064
|
+
function waitForHttp(host, port, timeoutMs = 6e4) {
|
|
1065
|
+
return new Promise((resolve, reject) => {
|
|
1066
|
+
const deadline = Date.now() + timeoutMs;
|
|
1067
|
+
const attempt = () => {
|
|
1068
|
+
if (Date.now() > deadline)
|
|
1069
|
+
return reject(new Error(`timed out waiting for HTTP at ${host}:${port}`));
|
|
1070
|
+
const req = import_http2.default.get(`http://${host}:${port}/health`, (res) => {
|
|
1071
|
+
if (res.statusCode && res.statusCode < 500) return resolve();
|
|
1072
|
+
res.resume();
|
|
1073
|
+
setTimeout(attempt, 1e3);
|
|
1074
|
+
});
|
|
1075
|
+
req.on("error", () => setTimeout(attempt, 1e3));
|
|
1076
|
+
req.setTimeout(2e3, () => {
|
|
1077
|
+
req.destroy();
|
|
1078
|
+
setTimeout(attempt, 1e3);
|
|
1079
|
+
});
|
|
1080
|
+
};
|
|
1081
|
+
attempt();
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1062
1084
|
async function sendQmpCommand(socketPath, execute) {
|
|
1063
1085
|
return new Promise((resolve, reject) => {
|
|
1064
1086
|
const sock = import_net.default.createConnection(socketPath);
|
|
@@ -1104,7 +1126,7 @@ async function sendQmpCommand(socketPath, execute) {
|
|
|
1104
1126
|
var import_child_process3 = require("child_process");
|
|
1105
1127
|
var import_child_process4 = require("child_process");
|
|
1106
1128
|
var import_util = require("util");
|
|
1107
|
-
var
|
|
1129
|
+
var import_http3 = __toESM(require("http"));
|
|
1108
1130
|
var import_net2 = __toESM(require("net"));
|
|
1109
1131
|
var import_path5 = __toESM(require("path"));
|
|
1110
1132
|
var import_promises4 = __toESM(require("fs/promises"));
|
|
@@ -1241,7 +1263,7 @@ var FirecrackerExecutor = class {
|
|
|
1241
1263
|
host_dev_name: tapName
|
|
1242
1264
|
});
|
|
1243
1265
|
await fcRequest(apiSocketPath, "PUT", "/actions", { action_type: "InstanceStart" });
|
|
1244
|
-
if (runMode !== "job") await
|
|
1266
|
+
if (runMode !== "job") await waitForHttp2(guestIp, 8080);
|
|
1245
1267
|
const metadata = { apiSocketPath, tapName, subnet, guestIp, pid: proc.pid };
|
|
1246
1268
|
const handle = {
|
|
1247
1269
|
vmId: spec.vmId,
|
|
@@ -1404,7 +1426,7 @@ var FirecrackerExecutor = class {
|
|
|
1404
1426
|
const vm = this.vms.get(vmId);
|
|
1405
1427
|
if (!vm?.handle.running) throw new Error(`vm ${vmId} is not running`);
|
|
1406
1428
|
return new Promise((resolve, reject) => {
|
|
1407
|
-
const req =
|
|
1429
|
+
const req = import_http3.default.request(
|
|
1408
1430
|
{
|
|
1409
1431
|
host: vm.guestIp,
|
|
1410
1432
|
port: 8080,
|
|
@@ -1450,7 +1472,7 @@ var FirecrackerExecutor = class {
|
|
|
1450
1472
|
function fcRequest(socketPath, method, urlPath, body) {
|
|
1451
1473
|
return new Promise((resolve, reject) => {
|
|
1452
1474
|
const payload = JSON.stringify(body);
|
|
1453
|
-
const req =
|
|
1475
|
+
const req = import_http3.default.request(
|
|
1454
1476
|
{
|
|
1455
1477
|
socketPath,
|
|
1456
1478
|
method,
|
|
@@ -1499,13 +1521,13 @@ function waitForSocket(socketPath, timeoutMs = 1e4) {
|
|
|
1499
1521
|
attempt();
|
|
1500
1522
|
});
|
|
1501
1523
|
}
|
|
1502
|
-
function
|
|
1524
|
+
function waitForHttp2(host, port, timeoutMs = 6e4) {
|
|
1503
1525
|
return new Promise((resolve, reject) => {
|
|
1504
1526
|
const deadline = Date.now() + timeoutMs;
|
|
1505
1527
|
const attempt = () => {
|
|
1506
1528
|
if (Date.now() > deadline)
|
|
1507
1529
|
return reject(new Error(`timed out waiting for HTTP at ${host}:${port}`));
|
|
1508
|
-
const req =
|
|
1530
|
+
const req = import_http3.default.get(`http://${host}:${port}/health`, (res) => {
|
|
1509
1531
|
if (res.statusCode && res.statusCode < 500) return resolve();
|
|
1510
1532
|
res.resume();
|
|
1511
1533
|
setTimeout(attempt, 1e3);
|
|
@@ -1523,7 +1545,7 @@ function waitForHttp(host, port, timeoutMs = 6e4) {
|
|
|
1523
1545
|
// src/executor/docker-executor.ts
|
|
1524
1546
|
var import_child_process5 = require("child_process");
|
|
1525
1547
|
var import_util2 = require("util");
|
|
1526
|
-
var
|
|
1548
|
+
var import_http4 = __toESM(require("http"));
|
|
1527
1549
|
var DEFAULT_EXEC_TIMEOUT_MS2 = 6e4;
|
|
1528
1550
|
var MAX_EXEC_TIMEOUT_MS2 = 3e5;
|
|
1529
1551
|
var MAX_OUTPUT_BYTES4 = 1024 * 1024;
|
|
@@ -1815,7 +1837,7 @@ var DockerExecutor = class {
|
|
|
1815
1837
|
const vm = this.mustGet(vmId);
|
|
1816
1838
|
if (!vm.handle.running) throw new Error(`vm ${vmId} is not running`);
|
|
1817
1839
|
return new Promise((resolve, reject) => {
|
|
1818
|
-
const req =
|
|
1840
|
+
const req = import_http4.default.request(
|
|
1819
1841
|
{
|
|
1820
1842
|
host: "127.0.0.1",
|
|
1821
1843
|
port: vm.hostPort,
|
|
@@ -1933,7 +1955,7 @@ var DockerExecutor = class {
|
|
|
1933
1955
|
const deadline = Date.now() + timeoutMs;
|
|
1934
1956
|
for (; ; ) {
|
|
1935
1957
|
const ok = await new Promise((resolve) => {
|
|
1936
|
-
const req =
|
|
1958
|
+
const req = import_http4.default.get({ host: "127.0.0.1", port, path: "/", timeout: 2e3 }, (res) => {
|
|
1937
1959
|
res.resume();
|
|
1938
1960
|
resolve(true);
|
|
1939
1961
|
});
|
|
@@ -1981,7 +2003,7 @@ var import_util3 = require("util");
|
|
|
1981
2003
|
var import_promises5 = __toESM(require("fs/promises"));
|
|
1982
2004
|
var import_os8 = __toESM(require("os"));
|
|
1983
2005
|
var import_path6 = __toESM(require("path"));
|
|
1984
|
-
var
|
|
2006
|
+
var import_http5 = __toESM(require("http"));
|
|
1985
2007
|
var DEFAULT_EXEC_TIMEOUT_MS3 = 6e4;
|
|
1986
2008
|
var MAX_EXEC_TIMEOUT_MS3 = 3e5;
|
|
1987
2009
|
var MAX_OUTPUT_BYTES5 = 1024 * 1024;
|
|
@@ -2289,7 +2311,7 @@ var DockerSandboxExecutor = class {
|
|
|
2289
2311
|
const vm = this.mustGet(vmId);
|
|
2290
2312
|
if (!vm.handle.running) throw new Error(`vm ${vmId} is not running`);
|
|
2291
2313
|
return new Promise((resolve, reject) => {
|
|
2292
|
-
const req =
|
|
2314
|
+
const req = import_http5.default.request(
|
|
2293
2315
|
{
|
|
2294
2316
|
host: "127.0.0.1",
|
|
2295
2317
|
port: vm.hostPort,
|
|
@@ -2398,7 +2420,7 @@ var DockerSandboxExecutor = class {
|
|
|
2398
2420
|
}
|
|
2399
2421
|
async probeAgent(port) {
|
|
2400
2422
|
return new Promise((resolve) => {
|
|
2401
|
-
const req =
|
|
2423
|
+
const req = import_http5.default.get({ host: "127.0.0.1", port, path: "/", timeout: 2e3 }, (res) => {
|
|
2402
2424
|
res.resume();
|
|
2403
2425
|
resolve(true);
|
|
2404
2426
|
});
|
|
@@ -2421,7 +2443,7 @@ var DockerSandboxExecutor = class {
|
|
|
2421
2443
|
};
|
|
2422
2444
|
|
|
2423
2445
|
// src/executor/remote-executor.ts
|
|
2424
|
-
var
|
|
2446
|
+
var import_http6 = __toESM(require("http"));
|
|
2425
2447
|
var import_https = __toESM(require("https"));
|
|
2426
2448
|
var JOB_POLL_INTERVAL_MS = 3e3;
|
|
2427
2449
|
var RemoteExecutor = class {
|
|
@@ -2527,7 +2549,7 @@ var RemoteExecutor = class {
|
|
|
2527
2549
|
}
|
|
2528
2550
|
request(method, path8, body) {
|
|
2529
2551
|
const url = new URL(this.base + path8);
|
|
2530
|
-
const lib = url.protocol === "https:" ? import_https.default :
|
|
2552
|
+
const lib = url.protocol === "https:" ? import_https.default : import_http6.default;
|
|
2531
2553
|
const payload = body !== void 0 ? JSON.stringify(body) : void 0;
|
|
2532
2554
|
return new Promise((resolve, reject) => {
|
|
2533
2555
|
const req = lib.request(
|
|
@@ -2872,7 +2894,7 @@ var LambdaMicrovmExecutor = class {
|
|
|
2872
2894
|
};
|
|
2873
2895
|
|
|
2874
2896
|
// src/executor/fargate-executor.ts
|
|
2875
|
-
var
|
|
2897
|
+
var import_http7 = __toESM(require("http"));
|
|
2876
2898
|
var import_client_ecs = require("@aws-sdk/client-ecs");
|
|
2877
2899
|
var JOB_POLL_INTERVAL_MS2 = 5e3;
|
|
2878
2900
|
var FARGATE_MEM_RANGES = {
|
|
@@ -3064,7 +3086,7 @@ var FargateExecutor = class {
|
|
|
3064
3086
|
const vm = this.mustGet(vmId);
|
|
3065
3087
|
if (!vm.handle.running) throw new Error(`vm ${vmId} is not running`);
|
|
3066
3088
|
return new Promise((resolve, reject) => {
|
|
3067
|
-
const req =
|
|
3089
|
+
const req = import_http7.default.request(
|
|
3068
3090
|
{
|
|
3069
3091
|
host: vm.ip,
|
|
3070
3092
|
port: this.config.guestPort ?? 8080,
|
|
@@ -4154,9 +4176,9 @@ function attachConsoleRelays(executor, sandboxSocket) {
|
|
|
4154
4176
|
}
|
|
4155
4177
|
|
|
4156
4178
|
// src/health-server.ts
|
|
4157
|
-
var
|
|
4179
|
+
var import_http8 = __toESM(require("http"));
|
|
4158
4180
|
async function startSandboxHealthServer(options) {
|
|
4159
|
-
const server =
|
|
4181
|
+
const server = import_http8.default.createServer((req, res) => {
|
|
4160
4182
|
const pathname = new URL(req.url ?? "/", "http://localhost").pathname;
|
|
4161
4183
|
if (pathname === `${options.pathPrefix}/healthz`) {
|
|
4162
4184
|
res.writeHead(200, { "content-type": "application/json" });
|