isol8 0.11.2 → 0.12.0-alpha.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/dist/cli.js CHANGED
@@ -6318,7 +6318,7 @@ var require_bcrypt_pbkdf = __commonJS((exports, module) => {
6318
6318
 
6319
6319
  // node_modules/cpu-features/build/Release/cpufeatures.node
6320
6320
  var require_cpufeatures = __commonJS((exports, module) => {
6321
- module.exports = __require("./cpufeatures-tjjrgpt7.node");
6321
+ module.exports = __require("./cpufeatures-8g73ch7n.node");
6322
6322
  });
6323
6323
 
6324
6324
  // node_modules/cpu-features/lib/index.js
@@ -6929,9 +6929,14 @@ var require_utils2 = __commonJS((exports, module) => {
6929
6929
  };
6930
6930
  });
6931
6931
 
6932
+ // node_modules/ssh2/lib/protocol/crypto/build/Release/sshcrypto.node
6933
+ var require_sshcrypto = __commonJS((exports, module) => {
6934
+ module.exports = __require("./sshcrypto-f6atjna1.node");
6935
+ });
6936
+
6932
6937
  // node_modules/ssh2/lib/protocol/crypto/poly1305.js
6933
6938
  var require_poly1305 = __commonJS((exports, module) => {
6934
- var __dirname = "/home/runner/work/isol8/isol8/node_modules/ssh2/lib/protocol/crypto", __filename = "/home/runner/work/isol8/isol8/node_modules/ssh2/lib/protocol/crypto/poly1305.js";
6939
+ var __dirname = "/Users/dhruv/Developer/Projects/isol8/node_modules/ssh2/lib/protocol/crypto", __filename = "/Users/dhruv/Developer/Projects/isol8/node_modules/ssh2/lib/protocol/crypto/poly1305.js";
6935
6940
  var createPoly1305 = function() {
6936
6941
  var _scriptDir = typeof document !== "undefined" && document.currentScript ? document.currentScript.src : undefined;
6937
6942
  if (typeof __filename !== "undefined")
@@ -7415,7 +7420,7 @@ var require_crypto = __commonJS((exports, module) => {
7415
7420
  var ChaChaPolyDecipher;
7416
7421
  var GenericDecipher;
7417
7422
  try {
7418
- binding = (()=>{throw new Error("Cannot require module "+"./crypto/build/Release/sshcrypto.node");})();
7423
+ binding = require_sshcrypto();
7419
7424
  ({
7420
7425
  AESGCMCipher,
7421
7426
  ChaChaPolyCipher,
@@ -8676,7 +8681,7 @@ ${formatted}-----END ${type} KEY-----`;
8676
8681
  }
8677
8682
  return Buffer.from(hex, "hex");
8678
8683
  }
8679
- return function genOpenSSLRSAPriv2(n, e, d, iqmp, p, q) {
8684
+ return function genOpenSSLRSAPriv(n, e, d, iqmp, p, q) {
8680
8685
  const bn_d = bigIntFromBuffer(d);
8681
8686
  const dmp1 = bigIntToBuffer(bn_d % (bigIntFromBuffer(p) - 1n));
8682
8687
  const dmq1 = bigIntToBuffer(bn_d % (bigIntFromBuffer(q) - 1n));
@@ -9704,7 +9709,7 @@ ${formatted}-----END ${type} KEY-----`;
9704
9709
 
9705
9710
  // node_modules/ssh2/lib/agent.js
9706
9711
  var require_agent = __commonJS((exports, module) => {
9707
- var __dirname = "/home/runner/work/isol8/isol8/node_modules/ssh2/lib";
9712
+ var __dirname = "/Users/dhruv/Developer/Projects/isol8/node_modules/ssh2/lib";
9708
9713
  var { Socket } = __require("net");
9709
9714
  var { Duplex } = __require("stream");
9710
9715
  var { resolve } = __require("path");
@@ -21677,7 +21682,7 @@ var require__stream_writable = __commonJS((exports, module) => {
21677
21682
  }
21678
21683
  });
21679
21684
  } else {
21680
- realHasInstance = function realHasInstance2(object) {
21685
+ realHasInstance = function realHasInstance(object) {
21681
21686
  return object instanceof this;
21682
21687
  };
21683
21688
  }
@@ -22475,28 +22480,28 @@ var require_end_of_stream = __commonJS((exports, module) => {
22475
22480
  callback = once(callback || noop);
22476
22481
  var readable = opts.readable || opts.readable !== false && stream.readable;
22477
22482
  var writable = opts.writable || opts.writable !== false && stream.writable;
22478
- var onlegacyfinish = function onlegacyfinish2() {
22483
+ var onlegacyfinish = function onlegacyfinish() {
22479
22484
  if (!stream.writable)
22480
22485
  onfinish();
22481
22486
  };
22482
22487
  var writableEnded = stream._writableState && stream._writableState.finished;
22483
- var onfinish = function onfinish2() {
22488
+ var onfinish = function onfinish() {
22484
22489
  writable = false;
22485
22490
  writableEnded = true;
22486
22491
  if (!readable)
22487
22492
  callback.call(stream);
22488
22493
  };
22489
22494
  var readableEnded = stream._readableState && stream._readableState.endEmitted;
22490
- var onend = function onend2() {
22495
+ var onend = function onend() {
22491
22496
  readable = false;
22492
22497
  readableEnded = true;
22493
22498
  if (!writable)
22494
22499
  callback.call(stream);
22495
22500
  };
22496
- var onerror = function onerror2(err) {
22501
+ var onerror = function onerror(err) {
22497
22502
  callback.call(stream, err);
22498
22503
  };
22499
- var onclose = function onclose2() {
22504
+ var onclose = function onclose() {
22500
22505
  var err;
22501
22506
  if (readable && !readableEnded) {
22502
22507
  if (!stream._readableState || !stream._readableState.ended)
@@ -22509,7 +22514,7 @@ var require_end_of_stream = __commonJS((exports, module) => {
22509
22514
  return callback.call(stream, err);
22510
22515
  }
22511
22516
  };
22512
- var onrequest = function onrequest2() {
22517
+ var onrequest = function onrequest() {
22513
22518
  stream.req.on("finish", onfinish);
22514
22519
  };
22515
22520
  if (isRequest(stream)) {
@@ -22666,7 +22671,7 @@ var require_async_iterator = __commonJS((exports, module) => {
22666
22671
  });
22667
22672
  });
22668
22673
  }), _Object$setPrototypeO), AsyncIteratorPrototype);
22669
- var createReadableStreamAsyncIterator = function createReadableStreamAsyncIterator2(stream) {
22674
+ var createReadableStreamAsyncIterator = function createReadableStreamAsyncIterator(stream) {
22670
22675
  var _Object$create;
22671
22676
  var iterator = Object.create(ReadableStreamAsyncIteratorPrototype, (_Object$create = {}, _defineProperty(_Object$create, kStream, {
22672
22677
  value: stream,
@@ -22855,7 +22860,7 @@ var require__stream_readable = __commonJS((exports, module) => {
22855
22860
  var Duplex;
22856
22861
  Readable.ReadableState = ReadableState;
22857
22862
  var EE = __require("events").EventEmitter;
22858
- var EElistenerCount = function EElistenerCount2(emitter, type) {
22863
+ var EElistenerCount = function EElistenerCount(emitter, type) {
22859
22864
  return emitter.listeners(type).length;
22860
22865
  };
22861
22866
  var Stream = __require("stream");
@@ -22872,7 +22877,7 @@ var require__stream_readable = __commonJS((exports, module) => {
22872
22877
  if (debugUtil && debugUtil.debuglog) {
22873
22878
  debug = debugUtil.debuglog("stream");
22874
22879
  } else {
22875
- debug = function debug2() {};
22880
+ debug = function debug() {};
22876
22881
  }
22877
22882
  var BufferList = require_buffer_list();
22878
22883
  var destroyImpl = require_destroy();
@@ -25530,14 +25535,14 @@ var require_BufferList = __commonJS((exports, module) => {
25530
25535
  if (srcEnd <= 0) {
25531
25536
  return dst || Buffer2.alloc(0);
25532
25537
  }
25533
- const copy2 = !!dst;
25538
+ const copy = !!dst;
25534
25539
  const off = this._offset(srcStart);
25535
25540
  const len = srcEnd - srcStart;
25536
25541
  let bytes = len;
25537
- let bufoff = copy2 && dstStart || 0;
25542
+ let bufoff = copy && dstStart || 0;
25538
25543
  let start = off[1];
25539
25544
  if (srcStart === 0 && srcEnd === this.length) {
25540
- if (!copy2) {
25545
+ if (!copy) {
25541
25546
  return this._bufs.length === 1 ? this._bufs[0] : Buffer2.concat(this._bufs, this.length);
25542
25547
  }
25543
25548
  for (let i = 0;i < this._bufs.length; i++) {
@@ -25547,9 +25552,9 @@ var require_BufferList = __commonJS((exports, module) => {
25547
25552
  return dst;
25548
25553
  }
25549
25554
  if (bytes <= this._bufs[off[0]].length - start) {
25550
- return copy2 ? this._bufs[off[0]].copy(dst, dstStart, start, start + bytes) : this._bufs[off[0]].slice(start, start + bytes);
25555
+ return copy ? this._bufs[off[0]].copy(dst, dstStart, start, start + bytes) : this._bufs[off[0]].slice(start, start + bytes);
25551
25556
  }
25552
- if (!copy2) {
25557
+ if (!copy) {
25553
25558
  dst = Buffer2.allocUnsafe(len);
25554
25559
  }
25555
25560
  for (let i = off[0];i < this._bufs.length; i++) {
@@ -25771,7 +25776,7 @@ var require_bl = __commonJS((exports, module) => {
25771
25776
  }
25772
25777
  if (typeof callback === "function") {
25773
25778
  this._callback = callback;
25774
- const piper = function piper2(err) {
25779
+ const piper = function piper(err) {
25775
25780
  if (this._callback) {
25776
25781
  this._callback(err);
25777
25782
  this._callback = null;
@@ -34834,7 +34839,7 @@ var require_writer2 = __commonJS((exports, module) => {
34834
34839
  this.tail = this.head;
34835
34840
  this.states = null;
34836
34841
  }
34837
- var create = function create2() {
34842
+ var create = function create() {
34838
34843
  return util.Buffer ? function create_buffer_setup() {
34839
34844
  return (Writer.create = function create_buffer() {
34840
34845
  return new BufferWriter;
@@ -35058,12 +35063,12 @@ var require_reader2 = __commonJS((exports, module) => {
35058
35063
  if (buffer instanceof Uint8Array || Array.isArray(buffer))
35059
35064
  return new Reader(buffer);
35060
35065
  throw Error("illegal buffer");
35061
- } : function create_array2(buffer) {
35066
+ } : function create_array(buffer) {
35062
35067
  if (Array.isArray(buffer))
35063
35068
  return new Reader(buffer);
35064
35069
  throw Error("illegal buffer");
35065
35070
  };
35066
- var create = function create2() {
35071
+ var create = function create() {
35067
35072
  return util.Buffer ? function create_buffer_setup(buffer) {
35068
35073
  return (Reader.create = function create_buffer(buffer2) {
35069
35074
  return util.Buffer.isBuffer(buffer2) ? new BufferReader(buffer2) : create_array(buffer2);
@@ -35489,10 +35494,10 @@ var require_fetch = __commonJS((exports, module) => {
35489
35494
  // node_modules/@protobufjs/path/index.js
35490
35495
  var require_path = __commonJS((exports) => {
35491
35496
  var path = exports;
35492
- var isAbsolute = path.isAbsolute = function isAbsolute2(path2) {
35497
+ var isAbsolute = path.isAbsolute = function isAbsolute(path2) {
35493
35498
  return /^(?:\/|\w+:)/.test(path2);
35494
35499
  };
35495
- var normalize = path.normalize = function normalize2(path2) {
35500
+ var normalize = path.normalize = function normalize(path2) {
35496
35501
  path2 = path2.replace(/\\/g, "/").replace(/\/{2,}/g, "/");
35497
35502
  var parts = path2.split("/"), absolute = isAbsolute(path2), prefix = "";
35498
35503
  if (absolute)
@@ -35657,7 +35662,7 @@ var require_namespace = __commonJS((exports, module) => {
35657
35662
  object.onRemove(this);
35658
35663
  return clearCache(this);
35659
35664
  };
35660
- Namespace.prototype.define = function define2(path, json) {
35665
+ Namespace.prototype.define = function define(path, json) {
35661
35666
  if (util.isString(path))
35662
35667
  path = path.split(".");
35663
35668
  else if (!Array.isArray(path))
@@ -42473,7 +42478,7 @@ var require_src3 = __commonJS((exports) => {
42473
42478
 
42474
42479
  // node_modules/@grpc/grpc-js/build/src/channelz.js
42475
42480
  var require_channelz = __commonJS((exports) => {
42476
- var __dirname = "/home/runner/work/isol8/isol8/node_modules/@grpc/grpc-js/build/src";
42481
+ var __dirname = "/Users/dhruv/Developer/Projects/isol8/node_modules/@grpc/grpc-js/build/src";
42477
42482
  Object.defineProperty(exports, "__esModule", { value: true });
42478
42483
  exports.registerChannelzSocket = exports.registerChannelzServer = exports.registerChannelzSubchannel = exports.registerChannelzChannel = exports.ChannelzCallTrackerStub = exports.ChannelzCallTracker = exports.ChannelzChildrenTrackerStub = exports.ChannelzChildrenTracker = exports.ChannelzTrace = exports.ChannelzTraceStub = undefined;
42479
42484
  exports.unregisterChannelzRef = unregisterChannelzRef;
@@ -47876,7 +47881,7 @@ var require_duration = __commonJS((exports) => {
47876
47881
 
47877
47882
  // node_modules/@grpc/grpc-js/build/src/orca.js
47878
47883
  var require_orca = __commonJS((exports) => {
47879
- var __dirname = "/home/runner/work/isol8/isol8/node_modules/@grpc/grpc-js/build/src";
47884
+ var __dirname = "/Users/dhruv/Developer/Projects/isol8/node_modules/@grpc/grpc-js/build/src";
47880
47885
  Object.defineProperty(exports, "__esModule", { value: true });
47881
47886
  exports.OrcaOobMetricsSubchannelWrapper = exports.GRPC_METRICS_HEADER = exports.ServerMetricRecorder = exports.PerRequestMetricRecorder = undefined;
47882
47887
  exports.createOrcaClient = createOrcaClient;
@@ -53265,7 +53270,7 @@ var require_dist = __commonJS((exports) => {
53265
53270
 
53266
53271
  // node_modules/dockerode/lib/session.js
53267
53272
  var require_session = __commonJS((exports, module) => {
53268
- var __dirname = "/home/runner/work/isol8/isol8/node_modules/dockerode/lib";
53273
+ var __dirname = "/Users/dhruv/Developer/Projects/isol8/node_modules/dockerode/lib";
53269
53274
  var grpc = require_src4();
53270
53275
  var protoLoader = require_src5();
53271
53276
  var path = __require("path");
@@ -54491,7 +54496,7 @@ var require_docker = __commonJS((exports, module) => {
54491
54496
  stream: true,
54492
54497
  stdout: true,
54493
54498
  stderr: true
54494
- }, function handler2(err2, stream) {
54499
+ }, function handler(err2, stream) {
54495
54500
  if (err2)
54496
54501
  return callback(err2, null, container);
54497
54502
  hub.emit("stream", stream);
@@ -54780,7 +54785,8 @@ function mergeConfig(defaults, overrides) {
54780
54785
  maxConcurrent: overrides.maxConcurrent ?? defaults.maxConcurrent,
54781
54786
  defaults: {
54782
54787
  ...defaults.defaults,
54783
- ...overrides.defaults
54788
+ ...overrides.defaults,
54789
+ readonlyRootFs: overrides.defaults?.readonlyRootFs ?? defaults.defaults.readonlyRootFs
54784
54790
  },
54785
54791
  network: {
54786
54792
  whitelist: overrides.network?.whitelist ?? defaults.network.whitelist,
@@ -54824,7 +54830,8 @@ var init_config = __esm(() => {
54824
54830
  cpuLimit: 1,
54825
54831
  network: "none",
54826
54832
  sandboxSize: "512m",
54827
- tmpSize: "256m"
54833
+ tmpSize: "256m",
54834
+ readonlyRootFs: true
54828
54835
  },
54829
54836
  network: {
54830
54837
  whitelist: [],
@@ -55412,6 +55419,73 @@ class Semaphore {
55412
55419
  }
55413
55420
  }
55414
55421
 
55422
+ // src/engine/default-seccomp-profile.ts
55423
+ var EMBEDDED_DEFAULT_SECCOMP_PROFILE;
55424
+ var init_default_seccomp_profile = __esm(() => {
55425
+ EMBEDDED_DEFAULT_SECCOMP_PROFILE = JSON.stringify({
55426
+ defaultAction: "SCMP_ACT_ALLOW",
55427
+ architectures: ["SCMP_ARCH_X86_64", "SCMP_ARCH_X86", "SCMP_ARCH_X32", "SCMP_ARCH_AARCH64"],
55428
+ syscalls: [
55429
+ {
55430
+ names: [
55431
+ "acct",
55432
+ "add_key",
55433
+ "bpf",
55434
+ "clock_adjtime",
55435
+ "clock_settime",
55436
+ "create_module",
55437
+ "delete_module",
55438
+ "finit_module",
55439
+ "get_mempolicy",
55440
+ "init_module",
55441
+ "ioperm",
55442
+ "iopl",
55443
+ "kcmp",
55444
+ "kexec_file_load",
55445
+ "kexec_load",
55446
+ "keyctl",
55447
+ "lookup_dcookie",
55448
+ "mbind",
55449
+ "mount",
55450
+ "move_pages",
55451
+ "name_to_handle_at",
55452
+ "open_by_handle_at",
55453
+ "perf_event_open",
55454
+ "pivot_root",
55455
+ "process_vm_readv",
55456
+ "process_vm_writev",
55457
+ "ptrace",
55458
+ "query_module",
55459
+ "quotactl",
55460
+ "reboot",
55461
+ "request_key",
55462
+ "set_mempolicy",
55463
+ "setns",
55464
+ "settimeofday",
55465
+ "stime",
55466
+ "swapon",
55467
+ "swapoff",
55468
+ "sysfs",
55469
+ "syslog",
55470
+ "umount",
55471
+ "umount2",
55472
+ "unshare",
55473
+ "uselib",
55474
+ "userfaultfd",
55475
+ "ustat",
55476
+ "vm86",
55477
+ "vm86old"
55478
+ ],
55479
+ action: "SCMP_ACT_ERRNO",
55480
+ args: [],
55481
+ comment: "",
55482
+ includes: {},
55483
+ excludes: {}
55484
+ }
55485
+ ]
55486
+ });
55487
+ });
55488
+
55415
55489
  // src/engine/utils.ts
55416
55490
  var exports_utils = {};
55417
55491
  __export(exports_utils, {
@@ -55518,6 +55592,15 @@ function validatePackageName(name) {
55518
55592
  }
55519
55593
 
55520
55594
  // src/engine/image-builder.ts
55595
+ var exports_image_builder = {};
55596
+ __export(exports_image_builder, {
55597
+ normalizePackages: () => normalizePackages,
55598
+ imageExists: () => imageExists,
55599
+ getCustomImageTag: () => getCustomImageTag,
55600
+ ensureImages: () => ensureImages,
55601
+ buildCustomImages: () => buildCustomImages,
55602
+ buildBaseImages: () => buildBaseImages
55603
+ });
55521
55604
  import { createHash as createHash2 } from "node:crypto";
55522
55605
  import { existsSync as existsSync3, readFileSync as readFileSync2 } from "node:fs";
55523
55606
  import { join as join3 } from "node:path";
@@ -55576,8 +55659,9 @@ async function removeImage(docker, imageId) {
55576
55659
  logger.debug(`[ImageBuilder] Could not remove image ${imageId.slice(0, 12)}: ${err}`);
55577
55660
  }
55578
55661
  }
55579
- async function buildBaseImages(docker, onProgress, force = false) {
55580
- const runtimes = RuntimeRegistry.list();
55662
+ async function buildBaseImages(docker, onProgress, force = false, onlyRuntimes) {
55663
+ const allRuntimes = RuntimeRegistry.list();
55664
+ const runtimes = onlyRuntimes ? allRuntimes.filter((r) => onlyRuntimes.includes(r.name)) : allRuntimes;
55581
55665
  const dockerHash = computeDockerDirHash();
55582
55666
  logger.debug(`[ImageBuilder] Docker directory hash: ${dockerHash.slice(0, 16)}...`);
55583
55667
  for (const adapter of runtimes) {
@@ -55727,6 +55811,26 @@ ${installCmd}
55727
55811
  }
55728
55812
  onProgress?.({ runtime, status: "done" });
55729
55813
  }
55814
+ async function imageExists(docker, imageName) {
55815
+ try {
55816
+ await docker.getImage(imageName).inspect();
55817
+ return true;
55818
+ } catch {
55819
+ return false;
55820
+ }
55821
+ }
55822
+ async function ensureImages(docker, onProgress) {
55823
+ const runtimes = RuntimeRegistry.list();
55824
+ const missing = [];
55825
+ for (const adapter of runtimes) {
55826
+ if (!await imageExists(docker, adapter.image)) {
55827
+ missing.push(adapter.name);
55828
+ }
55829
+ }
55830
+ if (missing.length > 0) {
55831
+ await buildBaseImages(docker, onProgress, false, missing);
55832
+ }
55833
+ }
55730
55834
  var DOCKERFILE_DIR, LABELS, DOCKER_BUILD_FILES;
55731
55835
  var init_image_builder = __esm(() => {
55732
55836
  init_runtime();
@@ -56155,7 +56259,19 @@ function wrapWithTimeout(cmd, timeoutSec) {
56155
56259
  function getInstallCommand(runtime, packages) {
56156
56260
  switch (runtime) {
56157
56261
  case "python":
56158
- return ["pip", "install", "--user", "--no-cache-dir", "--break-system-packages", ...packages];
56262
+ return [
56263
+ "pip",
56264
+ "install",
56265
+ "--user",
56266
+ "--no-cache-dir",
56267
+ "--break-system-packages",
56268
+ "--disable-pip-version-check",
56269
+ "--retries",
56270
+ "0",
56271
+ "--timeout",
56272
+ "15",
56273
+ ...packages
56274
+ ];
56159
56275
  case "node":
56160
56276
  return ["npm", "install", "--prefix", "/sandbox", ...packages];
56161
56277
  case "bun":
@@ -56168,8 +56284,9 @@ function getInstallCommand(runtime, packages) {
56168
56284
  throw new Error(`Unknown runtime for package install: ${runtime}`);
56169
56285
  }
56170
56286
  }
56171
- async function installPackages(container, runtime, packages) {
56172
- const cmd = getInstallCommand(runtime, packages);
56287
+ async function installPackages(container, runtime, packages, timeoutMs) {
56288
+ const timeoutSec = Math.max(1, Math.ceil(timeoutMs / 1000));
56289
+ const cmd = wrapWithTimeout(getInstallCommand(runtime, packages), timeoutSec);
56173
56290
  logger.debug(`Installing packages: ${JSON.stringify(cmd)}`);
56174
56291
  const env2 = [
56175
56292
  "PATH=/sandbox/.local/bin:/sandbox/.npm-global/bin:/sandbox/.bun-global/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin"
@@ -56180,6 +56297,12 @@ async function installPackages(container, runtime, packages) {
56180
56297
  env2.push("NPM_CONFIG_PREFIX=/sandbox/.npm-global");
56181
56298
  env2.push("NPM_CONFIG_CACHE=/sandbox/.npm-cache");
56182
56299
  env2.push("npm_config_cache=/sandbox/.npm-cache");
56300
+ env2.push("NPM_CONFIG_FETCH_RETRIES=0");
56301
+ env2.push("npm_config_fetch_retries=0");
56302
+ env2.push("NPM_CONFIG_FETCH_RETRY_MINTIMEOUT=1000");
56303
+ env2.push("npm_config_fetch_retry_mintimeout=1000");
56304
+ env2.push("NPM_CONFIG_FETCH_RETRY_MAXTIMEOUT=2000");
56305
+ env2.push("npm_config_fetch_retry_maxtimeout=2000");
56183
56306
  } else if (runtime === "bun") {
56184
56307
  env2.push("BUN_INSTALL_GLOBAL_DIR=/sandbox/.bun-global");
56185
56308
  env2.push("BUN_INSTALL_CACHE_DIR=/sandbox/.bun-cache");
@@ -56201,7 +56324,13 @@ async function installPackages(container, runtime, packages) {
56201
56324
  const stderrStream = new PassThrough;
56202
56325
  container.modem.demuxStream(stream, stdoutStream, stderrStream);
56203
56326
  stderrStream.on("data", (chunk) => {
56204
- stderr += chunk.toString();
56327
+ const text = chunk.toString();
56328
+ stderr += text;
56329
+ logger.debug(`[install:${runtime}:stderr] ${text.trimEnd()}`);
56330
+ });
56331
+ stdoutStream.on("data", (chunk) => {
56332
+ const text = chunk.toString();
56333
+ logger.debug(`[install:${runtime}:stdout] ${text.trimEnd()}`);
56205
56334
  });
56206
56335
  stream.on("end", async () => {
56207
56336
  try {
@@ -56531,7 +56660,7 @@ class DockerIsol8 {
56531
56660
  const filePath = `${SANDBOX_WORKDIR}/main${ext}`;
56532
56661
  await writeFileViaExec(container, filePath, request.code);
56533
56662
  if (request.installPackages?.length) {
56534
- await installPackages(container, request.runtime, request.installPackages);
56663
+ await installPackages(container, request.runtime, request.installPackages, timeoutMs);
56535
56664
  }
56536
56665
  if (request.files) {
56537
56666
  for (const [fPath, fContent] of Object.entries(request.files)) {
@@ -56600,6 +56729,26 @@ class DockerIsol8 {
56600
56729
  resolvedImage = legacyCustomTag;
56601
56730
  } catch {}
56602
56731
  }
56732
+ try {
56733
+ await this.docker.getImage(resolvedImage).inspect();
56734
+ } catch {
56735
+ logger.debug(`[ImageBuilder] Image ${resolvedImage} not found. Building...`);
56736
+ const { buildBaseImages: buildBaseImages2, buildCustomImages: buildCustomImages2 } = await Promise.resolve().then(() => (init_image_builder(), exports_image_builder));
56737
+ if (resolvedImage !== adapter.image && normalizedDeps.length > 0) {
56738
+ try {
56739
+ await this.docker.getImage(adapter.image).inspect();
56740
+ } catch {
56741
+ logger.debug(`[ImageBuilder] Base image ${adapter.image} missing. Building...`);
56742
+ await buildBaseImages2(this.docker, undefined, false, [adapter.name]);
56743
+ }
56744
+ logger.debug(`[ImageBuilder] Building custom image for ${adapter.name}...`);
56745
+ const dummyConfig = { dependencies: { [adapter.name]: normalizedDeps } };
56746
+ await buildCustomImages2(this.docker, dummyConfig, undefined, false);
56747
+ } else {
56748
+ logger.debug(`[ImageBuilder] Building base image for ${adapter.name}...`);
56749
+ await buildBaseImages2(this.docker, undefined, false, [adapter.name]);
56750
+ }
56751
+ }
56603
56752
  this.imageCache.set(cacheKey, resolvedImage);
56604
56753
  return resolvedImage;
56605
56754
  }
@@ -56660,7 +56809,7 @@ class DockerIsol8 {
56660
56809
  rawCmd = adapter.getCommand(req.code, filePath);
56661
56810
  }
56662
56811
  if (req.installPackages?.length) {
56663
- await installPackages(container, req.runtime, req.installPackages);
56812
+ await installPackages(container, req.runtime, req.installPackages, timeoutMs);
56664
56813
  }
56665
56814
  const timeoutSec = Math.ceil(timeoutMs / 1000);
56666
56815
  let cmd;
@@ -56768,7 +56917,7 @@ class DockerIsol8 {
56768
56917
  const rawCmd = adapter.getCommand(req.code, filePath);
56769
56918
  const timeoutSec = Math.ceil(timeoutMs / 1000);
56770
56919
  if (req.installPackages?.length) {
56771
- await installPackages(this.container, req.runtime, req.installPackages);
56920
+ await installPackages(this.container, req.runtime, req.installPackages, timeoutMs);
56772
56921
  }
56773
56922
  let cmd;
56774
56923
  if (req.stdin) {
@@ -56911,17 +57060,15 @@ class DockerIsol8 {
56911
57060
  const profile = readFileSync3(this.security.customProfilePath, "utf-8");
56912
57061
  opts.push(`seccomp=${profile}`);
56913
57062
  } catch (e) {
56914
- logger.error(`Failed to load custom seccomp profile: ${e}`);
57063
+ throw new Error(`Failed to load custom seccomp profile at ${this.security.customProfilePath}: ${e}`);
56915
57064
  }
56916
57065
  return opts;
56917
57066
  }
56918
57067
  try {
56919
57068
  const profile = this.loadDefaultSeccompProfile();
56920
- if (profile) {
56921
- opts.push(`seccomp=${profile}`);
56922
- }
57069
+ opts.push(`seccomp=${profile}`);
56923
57070
  } catch (e) {
56924
- logger.error(`Failed to load default seccomp profile: ${e}`);
57071
+ throw new Error(`Failed to load default seccomp profile: ${e}`);
56925
57072
  }
56926
57073
  return opts;
56927
57074
  }
@@ -56934,8 +57081,11 @@ class DockerIsol8 {
56934
57081
  if (existsSync4(prodPath)) {
56935
57082
  return readFileSync3(prodPath, "utf-8");
56936
57083
  }
56937
- logger.warn("Could not locate default seccomp profile. Running without seccomp filter.");
56938
- return null;
57084
+ if (EMBEDDED_DEFAULT_SECCOMP_PROFILE.length > 0) {
57085
+ logger.debug(`Default seccomp profile file not found. Using embedded profile. Tried: ${devPath.pathname}, ${prodPath.pathname}`);
57086
+ return EMBEDDED_DEFAULT_SECCOMP_PROFILE;
57087
+ }
57088
+ throw new Error("Embedded default seccomp profile is unavailable");
56939
57089
  }
56940
57090
  buildEnv(extra) {
56941
57091
  const env2 = [
@@ -57156,13 +57306,14 @@ class DockerIsol8 {
57156
57306
  }
57157
57307
  var import_dockerode, SANDBOX_WORKDIR = "/sandbox", MAX_OUTPUT_BYTES, PROXY_PORT = 8118, PROXY_STARTUP_TIMEOUT_MS = 5000, PROXY_POLL_INTERVAL_MS = 100;
57158
57308
  var init_docker = __esm(() => {
57309
+ import_dockerode = __toESM(require_docker(), 1);
57159
57310
  init_runtime();
57160
57311
  init_logger();
57161
57312
  init_audit();
57162
57313
  init_code_fetcher();
57314
+ init_default_seccomp_profile();
57163
57315
  init_image_builder();
57164
57316
  init_pool();
57165
- import_dockerode = __toESM(require_docker(), 1);
57166
57317
  MAX_OUTPUT_BYTES = 1024 * 1024;
57167
57318
  });
57168
57319
 
@@ -57171,7 +57322,7 @@ var package_default;
57171
57322
  var init_package = __esm(() => {
57172
57323
  package_default = {
57173
57324
  name: "isol8",
57174
- version: "0.11.1",
57325
+ version: "0.12.0-alpha.0",
57175
57326
  description: "Secure code execution engine for AI agents",
57176
57327
  author: "Illusion47586",
57177
57328
  license: "MIT",
@@ -58919,6 +59070,50 @@ async function createServer(options) {
58919
59070
  logger.debug(`[Server] Auto-prune: ${config.cleanup.autoPrune}`);
58920
59071
  const app = new Hono2;
58921
59072
  const globalSemaphore = new Semaphore(config.maxConcurrent);
59073
+ let pruneInterval;
59074
+ let cleanupInFlight = null;
59075
+ const cleanupSessions = async () => {
59076
+ let removed = 0;
59077
+ let failed = 0;
59078
+ const errors = [];
59079
+ for (const [id, session] of sessions) {
59080
+ try {
59081
+ await session.engine.stop();
59082
+ removed++;
59083
+ } catch (err) {
59084
+ failed++;
59085
+ const errorMsg = err instanceof Error ? err.message : String(err);
59086
+ errors.push(`${id}: ${errorMsg}`);
59087
+ } finally {
59088
+ sessions.delete(id);
59089
+ }
59090
+ }
59091
+ return { removed, failed, errors };
59092
+ };
59093
+ const runCleanup = async (includeImages) => {
59094
+ if (cleanupInFlight) {
59095
+ return cleanupInFlight;
59096
+ }
59097
+ cleanupInFlight = (async () => {
59098
+ logger.info(`[Server] Starting cleanup (sessions=true containers=true images=${includeImages})`);
59099
+ const sessionsResult = await cleanupSessions();
59100
+ const containersResult = await DockerIsol82.cleanup();
59101
+ const result = {
59102
+ sessions: sessionsResult,
59103
+ containers: containersResult
59104
+ };
59105
+ if (includeImages) {
59106
+ result.images = await DockerIsol82.cleanupImages();
59107
+ }
59108
+ logger.info(`[Server] Cleanup complete: sessions=${result.sessions.removed}/${result.sessions.failed} containers=${result.containers.removed}/${result.containers.failed}${result.images ? ` images=${result.images.removed}/${result.images.failed}` : ""}`);
59109
+ return result;
59110
+ })();
59111
+ try {
59112
+ return await cleanupInFlight;
59113
+ } finally {
59114
+ cleanupInFlight = null;
59115
+ }
59116
+ };
58922
59117
  app.use("*", authMiddleware(options.apiKey));
58923
59118
  app.get("/health", (c) => c.json({ status: "ok", version: VERSION }));
58924
59119
  app.post("/execute", async (c) => {
@@ -59099,8 +59294,21 @@ async function createServer(options) {
59099
59294
  }
59100
59295
  return c.json({ ok: true });
59101
59296
  });
59297
+ app.post("/cleanup", async (c) => {
59298
+ const body = await c.req.json().catch(() => ({}));
59299
+ const includeImages = body.images ?? true;
59300
+ logger.debug(`[Server] POST /cleanup images=${includeImages}`);
59301
+ try {
59302
+ const result = await runCleanup(includeImages);
59303
+ return c.json({ ok: true, ...result });
59304
+ } catch (err) {
59305
+ const message = err instanceof Error ? err.message : String(err);
59306
+ logger.error(`[Server] Cleanup failed: ${message}`);
59307
+ return c.json({ error: message }, 500);
59308
+ }
59309
+ });
59102
59310
  if (config.cleanup.autoPrune) {
59103
- setInterval(async () => {
59311
+ pruneInterval = setInterval(async () => {
59104
59312
  const maxAge = config.cleanup.maxContainerAgeMs;
59105
59313
  const now = Date.now();
59106
59314
  for (const [id, session] of sessions) {
@@ -59118,7 +59326,15 @@ async function createServer(options) {
59118
59326
  return {
59119
59327
  app,
59120
59328
  fetch: app.fetch,
59121
- port: options.port
59329
+ port: options.port,
59330
+ cleanup: async (includeImages = true) => runCleanup(includeImages),
59331
+ shutdown: async (includeImages = true) => {
59332
+ if (pruneInterval) {
59333
+ clearInterval(pruneInterval);
59334
+ pruneInterval = undefined;
59335
+ }
59336
+ await runCleanup(includeImages);
59337
+ }
59122
59338
  };
59123
59339
  }
59124
59340
  var sessions;
@@ -59738,7 +59954,7 @@ onetime.callCount = (function_) => {
59738
59954
  };
59739
59955
  var onetime_default = onetime;
59740
59956
 
59741
- // node_modules/signal-exit/dist/mjs/signals.js
59957
+ // node_modules/restore-cursor/node_modules/signal-exit/dist/mjs/signals.js
59742
59958
  var signals = [];
59743
59959
  signals.push("SIGHUP", "SIGINT", "SIGTERM");
59744
59960
  if (process.platform !== "win32") {
@@ -59748,7 +59964,7 @@ if (process.platform === "linux") {
59748
59964
  signals.push("SIGIO", "SIGPOLL", "SIGPWR", "SIGSTKFLT");
59749
59965
  }
59750
59966
 
59751
- // node_modules/signal-exit/dist/mjs/index.js
59967
+ // node_modules/restore-cursor/node_modules/signal-exit/dist/mjs/index.js
59752
59968
  var processOk = (process3) => !!process3 && typeof process3 === "object" && typeof process3.removeListener === "function" && typeof process3.emit === "function" && typeof process3.reallyExit === "function" && typeof process3.listeners === "function" && typeof process3.kill === "function" && typeof process3.pid === "number" && typeof process3.on === "function";
59753
59969
  var kExitEmitter = Symbol.for("signal-exit emitter");
59754
59970
  var global2 = globalThis;
@@ -62633,7 +62849,7 @@ program2.command("setup").description("Check Docker and build isol8 images").opt
62633
62849
  console.log(`
62634
62850
  [DONE] Setup complete!`);
62635
62851
  });
62636
- 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, 512m)").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("--url <url>", "Fetch code from URL").option("--github <path>", "GitHub shorthand: owner/repo/ref/path/to/file").option("--gist <path>", "Gist shorthand: gistId/file.ext").option("--hash <sha256>", "Expected SHA-256 hash of fetched code").option("--allow-insecure-code-url", "Allow insecure HTTP code URLs").option("--host <url>", "Execute on remote server").option("--key <key>", "API key for remote server").option("--no-stream", "Disable real-time output streaming").option("--debug", "Enable debug logging").option("--persist", "Keep container running after execution for inspection").option("--log-network", "Log all network requests (requires --net filtered)").action(async (file, opts) => {
62852
+ 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("--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, 512m)").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("--url <url>", "Fetch code from URL").option("--github <path>", "GitHub shorthand: owner/repo/ref/path/to/file").option("--gist <path>", "Gist shorthand: gistId/file.ext").option("--hash <sha256>", "Expected SHA-256 hash of fetched code").option("--allow-insecure-code-url", "Allow insecure HTTP code URLs").option("--host <url>", "Execute on remote server").option("--key <key>", "API key for remote server").option("--no-stream", "Disable real-time output streaming").option("--debug", "Enable debug logging").option("--persist", "Keep container running after execution for inspection").option("--log-network", "Log all network requests (requires --net filtered)").action(async (file, opts) => {
62637
62853
  const {
62638
62854
  code,
62639
62855
  codeUrl,
@@ -62762,9 +62978,39 @@ program2.command("serve").description("Start the isol8 remote server").option("-
62762
62978
  logger.debug("[Serve] Running under Bun, starting server in-process");
62763
62979
  const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), exports_server));
62764
62980
  const server = await createServer2({ port, apiKey, debug: opts.debug ?? false });
62981
+ let shuttingDown = false;
62982
+ const bunServer = Bun.serve({ fetch: server.app.fetch, port });
62983
+ const shutdown = async () => {
62984
+ if (shuttingDown) {
62985
+ return;
62986
+ }
62987
+ shuttingDown = true;
62988
+ logger.info("[Serve] Shutting down server and cleaning up resources...");
62989
+ bunServer.stop();
62990
+ try {
62991
+ await server.shutdown();
62992
+ logger.info("[Serve] Cleanup complete");
62993
+ process.exit(0);
62994
+ } catch (err) {
62995
+ const message = err instanceof Error ? err.message : String(err);
62996
+ logger.error(`[Serve] Cleanup failed: ${message}`);
62997
+ process.exit(1);
62998
+ }
62999
+ };
63000
+ process.on("SIGINT", () => {
63001
+ shutdown().catch((err) => {
63002
+ const message = err instanceof Error ? err.message : String(err);
63003
+ logger.error(`[Serve] Shutdown handler failed: ${message}`);
63004
+ });
63005
+ });
63006
+ process.on("SIGTERM", () => {
63007
+ shutdown().catch((err) => {
63008
+ const message = err instanceof Error ? err.message : String(err);
63009
+ logger.error(`[Serve] Shutdown handler failed: ${message}`);
63010
+ });
63011
+ });
62765
63012
  console.log(`[INFO] isol8 server v${VERSION} listening on http://localhost:${port}`);
62766
63013
  console.log(" Auth: Bearer token required");
62767
- Bun.serve({ fetch: server.app.fetch, port });
62768
63014
  return;
62769
63015
  }
62770
63016
  logger.debug("[Serve] Running under Node.js, launching standalone binary");
@@ -63185,6 +63431,7 @@ program2.command("cleanup").description("Remove orphaned isol8 containers (and o
63185
63431
  async function resolveRunInput(file, opts) {
63186
63432
  const config = loadConfig();
63187
63433
  logger.debug("[Run] Config loaded");
63434
+ const hasExplicitNetFlag = process.argv.some((arg) => arg === "--net");
63188
63435
  let code;
63189
63436
  let codeUrl;
63190
63437
  let codeHash;
@@ -63249,7 +63496,6 @@ async function resolveRunInput(file, opts) {
63249
63496
  timeoutMs: opts.timeout ? Number.parseInt(opts.timeout, 10) : config.defaults.timeoutMs,
63250
63497
  ...opts.image ? { image: opts.image } : {},
63251
63498
  ...opts.pidsLimit ? { pidsLimit: Number.parseInt(opts.pidsLimit, 10) } : {},
63252
- ...opts.writable ? { readonlyRootFs: false } : {},
63253
63499
  ...opts.maxOutput ? { maxOutputSize: Number.parseInt(opts.maxOutput, 10) } : {},
63254
63500
  ...opts.tmpSize ? { tmpSize: opts.tmpSize } : {},
63255
63501
  debug: opts.debug ?? config.debug,
@@ -63258,6 +63504,20 @@ async function resolveRunInput(file, opts) {
63258
63504
  dependencies: config.dependencies,
63259
63505
  remoteCode: config.remoteCode
63260
63506
  };
63507
+ if (opts.install.length > 0 && !hasExplicitNetFlag) {
63508
+ engineOptions.network = "filtered";
63509
+ logger.debug("[Run] --install detected without explicit --net; using filtered network mode automatically");
63510
+ }
63511
+ if (opts.install.length > 0 && engineOptions.network === "filtered") {
63512
+ const runtimeRegistryAllowlist = getDefaultRegistryAllowPatterns(runtime);
63513
+ if (runtimeRegistryAllowlist.length > 0) {
63514
+ engineOptions.networkFilter = {
63515
+ whitelist: Array.from(new Set([...engineOptions.networkFilter?.whitelist ?? [], ...runtimeRegistryAllowlist])),
63516
+ blacklist: engineOptions.networkFilter?.blacklist ?? []
63517
+ };
63518
+ logger.debug(`[Run] Added default package registries for ${runtime}: ${runtimeRegistryAllowlist.join(", ")}`);
63519
+ }
63520
+ }
63261
63521
  logger.debug(`[Run] Engine options: mode=${engineOptions.mode}, network=${engineOptions.network}`);
63262
63522
  let fileExtension;
63263
63523
  if (file) {
@@ -63333,6 +63593,19 @@ function detectRuntimeFromPath(pathValue) {
63333
63593
  return;
63334
63594
  }
63335
63595
  }
63596
+ function getDefaultRegistryAllowPatterns(runtime) {
63597
+ switch (runtime) {
63598
+ case "python":
63599
+ return ["^pypi\\.org$", "^files\\.pythonhosted\\.org$"];
63600
+ case "node":
63601
+ case "bun":
63602
+ return ["^registry\\.npmjs\\.org$"];
63603
+ case "bash":
63604
+ return ["^dl-cdn\\.alpinelinux\\.org$"];
63605
+ default:
63606
+ return [];
63607
+ }
63608
+ }
63336
63609
  function collect(value, previous) {
63337
63610
  return previous.concat([value]);
63338
63611
  }
@@ -63342,4 +63615,4 @@ if (!process.argv.slice(2).length) {
63342
63615
  }
63343
63616
  program2.parse();
63344
63617
 
63345
- //# debugId=33A00A6A263B687D64756E2164756E21
63618
+ //# debugId=3F3ACB896496CF6F64756E2164756E21