@impz/testing 6.4.2 → 6.6.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.
Files changed (2) hide show
  1. package/dist/index.js +297 -158
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -18834,7 +18834,11 @@ import { createImpClient as createImpClient2, watchEvents } from "@impz/client";
18834
18834
  // packages/daemon/src/vm/storage/data-layout.ts
18835
18835
  import { mkdirSync } from "fs";
18836
18836
  import { join } from "path";
18837
- var UFFD_RUN_FILES = { socket: "uffd.sock", pidFile: "uffd.pid" };
18837
+ var UFFD_RUN_FILES = {
18838
+ socket: "uffd.sock",
18839
+ pidFile: "uffd.pid",
18840
+ statsFile: "uffd.stats"
18841
+ };
18838
18842
  var DATA_DIRS = ["db", "system", "images", "imps"];
18839
18843
  function createDataDirs(dataDir) {
18840
18844
  for (const name of DATA_DIRS) {
@@ -18864,6 +18868,7 @@ function buildImpPaths(dataDir, impId) {
18864
18868
  pidFile: join(runDir, "pid"),
18865
18869
  uffdSocket: join(runDir, UFFD_RUN_FILES.socket),
18866
18870
  uffdPidFile: join(runDir, UFFD_RUN_FILES.pidFile),
18871
+ uffdStatsFile: join(runDir, UFFD_RUN_FILES.statsFile),
18867
18872
  ...buildSnapshotPaths(join(directory, "snapshot")),
18868
18873
  vmIdentity: join(directory, "vm.json"),
18869
18874
  checkpointsDir: join(directory, "checkpoints"),
@@ -21961,18 +21966,19 @@ function parseKsmConfig(parsed) {
21961
21966
  }
21962
21967
 
21963
21968
  // packages/daemon/src/create-impd.ts
21964
- import { readFileSync as readFileSync36 } from "fs";
21969
+ import { readFileSync as readFileSync38 } from "fs";
21965
21970
  import { release as release2 } from "os";
21966
- import { join as join47 } from "path";
21971
+ import { join as join48 } from "path";
21967
21972
  // packages/daemon/package.json
21968
21973
  var package_default = {
21969
21974
  name: "@impz/daemon",
21970
- version: "6.4.2",
21975
+ version: "6.6.0",
21971
21976
  private: true,
21972
21977
  description: "impd: the imp host daemon",
21973
21978
  type: "module",
21974
21979
  exports: {
21975
21980
  ".": "./src/index.ts",
21981
+ "./read-text": "./src/platform/process/read-text.ts",
21976
21982
  "./real-clock": "./src/platform/process/real-clock.ts",
21977
21983
  "./testing": "./testing/index.ts",
21978
21984
  "./testing/build-stub-clock": "./testing/platform/build-stub-clock.ts",
@@ -24140,6 +24146,12 @@ function writeRegularFile(path, text) {
24140
24146
  closeSync2(fd);
24141
24147
  }
24142
24148
  }
24149
+ function createZeroedFile(path, sizeBytes) {
24150
+ const fd = openRegularFile(path, constants.O_RDWR, 420);
24151
+ ftruncateSync(fd, 0);
24152
+ ftruncateSync(fd, sizeBytes);
24153
+ return fd;
24154
+ }
24143
24155
  function readRegularFile(path) {
24144
24156
  const fd = openSync2(path, constants.O_RDONLY | SAFE_FLAGS);
24145
24157
  try {
@@ -37525,6 +37537,7 @@ async function createImpdFirewall(config, deps, secretFiles, plan) {
37525
37537
  }
37526
37538
 
37527
37539
  // packages/daemon/src/create-impd-imps.ts
37540
+ import { readFileSync as readFileSync25 } from "fs";
37528
37541
  import { availableParallelism } from "os";
37529
37542
 
37530
37543
  // packages/daemon/src/host-net/net/tap-bytes.ts
@@ -41112,7 +41125,8 @@ function createImpContext(deps) {
41112
41125
  const records = {
41113
41126
  config: deps.config,
41114
41127
  db: deps.db,
41115
- identity: deps.identity
41128
+ identity: deps.identity,
41129
+ readHostLoad: deps.readHostLoad
41116
41130
  };
41117
41131
  const clock = {
41118
41132
  now,
@@ -42545,6 +42559,11 @@ function readDiskMib(path) {
42545
42559
  }
42546
42560
  }
42547
42561
 
42562
+ // packages/daemon/src/imps/imps/format-page-handler.ts
42563
+ function formatPageHandler(stats) {
42564
+ return stats === undefined ? "" : `; page handler faults=${String(stats.faults)} blocks=${String(stats.blocks)} serve=${String(stats.serveMs)}ms`;
42565
+ }
42566
+
42548
42567
  // packages/daemon/src/imps/imps/pick-huge-pages.ts
42549
42568
  function pickHugePages(isOn, imp) {
42550
42569
  return isOn && imp.maxMemoryMib <= imp.memoryMib && imp.memoryMib % 2 === 0 ? "2M" : "None";
@@ -42626,10 +42645,11 @@ function makeWakeImpVm(deps) {
42626
42645
  return startAfterFailedWake(imp, paths, wrong);
42627
42646
  }
42628
42647
  const wakeMs = Math.round(performance.now() - started);
42629
- getImpdLogger("imps").with({ imp: imp.name }).info("woke pid {pid} in {wakeMs}ms {timings}", {
42648
+ getImpdLogger("imps").with({ imp: imp.name }).info("woke pid {pid} in {wakeMs}ms {timings}{pageHandler}", {
42630
42649
  pid: String(woken.pid),
42631
42650
  wakeMs: String(wakeMs),
42632
- timings: formatTimings(woken.timings)
42651
+ timings: formatTimings(woken.timings),
42652
+ pageHandler: formatPageHandler(woken.pageHandler)
42633
42653
  });
42634
42654
  if (hugePages === "None") {
42635
42655
  writeHostPagesIdentity(imp, paths);
@@ -43204,10 +43224,11 @@ function probeSealedEntry(paths, path) {
43204
43224
  const entry = lstatSync3(path);
43205
43225
  const uffdSocket = join21(paths.runDir, UFFD_RUN_FILES.socket);
43206
43226
  const uffdPidFile = join21(paths.runDir, UFFD_RUN_FILES.pidFile);
43227
+ const uffdStatsFile = join21(paths.runDir, UFFD_RUN_FILES.statsFile);
43207
43228
  if (path === paths.apiSocket || path === paths.vsockSocket || path === uffdSocket) {
43208
43229
  return entry.isSocket();
43209
43230
  }
43210
- return (path === paths.logFile || path === paths.pidFile || path === uffdPidFile) && entry.isFile() && entry.uid === IMPD_USER.uid && entry.nlink === 1;
43231
+ return (path === paths.logFile || path === paths.pidFile || path === uffdPidFile || path === uffdStatsFile) && entry.isFile() && entry.uid === IMPD_USER.uid && entry.nlink === 1;
43211
43232
  }
43212
43233
  function setupImpdDir(directory) {
43213
43234
  setupRealDir(directory);
@@ -43252,6 +43273,16 @@ function readOwnerUid(path) {
43252
43273
 
43253
43274
  // packages/daemon/src/vm/vmm/uffd-handler.ts
43254
43275
  import { closeSync as closeSync10, existsSync as existsSync13, openSync as openSync8, rmSync as rmSync20 } from "fs";
43276
+
43277
+ // packages/daemon/src/vm/vmm/uffd-stats-layout.ts
43278
+ var UFFD_STATS_OFFSETS = {
43279
+ faults: 0,
43280
+ blocks: 8,
43281
+ serveNs: 16
43282
+ };
43283
+ var UFFD_STATS_BYTES = 24;
43284
+
43285
+ // packages/daemon/src/vm/vmm/uffd-handler.ts
43255
43286
  var MEM_FILE_FD = 3;
43256
43287
  var SOCKET_WAIT_MS2 = 3000;
43257
43288
  async function startUffdHandler(plan) {
@@ -43264,11 +43295,13 @@ async function startUffdHandler(plan) {
43264
43295
  ...plan.jail === null ? [] : ["--uid", String(plan.jail.uid), "--gid", String(plan.jail.gid)]
43265
43296
  ];
43266
43297
  const memFd = openSync8(plan.memFile, "r");
43298
+ const statsFd = createZeroedFile(paths.uffdStatsFile, UFFD_STATS_BYTES);
43267
43299
  const log = setupLogFile(paths.logFile);
43268
43300
  const child = Bun.spawn(buildSpawnArgv(command, plan.cgroup?.procsPath ?? null, null), {
43269
- stdio: ["ignore", log, log, memFd]
43301
+ stdio: ["ignore", log, log, memFd, statsFd]
43270
43302
  });
43271
43303
  closeSync10(memFd);
43304
+ closeSync10(statsFd);
43272
43305
  closeSync10(log);
43273
43306
  child.unref();
43274
43307
  writeRegularFile(paths.uffdPidFile, `${String(child.pid)}
@@ -43287,6 +43320,15 @@ function removeUffdFiles(paths) {
43287
43320
  rmSync20(paths.uffdSocket, { force: true });
43288
43321
  rmSync20(`${paths.uffdSocket}.new`, { force: true });
43289
43322
  rmSync20(paths.uffdPidFile, { force: true });
43323
+ rmSync20(paths.uffdStatsFile, { force: true });
43324
+ }
43325
+ function readUffdStats(paths, readFile) {
43326
+ const raw = readFile(paths.uffdStatsFile);
43327
+ return {
43328
+ faults: Number(raw.readBigUInt64LE(UFFD_STATS_OFFSETS.faults)),
43329
+ blocks: Number(raw.readBigUInt64LE(UFFD_STATS_OFFSETS.blocks)),
43330
+ serveMs: Math.round(Number(raw.readBigUInt64LE(UFFD_STATS_OFFSETS.serveNs)) / 1e6)
43331
+ };
43290
43332
  }
43291
43333
  function readHandlerState(paths, procRoot = "/proc") {
43292
43334
  if (!existsSync13(paths.uffdPidFile)) {
@@ -43497,6 +43539,22 @@ ${readLogTail(plan.paths.logFile, 5)}`, step.fault, error);
43497
43539
  }
43498
43540
  }
43499
43541
 
43542
+ // packages/daemon/src/imps/imps/format-host-stall.ts
43543
+ var STALL_FIGURES = [
43544
+ ["cpu", "cpuStallUs"],
43545
+ ["io", "ioStallUs"],
43546
+ ["memory", "memoryStallUs"],
43547
+ ["steal", "stealUs"]
43548
+ ];
43549
+ function formatHostStall(before, after) {
43550
+ const figures = STALL_FIGURES.flatMap(([name, field]) => {
43551
+ const startUs = before[field];
43552
+ const endUs = after[field];
43553
+ return startUs === null || endUs === null ? [] : [`${name}=${String(Math.round((endUs - startUs) / 1000))}ms`];
43554
+ });
43555
+ return figures.length === 0 ? "" : `; host stall ${figures.join(" ")}`;
43556
+ }
43557
+
43500
43558
  // packages/daemon/src/imps/imps/start-cold-vm.ts
43501
43559
  var CLAIM_SEED_BYTES = 64;
43502
43560
  async function startColdVm(context, start) {
@@ -43552,11 +43610,12 @@ async function startColdVm(context, start) {
43552
43610
  }
43553
43611
  });
43554
43612
  context.templates?.reportRestored(template);
43555
- getImpdLogger("imps").with({ imp: imp.name }).info("restored boot template {key} as pid {pid} {timings}{guestSteps}", {
43613
+ getImpdLogger("imps").with({ imp: imp.name }).info("restored boot template {key} as pid {pid} {timings}{guestSteps}{hostStall}", {
43556
43614
  key: template.key.slice(0, 12),
43557
43615
  pid: String(vm.pid),
43558
43616
  timings: formatTimings({ ...hostSteps, ...vm.timings }),
43559
- guestSteps: formatGuestSteps(vm.guestSteps)
43617
+ guestSteps: formatGuestSteps(vm.guestSteps),
43618
+ hostStall: formatHostStall(start.loadBefore, context.readHostLoad())
43560
43619
  });
43561
43620
  return vm;
43562
43621
  } catch (error) {
@@ -43589,10 +43648,11 @@ async function startColdVm(context, start) {
43589
43648
  isIdentityReset: imp.isIdentityResetPending,
43590
43649
  jail: context.findJailUser(imp)
43591
43650
  });
43592
- getImpdLogger("imps").with({ imp: imp.name }).info("booted pid {pid} {timings}{guestSteps}", {
43651
+ getImpdLogger("imps").with({ imp: imp.name }).info("booted pid {pid} {timings}{guestSteps}{hostStall}", {
43593
43652
  pid: String(vm.pid),
43594
43653
  timings: formatTimings({ ...hostSteps, ...vm.timings }),
43595
- guestSteps: formatGuestSteps(vm.guestSteps)
43654
+ guestSteps: formatGuestSteps(vm.guestSteps),
43655
+ hostStall: formatHostStall(start.loadBefore, context.readHostLoad())
43596
43656
  });
43597
43657
  return vm;
43598
43658
  }
@@ -43673,6 +43733,7 @@ function createImpVmOps(host) {
43673
43733
  hugePagesMib: hugePages === "2M" ? imp.memoryMib : 0
43674
43734
  });
43675
43735
  const setupStarted = performance.now();
43736
+ const loadBefore = context.readHostLoad();
43676
43737
  try {
43677
43738
  removeSnapshot(paths);
43678
43739
  await context.egress.requireImp(imp.id);
@@ -43690,6 +43751,7 @@ function createImpVmOps(host) {
43690
43751
  cgroup,
43691
43752
  hugePages,
43692
43753
  hostSteps,
43754
+ loadBefore,
43693
43755
  diskReady
43694
43756
  });
43695
43757
  startCounting(context, imp, vm.pid);
@@ -44394,6 +44456,56 @@ function createImpService(deps, createWatchdog) {
44394
44456
  };
44395
44457
  }
44396
44458
 
44459
+ // packages/daemon/src/platform/process/read-host-load.ts
44460
+ import { join as join22 } from "path";
44461
+
44462
+ // packages/daemon/src/platform/process/find-unexpected-read-code.ts
44463
+ var UNSUPPORTED_CODES = new Set(["ENOENT", "EOPNOTSUPP"]);
44464
+ function findUnexpectedReadCode(error) {
44465
+ const code = error instanceof Error && "code" in error ? String(error.code) : "unknown";
44466
+ return UNSUPPORTED_CODES.has(code) ? null : code;
44467
+ }
44468
+
44469
+ // packages/daemon/src/platform/process/read-host-load.ts
44470
+ function readHostLoad(sources) {
44471
+ const readProc = (...names) => readProcFile(sources, join22(sources.procRoot, ...names));
44472
+ return {
44473
+ cpuStallUs: parsePressureTotal(readProc("pressure", "cpu")),
44474
+ ioStallUs: parsePressureTotal(readProc("pressure", "io")),
44475
+ memoryStallUs: parsePressureTotal(readProc("pressure", "memory")),
44476
+ stealUs: parseStealUs(readProc("stat"))
44477
+ };
44478
+ }
44479
+ function readProcFile(sources, path) {
44480
+ try {
44481
+ return sources.readFile(path);
44482
+ } catch (error) {
44483
+ const code = findUnexpectedReadCode(error);
44484
+ if (code !== null) {
44485
+ sources.logger.warning("cannot read {path} for the host stall: {code}", { path, code });
44486
+ }
44487
+ return null;
44488
+ }
44489
+ }
44490
+ function parsePressureTotal(pressure) {
44491
+ const total = pressure === null ? undefined : /^some .*total=(?<us>\d+)$/mv.exec(pressure);
44492
+ return total?.groups?.["us"] === undefined ? null : Number(total.groups["us"]);
44493
+ }
44494
+ var STEAL_FIELD = 8;
44495
+ var US_PER_TICK = 1e4;
44496
+ function parseStealUs(stat) {
44497
+ const fields = stat?.split(`
44498
+ `).find((line) => line.startsWith("cpu "))?.split(/\s+/v);
44499
+ const steal = fields?.[STEAL_FIELD];
44500
+ return steal === undefined ? null : Number(steal) * US_PER_TICK;
44501
+ }
44502
+
44503
+ // packages/daemon/src/platform/process/read-text.ts
44504
+ import { readFileSync as readFileSync22 } from "fs";
44505
+ function readText(path) {
44506
+ return readFileSync22(path, "utf8");
44507
+ }
44508
+
44397
44509
  // packages/daemon/src/platform/telemetry/imp-telemetry.ts
44398
44510
  import { ROOT_CONTEXT, metrics as metrics2, trace } from "@opentelemetry/api";
44399
44511
  var SPAN_NAMES = {
@@ -44770,12 +44882,12 @@ function createMemoryController(deps) {
44770
44882
  import {
44771
44883
  existsSync as existsSync14,
44772
44884
  mkdirSync as mkdirSync16,
44773
- readFileSync as readFileSync22,
44885
+ readFileSync as readFileSync23,
44774
44886
  readdirSync as readdirSync8,
44775
44887
  rmdirSync as rmdirSync2,
44776
44888
  writeFileSync as writeFileSync5
44777
44889
  } from "fs";
44778
- import { join as join22 } from "path";
44890
+ import { join as join23 } from "path";
44779
44891
  var PERIOD_US = 1e5;
44780
44892
  var MEMORY_MIN_OVERHEAD_MIB = 256;
44781
44893
  var MEMORY_OVERHEAD_DIVISOR = 8;
@@ -44803,18 +44915,18 @@ function parseOomKills(text) {
44803
44915
  return match?.groups === undefined ? null : Number(match.groups["count"]);
44804
44916
  }
44805
44917
  function createCpuCgroups(options) {
44806
- const imps = join22(options.root, "imps");
44918
+ const imps = join23(options.root, "imps");
44807
44919
  const procRoot = options.procRoot ?? "/proc";
44808
44920
  const rmdir = options.rmdir ?? rmdirSync2;
44809
44921
  const sleep = options.sleep ?? Bun.sleep;
44810
44922
  const isEnforced = probeControllerDelegated(imps, "cpu");
44811
44923
  const isMemoryEnforced = isEnforced && probeControllerDelegated(imps, "memory");
44812
- const getDir = (impId) => join22(imps, impId);
44924
+ const getDir = (impId) => join23(imps, impId);
44813
44925
  const guestMibs = new Map;
44814
44926
  const oomBaselines = new Map;
44815
44927
  const readOomKills = (impId) => {
44816
44928
  try {
44817
- const events = readFileSync22(join22(getDir(impId), "memory.events"), "utf8");
44929
+ const events = readFileSync23(join23(getDir(impId), "memory.events"), "utf8");
44818
44930
  return parseOomKills(events);
44819
44931
  } catch {
44820
44932
  return null;
@@ -44824,8 +44936,8 @@ function createCpuCgroups(options) {
44824
44936
  oomBaselines.set(impId, readOomKills(impId) ?? 0);
44825
44937
  };
44826
44938
  const writeSettings = (impId, cpu, limit) => {
44827
- writeFileSync5(join22(getDir(impId), "cpu.weight"), String(cpu.weight));
44828
- writeFileSync5(join22(getDir(impId), "cpu.max"), formatCpuMax(limit));
44939
+ writeFileSync5(join23(getDir(impId), "cpu.weight"), String(cpu.weight));
44940
+ writeFileSync5(join23(getDir(impId), "cpu.max"), formatCpuMax(limit));
44829
44941
  };
44830
44942
  const writeMemory = (impId) => {
44831
44943
  const guestMib = guestMibs.get(impId);
@@ -44833,10 +44945,10 @@ function createCpuCgroups(options) {
44833
44945
  return;
44834
44946
  }
44835
44947
  const directory = getDir(impId);
44836
- writeFileSync5(join22(directory, "memory.max"), buildMemoryMax(guestMib));
44837
- writeFileSync5(join22(directory, "memory.high"), "max");
44838
- writeFileSync5(join22(directory, "memory.swap.max"), "0");
44839
- writeFileSync5(join22(directory, "memory.oom.group"), "1");
44948
+ writeFileSync5(join23(directory, "memory.max"), buildMemoryMax(guestMib));
44949
+ writeFileSync5(join23(directory, "memory.high"), "max");
44950
+ writeFileSync5(join23(directory, "memory.swap.max"), "0");
44951
+ writeFileSync5(join23(directory, "memory.oom.group"), "1");
44840
44952
  };
44841
44953
  const setup = (impId, cpu, memoryMib) => {
44842
44954
  if (!isEnforced) {
@@ -44858,7 +44970,7 @@ function createCpuCgroups(options) {
44858
44970
  return null;
44859
44971
  }
44860
44972
  return {
44861
- procsPath: join22(getDir(impId), "cgroup.procs"),
44973
+ procsPath: join23(getDir(impId), "cgroup.procs"),
44862
44974
  liftLimit: () => {
44863
44975
  tryWrite(impId, "lift the limit", () => {
44864
44976
  writeSettings(impId, cpu, null);
@@ -44942,7 +45054,7 @@ function createCpuCgroups(options) {
44942
45054
  kill: (impId) => {
44943
45055
  if (isEnforced && existsSync14(getDir(impId))) {
44944
45056
  tryWrite(impId, "kill", () => {
44945
- writeFileSync5(join22(getDir(impId), "cgroup.kill"), "1");
45057
+ writeFileSync5(join23(getDir(impId), "cgroup.kill"), "1");
44946
45058
  });
44947
45059
  }
44948
45060
  },
@@ -44953,7 +45065,7 @@ function createCpuCgroups(options) {
44953
45065
  },
44954
45066
  readCpuStat: (impId) => {
44955
45067
  try {
44956
- const stat = readFileSync22(join22(getDir(impId), "cpu.stat"), "utf8");
45068
+ const stat = readFileSync23(join23(getDir(impId), "cpu.stat"), "utf8");
44957
45069
  return parseCpuStat(stat);
44958
45070
  } catch {
44959
45071
  return null;
@@ -44963,7 +45075,7 @@ function createCpuCgroups(options) {
44963
45075
  }
44964
45076
  function probeControllerDelegated(imps, controller) {
44965
45077
  try {
44966
- const delegated = readFileSync22(join22(imps, "cgroup.subtree_control"), "utf8");
45078
+ const delegated = readFileSync23(join23(imps, "cgroup.subtree_control"), "utf8");
44967
45079
  return delegated.split(/\s+/u).includes(controller);
44968
45080
  } catch {
44969
45081
  return false;
@@ -44996,13 +45108,13 @@ function probeUffdDevice(path = "/dev/userfaultfd") {
44996
45108
  }
44997
45109
 
44998
45110
  // packages/daemon/src/vm/vmm/read-huge-page-pool.ts
44999
- import { readFileSync as readFileSync23 } from "fs";
45000
- import { join as join23 } from "path";
45111
+ import { readFileSync as readFileSync24 } from "fs";
45112
+ import { join as join24 } from "path";
45001
45113
  var HUGE_PAGE_MIB = 2;
45002
45114
  function readHugePagePool(sysRoot = "/sys") {
45003
- const directory = join23(sysRoot, "kernel", "mm", "hugepages", "hugepages-2048kB");
45115
+ const directory = join24(sysRoot, "kernel", "mm", "hugepages", "hugepages-2048kB");
45004
45116
  try {
45005
- const readCount = (name) => Number(readFileSync23(join23(directory, name), "utf8").trim());
45117
+ const readCount = (name) => Number(readFileSync24(join24(directory, name), "utf8").trim());
45006
45118
  const total = readCount("nr_hugepages");
45007
45119
  const free = readCount("free_hugepages") - readCount("resv_hugepages");
45008
45120
  if (!Number.isSafeInteger(total) || !Number.isSafeInteger(free)) {
@@ -45088,11 +45200,12 @@ var UFFD_WATCH_INTERVAL_MS = 100;
45088
45200
  var WAKE_AGENT_DEADLINE_MS = 1e4;
45089
45201
  var GUEST_MEMORY_TIMEOUTS = { requestMs: 1000, snapshotMs: 1000 };
45090
45202
  var UPTIME_PING_TIMEOUT_MS = 250;
45091
- function createVmRunner(jails, options = {}) {
45203
+ function createVmRunner(jails, options) {
45092
45204
  const mergeWrapper = options.mergeWrapper ?? null;
45093
45205
  const sendUptimePing = options.sendUptimePing ?? sendPing;
45094
45206
  const procRoot = options.procRoot ?? "/proc";
45095
45207
  const createClient = options.createClient ?? createFirecrackerClient;
45208
+ const readFile = options.readFile;
45096
45209
  const uffdHandlerBin = options.uffdHandlerBin ?? null;
45097
45210
  const uffdWatch = createUffdWatch({
45098
45211
  probeVmAlive: (pid, paths) => probeProcessAlive(pid, paths.apiSocket, procRoot),
@@ -45323,7 +45436,8 @@ ${readLogTail(plan.paths.logFile)}`, {
45323
45436
  firecrackerVersion,
45324
45437
  agentVersion: ping.version,
45325
45438
  timings: timer.marks,
45326
- bootId: ping.bootId
45439
+ bootId: ping.bootId,
45440
+ ...isUffd && { pageHandler: readUffdStats(plan.paths, readFile) }
45327
45441
  };
45328
45442
  } catch (error) {
45329
45443
  const reason = explainUffdFailure(plan.paths, procRoot, getErrorMessage(error));
@@ -45422,7 +45536,8 @@ function createImpdImps(config, deps, parts) {
45422
45536
  killCgroup: cgroups.kill
45423
45537
  }), {
45424
45538
  mergeWrapper: config.ksm?.execBin ?? null,
45425
- uffdHandlerBin: config.hugePages?.handlerBin ?? null
45539
+ uffdHandlerBin: config.hugePages?.handlerBin ?? null,
45540
+ readFile: readFileSync25
45426
45541
  });
45427
45542
  const {
45428
45543
  readVmRam,
@@ -45581,6 +45696,7 @@ function resolveImpBoundaries(boundaries) {
45581
45696
  kernelOops: boundaries.kernelOops ?? createKernelOopsWatch(),
45582
45697
  readThreadIds: boundaries.readThreadIds ?? ((pid) => readThreadIds(pid)),
45583
45698
  readNetBytes: boundaries.readNetBytes ?? ((tap) => readGuestNetBytes(tap)),
45699
+ readHostLoad: boundaries.readHostLoad ?? (() => readHostLoad({ procRoot: "/proc", readFile: readText, logger: getImpdLogger("imps") })),
45584
45700
  ...boundaries.openTap !== undefined && { openTap: boundaries.openTap },
45585
45701
  ...boundaries.now !== undefined && { now: boundaries.now }
45586
45702
  };
@@ -45595,7 +45711,7 @@ function makeStandInVmRam(readRam) {
45595
45711
 
45596
45712
  // packages/daemon/src/imp-ops/moves/move-receiver.ts
45597
45713
  import { existsSync as existsSync16, rmSync as rmSync24 } from "fs";
45598
- import { join as join25 } from "path";
45714
+ import { join as join26 } from "path";
45599
45715
 
45600
45716
  // packages/daemon/src/platform/db/probe-slot-free.ts
45601
45717
  async function probeSlotFree(db, slot, now) {
@@ -45920,7 +46036,7 @@ function readReceipt(receipt, secret) {
45920
46036
  // packages/daemon/src/imp-ops/moves/read-move-stream.ts
45921
46037
  import { mkdirSync as mkdirSync19, rmSync as rmSync23 } from "fs";
45922
46038
  import { open as open7 } from "fs/promises";
45923
- import { join as join24 } from "path";
46039
+ import { join as join25 } from "path";
45924
46040
  import invariant5 from "tiny-invariant";
45925
46041
 
45926
46042
  // packages/daemon/src/imp-ops/moves/build-received-digest.ts
@@ -46545,7 +46661,7 @@ async function readMoveStream(deps, options) {
46545
46661
  const count = createByteCounter(row.bytes);
46546
46662
  const files = [];
46547
46663
  mkdirSync19(options.tempDir, { recursive: true, mode: 448 });
46548
- const temp = join24(options.tempDir, `${row.id}.part`);
46664
+ const temp = join25(options.tempDir, `${row.id}.part`);
46549
46665
  const writeDisk = async (impId) => {
46550
46666
  if (header.streams !== null) {
46551
46667
  await writeMoveStreams(deps, {
@@ -46760,7 +46876,7 @@ async function requireMoveTicket(db, request) {
46760
46876
  // packages/daemon/src/imp-ops/moves/move-receiver.ts
46761
46877
  var STREAM_WINDOW_MS = 10 * 60 * 1000;
46762
46878
  function createMoveReceiver(deps) {
46763
- const tempDir = join25(deps.dataDir, "moves");
46879
+ const tempDir = join26(deps.dataDir, "moves");
46764
46880
  const sessions = new Map;
46765
46881
  const writeTicketRow = async (name, bytes, fields, write = (row) => writeMoveTicket(deps.db, row)) => {
46766
46882
  const created = mintOpaqueToken(MOVE_TICKET_PREFIX);
@@ -47935,12 +48051,12 @@ function toPeerError2(procedure, error) {
47935
48051
  // packages/daemon/src/vm/storage/write-image-files.ts
47936
48052
  import { writeFileSync as writeFileSync6 } from "fs";
47937
48053
  import { copyFile } from "fs/promises";
47938
- import { join as join26 } from "path";
48054
+ import { join as join27 } from "path";
47939
48055
  async function writeImageFiles(files, directory) {
47940
- const rootfs = join26(directory, "rootfs.ext4");
48056
+ const rootfs = join27(directory, "rootfs.ext4");
47941
48057
  writeFileSync6(rootfs, "");
47942
48058
  await writeChangedBlocks(files.rootfsPath, rootfs);
47943
- await copyFile(files.configPath, join26(directory, "config.json"));
48059
+ await copyFile(files.configPath, join27(directory, "config.json"));
47944
48060
  }
47945
48061
 
47946
48062
  // packages/daemon/src/create-impd-moves.ts
@@ -47980,7 +48096,7 @@ function createImpdMoves(config, deps, parts, hooks) {
47980
48096
 
47981
48097
  // packages/daemon/src/imps/images/template-service.ts
47982
48098
  import { copyFileSync as copyFileSync3, existsSync as existsSync17, statSync as statSync11, writeFileSync as writeFileSync7 } from "fs";
47983
- import { join as join27 } from "path";
48099
+ import { join as join28 } from "path";
47984
48100
 
47985
48101
  // packages/daemon/src/imps/images/read-held-image.ts
47986
48102
  async function readHeldImage(db, name, at) {
@@ -48268,7 +48384,7 @@ function createTemplateService(deps) {
48268
48384
  });
48269
48385
  const writeConfig = async (imageId, directory) => {
48270
48386
  const image = await readImageById(deps.db, imageId);
48271
- const target = join27(directory, "config.json");
48387
+ const target = join28(directory, "config.json");
48272
48388
  const config = image === undefined ? undefined : buildImagePaths(deps.config.dataDir, image.digest).config;
48273
48389
  if (config !== undefined && existsSync17(config)) {
48274
48390
  copyFileSync3(config, target);
@@ -48656,7 +48772,7 @@ function createImpdServices(config, deps, parts) {
48656
48772
 
48657
48773
  // packages/daemon/src/imps/images/build/create-image-builds.ts
48658
48774
  import { existsSync as existsSync19, mkdirSync as mkdirSync20, rmSync as rmSync25, statSync as statSync12 } from "fs";
48659
- import { join as join29, posix as posix3 } from "path";
48775
+ import { join as join30, posix as posix3 } from "path";
48660
48776
 
48661
48777
  // packages/local-tar/src/extract-local.ts
48662
48778
  import tar from "tar-stream";
@@ -48664,7 +48780,7 @@ import * as z83 from "zod";
48664
48780
  // packages/local-tar/src/pack-build-context.ts
48665
48781
  import { existsSync as existsSync18 } from "fs";
48666
48782
  import { lstat, readFile as readFile4, readdir } from "fs/promises";
48667
- import { join as join28, posix as posix2 } from "path";
48783
+ import { join as join29, posix as posix2 } from "path";
48668
48784
  import ignore from "@balena/dockerignore";
48669
48785
 
48670
48786
  // packages/local-tar/src/write-build-context.ts
@@ -48948,7 +49064,7 @@ class MissingDockerfileError extends Error {
48948
49064
  name = "MissingDockerfileError";
48949
49065
  }
48950
49066
  function listContextEntries(root, dockerfile) {
48951
- const found = listDockerfileCandidates(posix2.normalize(dockerfile)).find((candidate) => existsSync18(join28(root, candidate)));
49067
+ const found = listDockerfileCandidates(posix2.normalize(dockerfile)).find((candidate) => existsSync18(join29(root, candidate)));
48952
49068
  if (found === undefined) {
48953
49069
  return Promise.reject(new MissingDockerfileError(`there is no ${dockerfile} in ${root}`));
48954
49070
  }
@@ -48960,8 +49076,8 @@ var ENTRY_KINDS = [
48960
49076
  ["file", "isFile"]
48961
49077
  ];
48962
49078
  async function listEntries(root, dockerfile) {
48963
- const ignoreName = existsSync18(join28(root, `${dockerfile}.dockerignore`)) ? `${dockerfile}.dockerignore` : ".dockerignore";
48964
- const patterns = existsSync18(join28(root, ignoreName)) ? await readFile4(join28(root, ignoreName), "utf8") : "";
49079
+ const ignoreName = existsSync18(join29(root, `${dockerfile}.dockerignore`)) ? `${dockerfile}.dockerignore` : ".dockerignore";
49080
+ const patterns = existsSync18(join29(root, ignoreName)) ? await readFile4(join29(root, ignoreName), "utf8") : "";
48965
49081
  const matcher = ignore().add(patterns);
48966
49082
  const hasExceptions = patterns.split(`
48967
49083
  `).some((line) => line.trim().startsWith("!"));
@@ -48971,7 +49087,7 @@ async function listEntries(root, dockerfile) {
48971
49087
  const entries = [];
48972
49088
  const children = await readdir(directory);
48973
49089
  for (const child of children.toSorted()) {
48974
- const path = join28(directory, child);
49090
+ const path = join29(directory, child);
48975
49091
  const name = prefix === "" ? child : `${prefix}/${child}`;
48976
49092
  const stats = await lstat(path);
48977
49093
  const ignored = matcher.ignores(name) && name !== dockerfileName;
@@ -50026,7 +50142,7 @@ function planRootfsOverhead(treeBytes) {
50026
50142
  }
50027
50143
 
50028
50144
  // packages/daemon/src/imps/images/rootfs/unpack-export.ts
50029
- import { readFileSync as readFileSync24 } from "fs";
50145
+ import { readFileSync as readFileSync26 } from "fs";
50030
50146
  var CAP_SETFCAP_BIT = 31n;
50031
50147
  var SETFCAP_HELP = "imp-host needs CAP_SETFCAP (docs/architecture/host.md#privileges)";
50032
50148
  var UNPACK_TAR_ARGS = [
@@ -50068,7 +50184,7 @@ function findXattrFailure(stderr) {
50068
50184
  });
50069
50185
  return failures.find((failure) => failure.missingSetfcap) ?? failures[0] ?? null;
50070
50186
  }
50071
- function readSetfcapWarning(status = readFileSync24("/proc/self/status", "utf8")) {
50187
+ function readSetfcapWarning(status = readFileSync26("/proc/self/status", "utf8")) {
50072
50188
  const effective = /^CapEff:\s*(?<mask>[0-9a-f]+)$/mu.exec(status)?.groups?.["mask"] ?? "0";
50073
50189
  if (BigInt(`0x${effective}`) >> CAP_SETFCAP_BIT & 1n) {
50074
50190
  return null;
@@ -50492,7 +50608,7 @@ function createImageBuilds(deps, writer) {
50492
50608
  });
50493
50609
  }
50494
50610
  const uploadsDir = buildUploadsDir(deps.config.dataDir);
50495
- const tarPath = join29(uploadsDir, `${Bun.randomUUIDv7()}.tar`);
50611
+ const tarPath = join30(uploadsDir, `${Bun.randomUUIDv7()}.tar`);
50496
50612
  mkdirSync20(uploadsDir, { recursive: true, mode: 448 });
50497
50613
  return deps.diskBudget.withRoom(tarBytes, async () => {
50498
50614
  try {
@@ -50649,7 +50765,7 @@ function buildImageRuntimeConfig(ociConfig) {
50649
50765
 
50650
50766
  // packages/daemon/src/imps/images/rootfs/create-image-writer.ts
50651
50767
  import { existsSync as existsSync20, mkdirSync as mkdirSync22, rmSync as rmSync27, statSync as statSync13, writeFileSync as writeFileSync8 } from "fs";
50652
- import { join as join31 } from "path";
50768
+ import { join as join32 } from "path";
50653
50769
 
50654
50770
  // packages/daemon/src/imps/images/rootfs/read-oci-config.ts
50655
50771
  import * as z88 from "zod";
@@ -50669,13 +50785,13 @@ async function readOciConfig(ref, signal, run) {
50669
50785
 
50670
50786
  // packages/daemon/src/imps/images/rootfs/write-image-config.ts
50671
50787
  import { closeSync as closeSync11, constants as constants6, lstatSync as lstatSync5, mkdirSync as mkdirSync21, openSync as openSync9, rmSync as rmSync26, writeSync as writeSync3 } from "fs";
50672
- import { join as join30 } from "path";
50788
+ import { join as join31 } from "path";
50673
50789
  function writeImageConfig(root, contents) {
50674
- const etc = join30(root, "etc");
50675
- const directory = join30(etc, "imp");
50790
+ const etc = join31(root, "etc");
50791
+ const directory = join31(etc, "imp");
50676
50792
  createDirectory(etc, "/etc");
50677
50793
  createDirectory(directory, "/etc/imp");
50678
- const file = join30(directory, "image.json");
50794
+ const file = join31(directory, "image.json");
50679
50795
  rmSync26(file, { recursive: true, force: true });
50680
50796
  const fd = openSync9(file, constants6.O_WRONLY | constants6.O_CREAT | constants6.O_EXCL | constants6.O_NOFOLLOW, 420);
50681
50797
  try {
@@ -50722,8 +50838,8 @@ function createImageWriter(deps) {
50722
50838
  const guestRootfsLock = buildKeyedMutex();
50723
50839
  const makeWorkDir = () => {
50724
50840
  const images = buildImagesDir(deps.config.dataDir);
50725
- const work = join31(images, `.build-${Bun.randomUUIDv7()}`);
50726
- const root = join31(work, "root");
50841
+ const work = join32(images, `.build-${Bun.randomUUIDv7()}`);
50842
+ const root = join32(work, "root");
50727
50843
  mkdirSync22(images, { recursive: true });
50728
50844
  mkdirSync22(work, { mode: 448 });
50729
50845
  mkdirSync22(root, { mode: 493 });
@@ -50734,7 +50850,7 @@ function createImageWriter(deps) {
50734
50850
  const usage = await readTreeUsage(root);
50735
50851
  const plan = planRootfs(usage);
50736
50852
  await deps.storage.createImage(digest, async (directory) => {
50737
- const image = join31(directory, "rootfs.ext4");
50853
+ const image = join32(directory, "rootfs.ext4");
50738
50854
  await runChecked(["truncate", "-s", String(plan.bytes), image]);
50739
50855
  await runChecked([
50740
50856
  "mkfs.ext4",
@@ -50747,7 +50863,7 @@ function createImageWriter(deps) {
50747
50863
  root,
50748
50864
  image
50749
50865
  ]);
50750
- writeFileSync8(join31(directory, "config.json"), JSON.stringify(ociConfig ?? {}, null, 2));
50866
+ writeFileSync8(join32(directory, "config.json"), JSON.stringify(ociConfig ?? {}, null, 2));
50751
50867
  });
50752
50868
  return readDiskUsage(buildImagePaths(deps.config.dataDir, digest).rootfs);
50753
50869
  };
@@ -51298,7 +51414,7 @@ async function runStreamed(argv, onStdout, signal) {
51298
51414
 
51299
51415
  // packages/daemon/src/vm/storage/count-tree-bytes.ts
51300
51416
  import { lstat as lstat3, readdir as readdir3 } from "fs/promises";
51301
- import { join as join32 } from "path";
51417
+ import { join as join33 } from "path";
51302
51418
  async function countTreeBytes(root, deps = {}) {
51303
51419
  const readDir = deps.readDir ?? readDirEntries;
51304
51420
  const inodes = new Map;
@@ -51307,11 +51423,11 @@ async function countTreeBytes(root, deps = {}) {
51307
51423
  const entries = await readEntries2(readDir, directory);
51308
51424
  for (const entry of entries) {
51309
51425
  if (entry.isDirectory()) {
51310
- dirs.push(join32(directory, entry.name));
51426
+ dirs.push(join33(directory, entry.name));
51311
51427
  }
51312
51428
  }
51313
51429
  const files = entries.filter((entry) => entry.isFile());
51314
- const stats = await Promise.all(files.map((entry) => readFileStats(join32(directory, entry.name))));
51430
+ const stats = await Promise.all(files.map((entry) => readFileStats(join33(directory, entry.name))));
51315
51431
  for (const stat of stats) {
51316
51432
  if (stat !== undefined) {
51317
51433
  inodes.set(`${String(stat.dev)}:${String(stat.ino)}`, Math.max(0, stat.blocks - 1) * 512);
@@ -51554,12 +51670,12 @@ function createTailnetAccess(config, deps, readStatus) {
51554
51670
  }
51555
51671
 
51556
51672
  // packages/daemon/src/identity/token.ts
51557
- import { existsSync as existsSync21, readFileSync as readFileSync25, writeFileSync as writeFileSync9 } from "fs";
51558
- import { join as join33 } from "path";
51673
+ import { existsSync as existsSync21, readFileSync as readFileSync27, writeFileSync as writeFileSync9 } from "fs";
51674
+ import { join as join34 } from "path";
51559
51675
  function loadOrCreateToken(dataDir) {
51560
- const path = join33(dataDir, "token");
51676
+ const path = join34(dataDir, "token");
51561
51677
  if (existsSync21(path)) {
51562
- return readFileSync25(path, "utf8").trim();
51678
+ return readFileSync27(path, "utf8").trim();
51563
51679
  }
51564
51680
  const token = mintSecret();
51565
51681
  writeFileSync9(path, `${token}
@@ -51681,13 +51797,13 @@ import { basename as basename4 } from "path";
51681
51797
 
51682
51798
  // packages/daemon/src/vm/storage/remove-unused-system-drives.ts
51683
51799
  import { readdirSync as readdirSync9, rmSync as rmSync28 } from "fs";
51684
- import { join as join34 } from "path";
51800
+ import { join as join35 } from "path";
51685
51801
  function removeUnusedSystemDrives(dataDir, keep) {
51686
51802
  const directory = buildSystemDrivesDir(dataDir);
51687
51803
  const removed = [];
51688
51804
  for (const name of readNames(directory)) {
51689
51805
  if (!keep.has(name)) {
51690
- rmSync28(join34(directory, name), { force: true });
51806
+ rmSync28(join35(directory, name), { force: true });
51691
51807
  removed.push(name);
51692
51808
  }
51693
51809
  }
@@ -52896,13 +53012,13 @@ function createPublicRecordsLink() {
52896
53012
 
52897
53013
  // packages/daemon/src/network/tailnet-names/host-id.ts
52898
53014
  import { randomBytes as randomBytes11 } from "crypto";
52899
- import { existsSync as existsSync22, mkdirSync as mkdirSync23, readFileSync as readFileSync26, writeFileSync as writeFileSync10 } from "fs";
52900
- import { join as join35 } from "path";
53015
+ import { existsSync as existsSync22, mkdirSync as mkdirSync23, readFileSync as readFileSync28, writeFileSync as writeFileSync10 } from "fs";
53016
+ import { join as join36 } from "path";
52901
53017
  function loadOrCreateHostId(dataDir) {
52902
- const directory = join35(dataDir, "tailnet-names");
52903
- const path = join35(directory, "host-id");
53018
+ const directory = join36(dataDir, "tailnet-names");
53019
+ const path = join36(directory, "host-id");
52904
53020
  if (existsSync22(path)) {
52905
- return readFileSync26(path, "utf8").trim();
53021
+ return readFileSync28(path, "utf8").trim();
52906
53022
  }
52907
53023
  mkdirSync23(directory, { recursive: true });
52908
53024
  const id = randomBytes11(16).toString("hex");
@@ -52912,7 +53028,7 @@ function loadOrCreateHostId(dataDir) {
52912
53028
  }
52913
53029
 
52914
53030
  // packages/daemon/src/network/tailnet-names/oauth-credential.ts
52915
- import { readFileSync as readFileSync27, statSync as statSync14 } from "fs";
53031
+ import { readFileSync as readFileSync29, statSync as statSync14 } from "fs";
52916
53032
  import * as z92 from "zod";
52917
53033
  var CredentialSchema = z92.object({ clientId: z92.string().min(1), clientSecret: z92.string().min(1) });
52918
53034
  function readOAuthCredential(path) {
@@ -52928,7 +53044,7 @@ function readOAuthCredential(path) {
52928
53044
  }
52929
53045
  function readJson(path) {
52930
53046
  try {
52931
- return JSON.parse(readFileSync27(path, "utf8"));
53047
+ return JSON.parse(readFileSync29(path, "utf8"));
52932
53048
  } catch {
52933
53049
  return null;
52934
53050
  }
@@ -53325,7 +53441,7 @@ async function startOtlpExport(env, version) {
53325
53441
  }
53326
53442
 
53327
53443
  // packages/daemon/src/network/https/wire-https-service.ts
53328
- import { readFileSync as readFileSync29 } from "fs";
53444
+ import { readFileSync as readFileSync31 } from "fs";
53329
53445
 
53330
53446
  // packages/daemon/src/platform/db/exposure.ts
53331
53447
  async function readPublicImp(db, name) {
@@ -53520,8 +53636,8 @@ function formatAcmeError(error) {
53520
53636
  }
53521
53637
 
53522
53638
  // packages/daemon/src/network/https/acme/cert-store.ts
53523
- import { existsSync as existsSync23, mkdirSync as mkdirSync24, readFileSync as readFileSync28, rmSync as rmSync29 } from "fs";
53524
- import { join as join36 } from "path";
53639
+ import { existsSync as existsSync23, mkdirSync as mkdirSync24, readFileSync as readFileSync30, rmSync as rmSync29 } from "fs";
53640
+ import { join as join37 } from "path";
53525
53641
  import * as z95 from "zod";
53526
53642
  var AttemptStateSchema = z95.object({
53527
53643
  failures: z95.int().nonnegative(),
@@ -53532,11 +53648,11 @@ var AccountSchema = z95.object({ directoryUrl: z95.string(), url: z95.string(),
53532
53648
  var LegacyAccountSchema = z95.object({ directoryUrl: z95.string(), url: z95.string() });
53533
53649
  var NO_ATTEMPTS = { failures: 0, lastAttemptAt: null, lastError: null };
53534
53650
  function createCertStore(dataDir) {
53535
- const directory = join36(dataDir, "tls");
53536
- const certificatePath = join36(directory, "certificate.pem");
53537
- const attemptsPath = join36(directory, "attempts.json");
53538
- const accountPath = join36(directory, "account.json");
53539
- const legacyKeyPath = join36(directory, "account.key");
53651
+ const directory = join37(dataDir, "tls");
53652
+ const certificatePath = join37(directory, "certificate.pem");
53653
+ const attemptsPath = join37(directory, "attempts.json");
53654
+ const accountPath = join37(directory, "account.json");
53655
+ const legacyKeyPath = join37(directory, "account.key");
53540
53656
  const warned = { account: false };
53541
53657
  const write = (path, content) => {
53542
53658
  mkdirSync24(directory, { recursive: true, mode: 448 });
@@ -53602,7 +53718,7 @@ ${certificate.chainPem.trimEnd()}
53602
53718
  };
53603
53719
  }
53604
53720
  function readIfExists(path) {
53605
- return existsSync23(path) ? readFileSync28(path, "utf8") : null;
53721
+ return existsSync23(path) ? readFileSync30(path, "utf8") : null;
53606
53722
  }
53607
53723
  function parseJson(text) {
53608
53724
  try {
@@ -54408,7 +54524,7 @@ function wireHttpsService(options) {
54408
54524
  const issue = createAcmeIssuer({
54409
54525
  directoryUrl: config.acmeDirectory,
54410
54526
  email: config.acmeEmail,
54411
- caPem: config.acmeCaFile === null ? null : readFileSync29(config.acmeCaFile, "utf8"),
54527
+ caPem: config.acmeCaFile === null ? null : readFileSync31(config.acmeCaFile, "utf8"),
54412
54528
  store,
54413
54529
  dns
54414
54530
  });
@@ -54995,17 +55111,17 @@ function buildTooMany() {
54995
55111
 
54996
55112
  // packages/daemon/src/surface/ssh/host-key.ts
54997
55113
  var import_ssh22 = __toESM(require_lib2(), 1);
54998
- import { existsSync as existsSync24, mkdirSync as mkdirSync25, readFileSync as readFileSync30, writeFileSync as writeFileSync11 } from "fs";
54999
- import { join as join37 } from "path";
55114
+ import { existsSync as existsSync24, mkdirSync as mkdirSync25, readFileSync as readFileSync32, writeFileSync as writeFileSync11 } from "fs";
55115
+ import { join as join38 } from "path";
55000
55116
  function setupSshDir(dataDir) {
55001
- const directory = join37(dataDir, "ssh");
55117
+ const directory = join38(dataDir, "ssh");
55002
55118
  mkdirSync25(directory, { recursive: true, mode: 448 });
55003
55119
  return directory;
55004
55120
  }
55005
55121
  function loadOrCreateHostKey(sshDir) {
55006
- const path = join37(sshDir, "host_key");
55122
+ const path = join38(sshDir, "host_key");
55007
55123
  if (existsSync24(path)) {
55008
- return readFileSync30(path, "utf8");
55124
+ return readFileSync32(path, "utf8");
55009
55125
  }
55010
55126
  const pair = generateEd25519Key();
55011
55127
  writeFileSync11(path, pair.private, { mode: 384, flag: "wx" });
@@ -56170,8 +56286,8 @@ async function stopImpd(parts, options) {
56170
56286
  }
56171
56287
 
56172
56288
  // packages/daemon/src/vm/storage/create-storage-backend.ts
56173
- import { existsSync as existsSync31, readFileSync as readFileSync34, readdirSync as readdirSync14, writeFileSync as writeFileSync14 } from "fs";
56174
- import { join as join46 } from "path";
56289
+ import { existsSync as existsSync31, readFileSync as readFileSync36, readdirSync as readdirSync14, writeFileSync as writeFileSync14 } from "fs";
56290
+ import { join as join47 } from "path";
56175
56291
 
56176
56292
  // packages/daemon/src/vm/storage/xfs-backend.ts
56177
56293
  import {
@@ -56184,7 +56300,7 @@ import {
56184
56300
  statfsSync as statfsSync2,
56185
56301
  writeFileSync as writeFileSync12
56186
56302
  } from "fs";
56187
- import { basename as basename6, dirname as dirname13, join as join41 } from "path";
56303
+ import { basename as basename6, dirname as dirname13, join as join42 } from "path";
56188
56304
 
56189
56305
  // packages/daemon/src/vm/storage/count-owner-bytes.ts
56190
56306
  function countOwnerBytes(files) {
@@ -56241,13 +56357,13 @@ import {
56241
56357
  copyFileSync as copyFileSync4,
56242
56358
  existsSync as existsSync25,
56243
56359
  mkdirSync as mkdirSync26,
56244
- readFileSync as readFileSync31,
56360
+ readFileSync as readFileSync33,
56245
56361
  readdirSync as readdirSync10,
56246
56362
  renameSync as renameSync6,
56247
56363
  rmSync as rmSync30,
56248
56364
  statSync as statSync15
56249
56365
  } from "fs";
56250
- import { basename as basename5, dirname as dirname11, join as join38 } from "path";
56366
+ import { basename as basename5, dirname as dirname11, join as join39 } from "path";
56251
56367
  import * as z97 from "zod";
56252
56368
  var CopiesSchema = z97.record(z97.string(), z97.object({ ino: z97.string(), ctimeNs: z97.string(), size: z97.string() }));
56253
56369
  function createXfsBackups(ctx) {
@@ -56255,7 +56371,7 @@ function createXfsBackups(ctx) {
56255
56371
  const freshCopies = new Set;
56256
56372
  const readCopies = () => {
56257
56373
  try {
56258
- return CopiesSchema.parse(JSON.parse(readFileSync31(backup.copies, "utf8")));
56374
+ return CopiesSchema.parse(JSON.parse(readFileSync33(backup.copies, "utf8")));
56259
56375
  } catch {
56260
56376
  return {};
56261
56377
  }
@@ -56278,7 +56394,7 @@ function createXfsBackups(ctx) {
56278
56394
  return {
56279
56395
  createBackupCopy: async (impId, _runId, options) => {
56280
56396
  const source = ctx.resolveImpPaths(impId).disk;
56281
- const target = join38(backup.tree, BACKUP_TREE.buildDisk(impId));
56397
+ const target = join39(backup.tree, BACKUP_TREE.buildDisk(impId));
56282
56398
  const stats = statSync15(source, { bigint: true });
56283
56399
  const record = {
56284
56400
  ino: String(stats.ino),
@@ -56306,34 +56422,34 @@ function createXfsBackups(ctx) {
56306
56422
  const checkpointIds = new Set;
56307
56423
  const imageDigests = new Set;
56308
56424
  for (const imp of request.imps) {
56309
- if (!existsSync25(join38(backup.tree, BACKUP_TREE.buildDisk(imp.impId)))) {
56425
+ if (!existsSync25(join39(backup.tree, BACKUP_TREE.buildDisk(imp.impId)))) {
56310
56426
  continue;
56311
56427
  }
56312
56428
  impIds.add(imp.impId);
56313
56429
  for (const checkpointId of imp.checkpointIds) {
56314
- const isCopied = await createTreeClone(ctx.buildCheckpointDisk(imp.impId, checkpointId), join38(backup.tree, BACKUP_TREE.buildCheckpointDisk(imp.impId, checkpointId)));
56430
+ const isCopied = await createTreeClone(ctx.buildCheckpointDisk(imp.impId, checkpointId), join39(backup.tree, BACKUP_TREE.buildCheckpointDisk(imp.impId, checkpointId)));
56315
56431
  if (isCopied) {
56316
56432
  checkpointIds.add(checkpointId);
56317
56433
  }
56318
56434
  }
56319
- removeUnlisted(join38(backup.tree, BACKUP_TREE.buildImpDir(imp.impId), "checkpoints"), new Set(imp.checkpointIds.filter((id) => checkpointIds.has(id))));
56435
+ removeUnlisted(join39(backup.tree, BACKUP_TREE.buildImpDir(imp.impId), "checkpoints"), new Set(imp.checkpointIds.filter((id) => checkpointIds.has(id))));
56320
56436
  }
56321
56437
  for (const digest of request.imageDigests) {
56322
56438
  const source = buildImagePaths(ctx.dataDir, digest);
56323
- const directory = join38(backup.tree, BACKUP_TREE.buildImageDir(digest));
56324
- const isCopied = await createTreeClone(source.rootfs, join38(directory, "rootfs.ext4"));
56439
+ const directory = join39(backup.tree, BACKUP_TREE.buildImageDir(digest));
56440
+ const isCopied = await createTreeClone(source.rootfs, join39(directory, "rootfs.ext4"));
56325
56441
  if (isCopied) {
56326
- copyFileSync4(source.config, join38(directory, "config.json"));
56442
+ copyFileSync4(source.config, join39(directory, "config.json"));
56327
56443
  imageDigests.add(digest);
56328
56444
  }
56329
56445
  }
56330
- removeUnlisted(join38(backup.tree, "imps"), impIds);
56331
- removeUnlisted(join38(backup.tree, "images"), new Set([...imageDigests].map((digest) => basename5(BACKUP_TREE.buildImageDir(digest)))));
56446
+ removeUnlisted(join39(backup.tree, "imps"), impIds);
56447
+ removeUnlisted(join39(backup.tree, "images"), new Set([...imageDigests].map((digest) => basename5(BACKUP_TREE.buildImageDir(digest)))));
56332
56448
  const copies = readCopies();
56333
56449
  writeCopies(Object.fromEntries(Object.entries(copies).filter(([id]) => impIds.has(id))));
56334
56450
  const removeFreshCopies = () => {
56335
56451
  for (const impId of freshCopies) {
56336
- rmSync30(join38(backup.tree, BACKUP_TREE.buildDisk(impId)), { force: true });
56452
+ rmSync30(join39(backup.tree, BACKUP_TREE.buildDisk(impId)), { force: true });
56337
56453
  }
56338
56454
  freshCopies.clear();
56339
56455
  return Promise.resolve();
@@ -56345,18 +56461,18 @@ function createXfsBackups(ctx) {
56345
56461
  function removeUnlisted(directory, keep) {
56346
56462
  const names = existsSync25(directory) ? readdirSync10(directory) : [];
56347
56463
  for (const name of names.filter((entry) => !keep.has(entry))) {
56348
- rmSync30(join38(directory, name), { recursive: true, force: true });
56464
+ rmSync30(join39(directory, name), { recursive: true, force: true });
56349
56465
  }
56350
56466
  }
56351
56467
 
56352
56468
  // packages/daemon/src/vm/storage/loop-backing-file.ts
56353
- import { readFileSync as readFileSync32, realpathSync, statfsSync } from "fs";
56354
- import { dirname as dirname12, join as join39 } from "path";
56469
+ import { readFileSync as readFileSync34, realpathSync, statfsSync } from "fs";
56470
+ import { dirname as dirname12, join as join40 } from "path";
56355
56471
  var HOST_DIRS = { procDir: "/proc", sysDir: "/sys" };
56356
56472
  function readLoopBackingFile(directory, hostDirs = HOST_DIRS) {
56357
56473
  try {
56358
56474
  const target = realpathSync(directory);
56359
- const mountInfo = readFileSync32(join39(hostDirs.procDir, "self", "mountinfo"), "utf8");
56475
+ const mountInfo = readFileSync34(join40(hostDirs.procDir, "self", "mountinfo"), "utf8");
56360
56476
  for (const line of mountInfo.split(`
56361
56477
  `)) {
56362
56478
  const [mounts = "", fields = ""] = line.split(" - ");
@@ -56364,8 +56480,8 @@ function readLoopBackingFile(directory, hostDirs = HOST_DIRS) {
56364
56480
  const [, source = ""] = fields.split(" ");
56365
56481
  const loop = /^\/dev\/(?<name>loop\d+)$/u.exec(source)?.groups?.["name"];
56366
56482
  if (mountPoint === target && loop !== undefined) {
56367
- const backing = join39(hostDirs.sysDir, "block", loop, "loop", "backing_file");
56368
- return readFileSync32(backing, "utf8").trim();
56483
+ const backing = join40(hostDirs.sysDir, "block", loop, "loop", "backing_file");
56484
+ return readFileSync34(backing, "utf8").trim();
56369
56485
  }
56370
56486
  }
56371
56487
  } catch {}
@@ -56386,7 +56502,7 @@ function readLoopHostFreeBytes(directory, hostDirs = HOST_DIRS) {
56386
56502
 
56387
56503
  // packages/daemon/src/vm/storage/orphan-files.ts
56388
56504
  import { existsSync as existsSync26, readdirSync as readdirSync11, statSync as statSync16 } from "fs";
56389
- import { join as join40 } from "path";
56505
+ import { join as join41 } from "path";
56390
56506
  function probeHoldingFiles(directory) {
56391
56507
  return existsSync26(directory) && readdirSync11(directory, { recursive: true, withFileTypes: true }).some((entry) => !entry.isDirectory());
56392
56508
  }
@@ -56394,7 +56510,7 @@ function listFilesUnder(directory) {
56394
56510
  if (!existsSync26(directory)) {
56395
56511
  return [];
56396
56512
  }
56397
- return readdirSync11(directory, { recursive: true, withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => join40(entry.parentPath, entry.name));
56513
+ return readdirSync11(directory, { recursive: true, withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => join41(entry.parentPath, entry.name));
56398
56514
  }
56399
56515
  function readDirectoryOrphan(kind, id, directory, snapshots) {
56400
56516
  const birth = statSync16(directory).birthtimeMs;
@@ -56420,7 +56536,7 @@ function createXfsBackend(deps) {
56420
56536
  const cloneFile = deps.cloneFile ?? createReflinkClone;
56421
56537
  const readFileExtents = deps.readFileExtents ?? readExtents;
56422
56538
  const resolveImpPaths = (impId) => buildImpPaths(deps.dataDir, impId);
56423
- const buildCheckpointDisk = (impId, checkpointId) => join41(resolveImpPaths(impId).checkpointsDir, checkpointId, "disk.ext4");
56539
+ const buildCheckpointDisk = (impId, checkpointId) => join42(resolveImpPaths(impId).checkpointsDir, checkpointId, "disk.ext4");
56424
56540
  const getSourceFile = (source) => {
56425
56541
  if (source.kind === "image") {
56426
56542
  return buildImagePaths(deps.dataDir, source.digest).rootfs;
@@ -56435,7 +56551,7 @@ function createXfsBackend(deps) {
56435
56551
  };
56436
56552
  const createImage = async (digest, write) => {
56437
56553
  const paths = buildImagePaths(deps.dataDir, digest);
56438
- const staged = join41(buildImagesDir(deps.dataDir), `${STAGING_PREFIX}${Bun.randomUUIDv7()}`);
56554
+ const staged = join42(buildImagesDir(deps.dataDir), `${STAGING_PREFIX}${Bun.randomUUIDv7()}`);
56439
56555
  mkdirSync27(staged, { recursive: true });
56440
56556
  try {
56441
56557
  await write(staged);
@@ -56456,13 +56572,13 @@ function createXfsBackend(deps) {
56456
56572
  return listEntries2(directory).map((id) => ({
56457
56573
  kind: "checkpoint",
56458
56574
  id,
56459
- directory: join41(directory, id)
56575
+ directory: join42(directory, id)
56460
56576
  }));
56461
56577
  }).filter((checkpoint) => !live.checkpointIds.has(checkpoint.id));
56462
56578
  const unknownImages = listEntries2(buildImagesDir(deps.dataDir)).filter((name) => !name.startsWith(".") && !liveDigests.has(name)).map((name) => ({
56463
56579
  kind: "image",
56464
56580
  id: name,
56465
- directory: join41(buildImagesDir(deps.dataDir), name)
56581
+ directory: join42(buildImagesDir(deps.dataDir), name)
56466
56582
  }));
56467
56583
  const unknownImps = impIds.filter((impId) => !live.impIds.has(impId)).map((impId) => ({
56468
56584
  kind: "imp",
@@ -56482,14 +56598,14 @@ function createXfsBackend(deps) {
56482
56598
  };
56483
56599
  const removeLeftover = (dropped, live) => {
56484
56600
  if (dropped.kind === "image") {
56485
- rmSync31(join41(buildImagesDir(deps.dataDir), dropped.id), { recursive: true, force: true });
56601
+ rmSync31(join42(buildImagesDir(deps.dataDir), dropped.id), { recursive: true, force: true });
56486
56602
  }
56487
56603
  if (dropped.kind === "imp") {
56488
56604
  rmSync31(resolveImpPaths(dropped.id).directory, { recursive: true, force: true });
56489
56605
  }
56490
56606
  if (dropped.kind === "checkpoint") {
56491
56607
  for (const impId of live.impIds) {
56492
- rmSync31(join41(resolveImpPaths(impId).checkpointsDir, dropped.id), {
56608
+ rmSync31(join42(resolveImpPaths(impId).checkpointsDir, dropped.id), {
56493
56609
  recursive: true,
56494
56610
  force: true
56495
56611
  });
@@ -56504,7 +56620,7 @@ function createXfsBackend(deps) {
56504
56620
  const listOtherFiles = () => {
56505
56621
  const images = listEntries2(buildImagesDir(deps.dataDir)).filter((name) => !name.startsWith(".")).map((name) => ({
56506
56622
  owner: `image:${name}`,
56507
- path: join41(buildImagesDir(deps.dataDir), name, "rootfs.ext4")
56623
+ path: join42(buildImagesDir(deps.dataDir), name, "rootfs.ext4")
56508
56624
  }));
56509
56625
  const tree = listFilesUnder(backup.tree).map((path) => ({ owner: "backup", path }));
56510
56626
  return [...images, ...tree].filter((file) => existsSync27(file.path));
@@ -56512,7 +56628,7 @@ function createXfsBackend(deps) {
56512
56628
  const usageState = { resumeImpId: null };
56513
56629
  const setupReserveFile = async () => {
56514
56630
  const bytes = deps.reserveFileBytes ?? 0;
56515
- const file = join41(deps.dataDir, "reserve");
56631
+ const file = join42(deps.dataDir, "reserve");
56516
56632
  if (bytes === 0 || existsSync27(file)) {
56517
56633
  return;
56518
56634
  }
@@ -56542,7 +56658,7 @@ function createXfsBackend(deps) {
56542
56658
  start: (live) => {
56543
56659
  const imagesDir = buildImagesDir(deps.dataDir);
56544
56660
  for (const name of listEntries2(imagesDir).filter((entry) => entry.startsWith("."))) {
56545
- rmSync31(join41(imagesDir, name), { recursive: true, force: true });
56661
+ rmSync31(join42(imagesDir, name), { recursive: true, force: true });
56546
56662
  }
56547
56663
  const swept = removeUnnamed(live, { isDryRun: false, isOrphans: false });
56548
56664
  printSweep(getImpdLogger("storage"), swept, "each");
@@ -56564,7 +56680,7 @@ function createXfsBackend(deps) {
56564
56680
  receiveMoveSnapshots: () => Promise.reject(new Error("xfs: only a ZFS host receives ZFS streams")),
56565
56681
  createImage,
56566
56682
  createImageFromImp: (digest, impId, steps) => createImage(digest, async (directory) => {
56567
- await steps.hold(() => cloneFile(resolveImpPaths(impId).disk, join41(directory, "rootfs.ext4")));
56683
+ await steps.hold(() => cloneFile(resolveImpPaths(impId).disk, join42(directory, "rootfs.ext4")));
56568
56684
  await steps.write(directory);
56569
56685
  }),
56570
56686
  removeImage: (digest) => {
@@ -56706,8 +56822,8 @@ function isSharedExtent(extent) {
56706
56822
  }
56707
56823
 
56708
56824
  // packages/daemon/src/vm/storage/zfs/zfs-backend.ts
56709
- import { existsSync as existsSync30, mkdirSync as mkdirSync28, readFileSync as readFileSync33, rmdirSync as rmdirSync3, writeFileSync as writeFileSync13 } from "fs";
56710
- import { join as join45 } from "path";
56825
+ import { existsSync as existsSync30, mkdirSync as mkdirSync28, readFileSync as readFileSync35, rmdirSync as rmdirSync3, writeFileSync as writeFileSync13 } from "fs";
56826
+ import { join as join46 } from "path";
56711
56827
 
56712
56828
  // packages/daemon/src/platform/process/run-stream.ts
56713
56829
  function createStreamRunner() {
@@ -56996,7 +57112,7 @@ function formatUiomoveWarning(version) {
56996
57112
 
56997
57113
  // packages/daemon/src/vm/storage/zfs/create-zfs-backups.ts
56998
57114
  import { rmSync as rmSync32 } from "fs";
56999
- import { dirname as dirname14, join as join42 } from "path";
57115
+ import { dirname as dirname14, join as join43 } from "path";
57000
57116
  function createZfsBackups(ctx) {
57001
57117
  return {
57002
57118
  createBackupCopy: (impId, runId) => ctx.runSnapshot(() => ctx.zfs.snapshot(`${ctx.buildDiskName(impId)}@bk-${runId}-${impId}`)),
@@ -57023,7 +57139,7 @@ function createZfsBackups(ctx) {
57023
57139
  ctx.startReclaim();
57024
57140
  };
57025
57141
  const createTreeClone = async (snapshot, name, relativeDir) => {
57026
- const directory = join42(tree, relativeDir);
57142
+ const directory = join43(tree, relativeDir);
57027
57143
  await ctx.zfs.clone(snapshot, name, { readonly: "on" });
57028
57144
  clones.push({ name, directory });
57029
57145
  await ctx.setupMount(name, directory, true);
@@ -57033,8 +57149,8 @@ function createZfsBackups(ctx) {
57033
57149
  if (mounted !== undefined) {
57034
57150
  throw new Error(`zfs: ${mounted} in the backup tree is still mounted`);
57035
57151
  }
57036
- rmSync32(join42(tree, "imps"), { recursive: true, force: true });
57037
- rmSync32(join42(tree, "images"), { recursive: true, force: true });
57152
+ rmSync32(join43(tree, "imps"), { recursive: true, force: true });
57153
+ rmSync32(join43(tree, "images"), { recursive: true, force: true });
57038
57154
  const entries = await ctx.listAll();
57039
57155
  for (const imp of request.imps) {
57040
57156
  const copy = entries.find((entry) => entry.type === "snapshot" && entry.name.endsWith(`@bk-${request.runId}-${imp.impId}`));
@@ -57167,7 +57283,7 @@ function createZfsCheckpoints(ctx) {
57167
57283
  }
57168
57284
 
57169
57285
  // packages/daemon/src/vm/storage/zfs/create-zfs-moves.ts
57170
- import { join as join43 } from "path";
57286
+ import { join as join44 } from "path";
57171
57287
  function createZfsMoves(ctx) {
57172
57288
  const openMoveFiles = async (snapshots, removeMoveSnapshot) => {
57173
57289
  const moveId = Bun.randomUUIDv7();
@@ -57196,7 +57312,7 @@ function createZfsMoves(ctx) {
57196
57312
  await removeClones();
57197
57313
  throw error;
57198
57314
  }
57199
- const paths = clones.map((clone) => join43(clone.directory, ctx.rootfsFile));
57315
+ const paths = clones.map((clone) => join44(clone.directory, ctx.rootfsFile));
57200
57316
  return {
57201
57317
  kind: "files",
57202
57318
  checkpointPaths: paths.slice(0, -1),
@@ -57452,7 +57568,7 @@ function createZfsReclaim(ctx) {
57452
57568
 
57453
57569
  // packages/daemon/src/vm/storage/zfs/create-zfs-sweep.ts
57454
57570
  import { existsSync as existsSync28, readdirSync as readdirSync13, rmSync as rmSync33 } from "fs";
57455
- import { join as join44 } from "path";
57571
+ import { join as join45 } from "path";
57456
57572
  var FORK_SNAPSHOT = /@fork-[^@]+$/u;
57457
57573
  var BACKUP_SNAPSHOT = /@bk-[^@]+$/u;
57458
57574
  var MOVE_SNAPSHOT = /@mv-[^@]+$/u;
@@ -57477,10 +57593,10 @@ function createZfsSweep(ctx) {
57477
57593
  const orphanCheckpoints = isOrphans ? [] : unmarked.filter((entry) => !isOnOrphan(entry) && isOrphanCheckpoint(entry));
57478
57594
  const keptDisks = isOrphans ? [] : unknownDisks;
57479
57595
  const keptImpIds = new Set(keptDisks.map((disk) => getChildId(disk.name, ctx.datasets.disks)));
57480
- const listUnknownDirs = (kind, parent) => (existsSync28(parent) ? readdirSync13(parent).toSorted() : []).filter((id) => !live.impIds.has(id) && !keptImpIds.has(id)).map((id) => ({ kind, id, directory: join44(parent, id) }));
57596
+ const listUnknownDirs = (kind, parent) => (existsSync28(parent) ? readdirSync13(parent).toSorted() : []).filter((id) => !live.impIds.has(id) && !keptImpIds.has(id)).map((id) => ({ kind, id, directory: join45(parent, id) }));
57481
57597
  const unknownDirs = [
57482
57598
  ...listUnknownDirs("imp", buildImpsDir(ctx.dataDir)),
57483
- ...listUnknownDirs("memory", join44(ctx.dataDir, "mem"))
57599
+ ...listUnknownDirs("memory", join45(ctx.dataDir, "mem"))
57484
57600
  ];
57485
57601
  const probeDirDropped = (entry) => isOrphans || !probeHoldingFiles(entry.directory);
57486
57602
  const droppedDirs = unknownDirs.filter((entry) => probeDirDropped(entry));
@@ -57569,7 +57685,7 @@ function createZfsSweep(ctx) {
57569
57685
  }
57570
57686
  }
57571
57687
  for (const impId of plan.memDirs) {
57572
- rmSync33(join44(ctx.dataDir, "mem", impId), { recursive: true, force: true });
57688
+ rmSync33(join45(ctx.dataDir, "mem", impId), { recursive: true, force: true });
57573
57689
  }
57574
57690
  return { dropped: toDropped(plan), kept };
57575
57691
  };
@@ -57657,13 +57773,13 @@ function createZfsBackend(deps) {
57657
57773
  const buildDiskName = (impId) => `${datasets.disks}/${impId}`;
57658
57774
  const buildImageName = (digest) => `${datasets.images}/${toDigestHex(digest)}`;
57659
57775
  const buildRestoreName = (impId) => `${datasets.staging}/restore-${impId}`;
57660
- const buildDiskDir = (impId) => join45(buildImpPaths(deps.dataDir, impId).directory, "disk");
57776
+ const buildDiskDir = (impId) => join46(buildImpPaths(deps.dataDir, impId).directory, "disk");
57661
57777
  const buildImageDir = (digest) => buildImagePaths(deps.dataDir, digest).directory;
57662
- const buildStagingDir = (name) => join45(deps.dataDir, "staging", name.slice(datasets.staging.length + 1));
57778
+ const buildStagingDir = (name) => join46(deps.dataDir, "staging", name.slice(datasets.staging.length + 1));
57663
57779
  const resolveImpPaths = (impId) => ({
57664
57780
  ...buildImpPaths(deps.dataDir, impId),
57665
- disk: join45(buildDiskDir(impId), ROOTFS_FILE),
57666
- ...buildSnapshotPaths(join45(deps.dataDir, "mem", impId))
57781
+ disk: join46(buildDiskDir(impId), ROOTFS_FILE),
57782
+ ...buildSnapshotPaths(join46(deps.dataDir, "mem", impId))
57667
57783
  });
57668
57784
  const listAll = () => zfs.list(deps.root);
57669
57785
  const setupMount = async (name, directory, isReadOnly = false) => {
@@ -57806,7 +57922,7 @@ function createZfsBackend(deps) {
57806
57922
  throw new Error(`zfs: ${deps.root} is not mounted on ${deps.dataDir} (host/scripts/setup-storage.sh mounts it)`);
57807
57923
  }
57808
57924
  await createMissingDatasets();
57809
- await setupMount(datasets.mem, join45(deps.dataDir, "mem"));
57925
+ await setupMount(datasets.mem, join46(deps.dataDir, "mem"));
57810
57926
  await resolveStaging();
57811
57927
  const swept = await sweep.removeLeftovers(live, { isDryRun: false, isOrphans: false });
57812
57928
  printSweep(getImpdLogger("storage"), swept, "each");
@@ -57891,7 +58007,7 @@ function createZfsBackend(deps) {
57891
58007
  await zfs.create(target);
57892
58008
  await setupMount(target, buildDiskDir(impId));
57893
58009
  });
57894
- writeFileSync13(join45(buildDiskDir(impId), ROOTFS_FILE), "");
58010
+ writeFileSync13(join46(buildDiskDir(impId), ROOTFS_FILE), "");
57895
58011
  return;
57896
58012
  }
57897
58013
  await runSerial(async () => {
@@ -57968,7 +58084,7 @@ function createZfsBackend(deps) {
57968
58084
  }
57969
58085
  function readZfsModuleVersion() {
57970
58086
  try {
57971
- return readFileSync33("/sys/module/zfs/version", "utf8").trim();
58087
+ return readFileSync35("/sys/module/zfs/version", "utf8").trim();
57972
58088
  } catch {
57973
58089
  return null;
57974
58090
  }
@@ -58011,14 +58127,14 @@ function createBackend(config, boundaries) {
58011
58127
  });
58012
58128
  }
58013
58129
  function checkStorageMarker(dataDir, kind) {
58014
- const marker = join46(dataDir, MARKER_FILE);
58015
- const recorded = existsSync31(marker) ? readFileSync34(marker, "utf8").trim() : readUnmarked(dataDir);
58130
+ const marker = join47(dataDir, MARKER_FILE);
58131
+ const recorded = existsSync31(marker) ? readFileSync36(marker, "utf8").trim() : readUnmarked(dataDir);
58016
58132
  if (recorded !== null && recorded !== kind) {
58017
58133
  throw new Error(`${dataDir} holds ${recorded} storage, but IMP_STORAGE_BACKEND is ${kind}; moving imps between backends is not supported`);
58018
58134
  }
58019
58135
  }
58020
58136
  function writeStorageMarker(dataDir, kind) {
58021
- const marker = join46(dataDir, MARKER_FILE);
58137
+ const marker = join47(dataDir, MARKER_FILE);
58022
58138
  if (!existsSync31(marker)) {
58023
58139
  writeFileSync14(marker, `${kind}
58024
58140
  `);
@@ -58031,7 +58147,7 @@ function readUnmarked(dataDir) {
58031
58147
  }
58032
58148
 
58033
58149
  // packages/daemon/src/vm/storage/setup-system-files.ts
58034
- import { existsSync as existsSync32, mkdirSync as mkdirSync29, readFileSync as readFileSync35 } from "fs";
58150
+ import { existsSync as existsSync32, mkdirSync as mkdirSync29, readFileSync as readFileSync37 } from "fs";
58035
58151
  import { dirname as dirname15 } from "path";
58036
58152
 
58037
58153
  // packages/daemon/src/vm/storage/system-file-info.ts
@@ -58067,7 +58183,7 @@ async function setupSystemFiles(config) {
58067
58183
  const missing = config.kernelSource === null ? " and no source is configured" : "";
58068
58184
  throw new Error(`${kernelSource} does not exist${missing}`);
58069
58185
  }
58070
- const kernel = readFileSync35(kernelSource);
58186
+ const kernel = readFileSync37(kernelSource);
58071
58187
  const guestKernel = readKernelInfo(kernel);
58072
58188
  if (config.kernelSource !== null && !probeContent(config.kernelPath, kernel)) {
58073
58189
  writeCopy(config.kernelSource, config.kernelPath);
@@ -58087,7 +58203,7 @@ async function setupSystemFiles(config) {
58087
58203
  };
58088
58204
  }
58089
58205
  function probeContent(path, content) {
58090
- return existsSync32(path) && Buffer.from(content).equals(readFileSync35(path));
58206
+ return existsSync32(path) && Buffer.from(content).equals(readFileSync37(path));
58091
58207
  }
58092
58208
  function writeCopy(source, target) {
58093
58209
  mkdirSync29(dirname15(target), { recursive: true });
@@ -58139,7 +58255,7 @@ async function startImpdParts(config, boundaries, plan) {
58139
58255
  }
58140
58256
  return files;
58141
58257
  });
58142
- const db = await runStep("database", () => boundaries.db ?? openDatabase(join47(config.dataDir, "db", "imp.sqlite")));
58258
+ const db = await runStep("database", () => boundaries.db ?? openDatabase(join48(config.dataDir, "db", "imp.sqlite")));
58143
58259
  plan.db = boundaries.db === undefined ? db : null;
58144
58260
  const kernelOops = boundaries.imps?.kernelOops ?? createKernelOopsWatch();
58145
58261
  const storage = boundaries.storage ?? createStorageBackend(config, { zfs: { isKernelOopsed: kernelOops.isOopsed } });
@@ -58246,7 +58362,7 @@ async function startImpdParts(config, boundaries, plan) {
58246
58362
  secretFiles
58247
58363
  });
58248
58364
  const state = { ready: false };
58249
- const authorizedKeys = createAuthorizedKeys(join47(setupSshDir(config.dataDir), "authorized_keys"));
58365
+ const authorizedKeys = createAuthorizedKeys(join48(setupSshDir(config.dataDir), "authorized_keys"));
58250
58366
  const access = await runStep("access", () => loadImpdAccess(config, deps, authorizedKeys.probeListed));
58251
58367
  const backups = config.backup === null ? null : createBackupService({
58252
58368
  dataDir: config.dataDir,
@@ -58312,7 +58428,7 @@ async function startImpdParts(config, boundaries, plan) {
58312
58428
  readTailnetNames: tailnetNames === null ? null : tailnetNames.readStatus,
58313
58429
  hostReaders: {
58314
58430
  readKernel: () => deps.hostKernelRelease ?? release2(),
58315
- readCpuInfo: deps.readCpuInfo ?? (() => readFileSync36("/proc/cpuinfo", "utf8")),
58431
+ readCpuInfo: deps.readCpuInfo ?? (() => readFileSync38("/proc/cpuinfo", "utf8")),
58316
58432
  readHugePagePool: deps.imps?.readHugePagePool ?? (() => readHugePagePool())
58317
58433
  },
58318
58434
  isReady: () => state.ready,
@@ -58431,6 +58547,11 @@ function buildStubTickerTimer() {
58431
58547
  };
58432
58548
  }
58433
58549
 
58550
+ // packages/daemon/testing/platform/format-run-prefix.ts
58551
+ function formatRunPrefix(owner) {
58552
+ return `pid${String(owner.pid)}-ns${owner.namespace}-`;
58553
+ }
58554
+
58434
58555
  // packages/daemon/testing/platform/open-migrated-copy.ts
58435
58556
  import { Database as Database4 } from "bun:sqlite";
58436
58557
  var TEMPLATE = {};
@@ -58453,6 +58574,15 @@ function pickImpdPort(draw) {
58453
58574
  return FIRST_PORT + Math.floor(draw * PORT_SPAN);
58454
58575
  }
58455
58576
 
58577
+ // packages/daemon/testing/platform/read-run-owner.ts
58578
+ import { readlinkSync as readlinkSync2 } from "fs";
58579
+ function readRunOwner() {
58580
+ return {
58581
+ pid: process.pid,
58582
+ namespace: readlinkSync2("/proc/self/ns/pid").replaceAll(/\D/gu, "")
58583
+ };
58584
+ }
58585
+
58456
58586
  // packages/daemon/testing/platform/start-impd-log-capture.ts
58457
58587
  import { resetSync } from "@logtape/logtape";
58458
58588
 
@@ -58547,7 +58677,8 @@ function buildStubVmm() {
58547
58677
  uptimeMs: 60000,
58548
58678
  identityReset: "ok",
58549
58679
  hasBootId: true,
58550
- bootSteps: {}
58680
+ bootSteps: {},
58681
+ pageHandler: undefined
58551
58682
  };
58552
58683
  const guestMemory = new Map;
58553
58684
  const readFakeGuestMemory = (directory) => {
@@ -58669,7 +58800,8 @@ log tail`);
58669
58800
  return {
58670
58801
  ...vm,
58671
58802
  hugePages: plan.hugePages ?? "None",
58672
- bootId: bootIds.get(plan.paths.apiSocket)
58803
+ bootId: bootIds.get(plan.paths.apiSocket),
58804
+ ...plan.hugePages === "2M" && { pageHandler: guest.pageHandler }
58673
58805
  };
58674
58806
  } finally {
58675
58807
  usedSnapshots.add(plan.paths.snapshotDir);
@@ -58879,6 +59011,9 @@ log tail`);
58879
59011
  setGuestBootSteps: (steps) => {
58880
59012
  guest.bootSteps = steps;
58881
59013
  },
59014
+ setPageHandlerStats: (stats) => {
59015
+ guest.pageHandler = stats;
59016
+ },
58882
59017
  setIdentityReset: (result) => {
58883
59018
  guest.identityReset = result;
58884
59019
  },
@@ -58918,7 +59053,7 @@ var NO_FREEZER = { freeze: () => Promise.resolve(), thaw: () => Promise.resolve(
58918
59053
  var KSM_KERNEL = "6.12.0";
58919
59054
  var IDLE_KSM = { running: true, sharedMib: 0, profitMib: 0, zeroMib: 0 };
58920
59055
  async function startTestImpd(stack, options = {}) {
58921
- const dataDir = options.dataDir ?? mkdtempSync(`${tmpdir()}/impd-test-`);
59056
+ const dataDir = options.dataDir ?? mkdtempSync(`${tmpdir()}/${formatRunPrefix(readRunOwner())}impd-test-`);
58922
59057
  if (options.dataDir === undefined) {
58923
59058
  stack.defer(() => rm2(dataDir, { recursive: true, force: true }));
58924
59059
  }
@@ -58989,6 +59124,7 @@ async function startTestImpd(stack, options = {}) {
58989
59124
  });
58990
59125
  const cgroups = options.cgroups ?? createCpuCgroups({ root: "/nonexistent" });
58991
59126
  const extra = options.boundaries ?? {};
59127
+ const procRoot = options.procRoot;
58992
59128
  const buildBoundaries = (identity, runner, storage) => {
58993
59129
  const jails = options.jails;
58994
59130
  return {
@@ -59088,6 +59224,9 @@ async function startTestImpd(stack, options = {}) {
59088
59224
  hostCpus: options.hostCpus ?? 8,
59089
59225
  kernelOops,
59090
59226
  readThreadIds: (pid) => options.procRoot === undefined ? null : readThreadIds(pid, options.procRoot),
59227
+ ...procRoot !== undefined && {
59228
+ readHostLoad: () => readHostLoad({ procRoot, readFile: readText, logger: getImpdLogger("imps") })
59229
+ },
59091
59230
  ...options.readUnsharedRamMib !== undefined && {
59092
59231
  readUnsharedRamMib: options.readUnsharedRamMib
59093
59232
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@impz/testing",
3
- "version": "6.4.2",
3
+ "version": "6.6.0",
4
4
  "description": "A real impd on stand-ins, for Bun tests of code that drives impd through @impz/client",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -43,7 +43,7 @@
43
43
  "ts-pattern": "^5.9.2",
44
44
  "xstate": "^5.33.3",
45
45
  "zod": "^4.6.7",
46
- "@impz/client": "6.4.2"
46
+ "@impz/client": "6.6.0"
47
47
  },
48
48
  "engines": {
49
49
  "bun": ">=1.4.3"