isol8 0.3.0 → 0.4.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/README.md +1 -1
- package/dist/cli.js +16 -10
- package/dist/cli.js.map +4 -4
- package/dist/index.js +7 -9
- package/dist/index.js.map +3 -3
- package/dist/src/engine/pool.d.ts +1 -0
- package/dist/src/engine/pool.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -101,7 +101,7 @@ isol8 run script.py --host http://server:3000 --key my-api-key
|
|
|
101
101
|
| `--allow <regex>` | Whitelist regex (repeatable, for `filtered`) | — |
|
|
102
102
|
| `--deny <regex>` | Blacklist regex (repeatable, for `filtered`) | — |
|
|
103
103
|
| `--out <file>` | Write stdout to file | — |
|
|
104
|
-
| `--stream` |
|
|
104
|
+
| `--no-stream` | Disable real-time output streaming | `false` |
|
|
105
105
|
| `--persistent` | Keep container alive between runs | `false` |
|
|
106
106
|
| `--timeout <ms>` | Execution timeout in milliseconds | `30000` |
|
|
107
107
|
| `--memory <limit>` | Memory limit (e.g. `512m`, `1g`) | `512m` |
|
package/dist/cli.js
CHANGED
|
@@ -55018,6 +55018,7 @@ class ContainerPool {
|
|
|
55018
55018
|
createOptions;
|
|
55019
55019
|
pools = new Map;
|
|
55020
55020
|
replenishing = new Set;
|
|
55021
|
+
pendingReplenishments = new Set;
|
|
55021
55022
|
constructor(options) {
|
|
55022
55023
|
this.docker = options.docker;
|
|
55023
55024
|
this.poolSize = options.poolSize ?? 2;
|
|
@@ -55067,6 +55068,7 @@ class ContainerPool {
|
|
|
55067
55068
|
await Promise.all(promises);
|
|
55068
55069
|
}
|
|
55069
55070
|
async drain() {
|
|
55071
|
+
await Promise.all(this.pendingReplenishments);
|
|
55070
55072
|
const promises = [];
|
|
55071
55073
|
for (const [, pool] of this.pools) {
|
|
55072
55074
|
for (const entry of pool) {
|
|
@@ -55081,26 +55083,20 @@ class ContainerPool {
|
|
|
55081
55083
|
...this.createOptions,
|
|
55082
55084
|
Image: image
|
|
55083
55085
|
});
|
|
55084
|
-
console.log(`[Pool] Container ${container.id} created for image: ${image}`);
|
|
55085
55086
|
await container.start();
|
|
55086
|
-
console.log(`[Pool] Container ${container.id} started.`);
|
|
55087
55087
|
return container;
|
|
55088
55088
|
}
|
|
55089
55089
|
replenish(image) {
|
|
55090
55090
|
if (this.replenishing.has(image)) {
|
|
55091
|
-
console.log(`[Pool] Replenishment for ${image} already in progress.`);
|
|
55092
55091
|
return;
|
|
55093
55092
|
}
|
|
55094
55093
|
this.replenishing.add(image);
|
|
55095
|
-
|
|
55096
|
-
this.createContainer(image).then((container) => {
|
|
55094
|
+
const promise = this.createContainer(image).then((container) => {
|
|
55097
55095
|
const pool = this.pools.get(image) ?? [];
|
|
55098
55096
|
if (pool.length < this.poolSize) {
|
|
55099
55097
|
pool.push({ container, createdAt: Date.now() });
|
|
55100
55098
|
this.pools.set(image, pool);
|
|
55101
|
-
console.log(`[Pool] Replenished container ${container.id} added to pool for ${image}. Current pool size: ${pool.length}`);
|
|
55102
55099
|
} else {
|
|
55103
|
-
console.log(`[Pool] Replenished container ${container.id} not needed (pool for ${image} is full), destroying.`);
|
|
55104
55100
|
container.remove({ force: true }).catch((err) => {
|
|
55105
55101
|
console.error(`[Pool] Error destroying unneeded replenished container ${container.id}:`, err);
|
|
55106
55102
|
});
|
|
@@ -55109,7 +55105,9 @@ class ContainerPool {
|
|
|
55109
55105
|
console.error(`[Pool] Error during replenishment for ${image}:`, err);
|
|
55110
55106
|
}).finally(() => {
|
|
55111
55107
|
this.replenishing.delete(image);
|
|
55108
|
+
this.pendingReplenishments.delete(promise);
|
|
55112
55109
|
});
|
|
55110
|
+
this.pendingReplenishments.add(promise);
|
|
55113
55111
|
}
|
|
55114
55112
|
}
|
|
55115
55113
|
|
|
@@ -61223,8 +61221,14 @@ program2.command("setup").description("Check Docker and build isol8 images").opt
|
|
|
61223
61221
|
console.log(`
|
|
61224
61222
|
[DONE] Setup complete!`);
|
|
61225
61223
|
});
|
|
61226
|
-
program2.command("run").description("Execute code in isol8").argument("[file]", "Script file to execute").option("-e, --eval <code>", "Execute inline code string").option("-r, --runtime <name>", "Force runtime (python, node, bun, deno, bash)").option("--net <mode>", "Network mode: none, host, filtered", "none").option("--allow <regex>", "Whitelist regex for filtered mode (repeatable)", collect, []).option("--deny <regex>", "Blacklist regex for filtered mode (repeatable)", collect, []).option("--out <file>", "Write output to file").option("--persistent", "Use persistent container").option("--timeout <ms>", "Execution timeout in milliseconds").option("--memory <limit>", "Memory limit (e.g. 512m, 1g)").option("--cpu <limit>", "CPU limit as fraction (e.g. 0.5, 2.0)").option("--image <name>", "Override Docker image").option("--pids-limit <n>", "Maximum number of processes").option("--writable", "Disable read-only root filesystem").option("--max-output <bytes>", "Maximum output size in bytes").option("--secret <KEY=VALUE>", "Secret env var (repeatable, values masked)", collect, []).option("--sandbox-size <size>", "Sandbox tmpfs size (e.g. 128m)").option("--tmp-size <size>", "Tmp tmpfs size (e.g. 256m, 512m)").option("--stdin <data>", "Data to pipe to stdin").option("--install <package>", "Install package for runtime (repeatable)", collect, []).option("--host <url>", "Execute on remote server").option("--key <key>", "API key for remote server").option("--stream", "
|
|
61224
|
+
program2.command("run").description("Execute code in isol8").argument("[file]", "Script file to execute").option("-e, --eval <code>", "Execute inline code string").option("-r, --runtime <name>", "Force runtime (python, node, bun, deno, bash)").option("--net <mode>", "Network mode: none, host, filtered", "none").option("--allow <regex>", "Whitelist regex for filtered mode (repeatable)", collect, []).option("--deny <regex>", "Blacklist regex for filtered mode (repeatable)", collect, []).option("--out <file>", "Write output to file").option("--persistent", "Use persistent container").option("--timeout <ms>", "Execution timeout in milliseconds").option("--memory <limit>", "Memory limit (e.g. 512m, 1g)").option("--cpu <limit>", "CPU limit as fraction (e.g. 0.5, 2.0)").option("--image <name>", "Override Docker image").option("--pids-limit <n>", "Maximum number of processes").option("--writable", "Disable read-only root filesystem").option("--max-output <bytes>", "Maximum output size in bytes").option("--secret <KEY=VALUE>", "Secret env var (repeatable, values masked)", collect, []).option("--sandbox-size <size>", "Sandbox tmpfs size (e.g. 128m)").option("--tmp-size <size>", "Tmp tmpfs size (e.g. 256m, 512m)").option("--stdin <data>", "Data to pipe to stdin").option("--install <package>", "Install package for runtime (repeatable)", collect, []).option("--host <url>", "Execute on remote server").option("--key <key>", "API key for remote server").option("--no-stream", "Disable real-time output streaming").action(async (file, opts) => {
|
|
61227
61225
|
const { code, runtime, engineOptions, engine, stdinData } = await resolveRunInput(file, opts);
|
|
61226
|
+
const cleanup = async () => {
|
|
61227
|
+
await engine.stop();
|
|
61228
|
+
process.exit(0);
|
|
61229
|
+
};
|
|
61230
|
+
process.on("SIGINT", cleanup);
|
|
61231
|
+
process.on("SIGTERM", cleanup);
|
|
61228
61232
|
const spinner = ora("Starting execution...").start();
|
|
61229
61233
|
try {
|
|
61230
61234
|
await engine.start();
|
|
@@ -61236,7 +61240,7 @@ program2.command("run").description("Execute code in isol8").argument("[file]",
|
|
|
61236
61240
|
...stdinData ? { stdin: stdinData } : {},
|
|
61237
61241
|
...opts.install.length > 0 ? { installPackages: opts.install } : {}
|
|
61238
61242
|
};
|
|
61239
|
-
if (opts.stream) {
|
|
61243
|
+
if (opts.stream !== false) {
|
|
61240
61244
|
spinner.stop();
|
|
61241
61245
|
const stream = engine.executeStream(req);
|
|
61242
61246
|
for await (const event of stream) {
|
|
@@ -61278,6 +61282,8 @@ program2.command("run").description("Execute code in isol8").argument("[file]",
|
|
|
61278
61282
|
throw err;
|
|
61279
61283
|
} finally {
|
|
61280
61284
|
await engine.stop();
|
|
61285
|
+
process.off("SIGINT", cleanup);
|
|
61286
|
+
process.off("SIGTERM", cleanup);
|
|
61281
61287
|
}
|
|
61282
61288
|
});
|
|
61283
61289
|
program2.command("serve").description("Start the isol8 remote server").option("-p, --port <port>", "Port to listen on", "3000").option("-k, --key <key>", "API key for authentication").action(async (opts) => {
|
|
@@ -61507,4 +61513,4 @@ if (!process.argv.slice(2).length) {
|
|
|
61507
61513
|
}
|
|
61508
61514
|
program2.parse();
|
|
61509
61515
|
|
|
61510
|
-
//# debugId=
|
|
61516
|
+
//# debugId=D191C9C5DB033D7B64756E2164756E21
|