@impz/testing 6.4.2 → 6.5.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 +239 -148
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -21961,18 +21961,19 @@ function parseKsmConfig(parsed) {
21961
21961
  }
21962
21962
 
21963
21963
  // packages/daemon/src/create-impd.ts
21964
- import { readFileSync as readFileSync36 } from "fs";
21964
+ import { readFileSync as readFileSync37 } from "fs";
21965
21965
  import { release as release2 } from "os";
21966
- import { join as join47 } from "path";
21966
+ import { join as join48 } from "path";
21967
21967
  // packages/daemon/package.json
21968
21968
  var package_default = {
21969
21969
  name: "@impz/daemon",
21970
- version: "6.4.2",
21970
+ version: "6.5.0",
21971
21971
  private: true,
21972
21972
  description: "impd: the imp host daemon",
21973
21973
  type: "module",
21974
21974
  exports: {
21975
21975
  ".": "./src/index.ts",
21976
+ "./read-text": "./src/platform/process/read-text.ts",
21976
21977
  "./real-clock": "./src/platform/process/real-clock.ts",
21977
21978
  "./testing": "./testing/index.ts",
21978
21979
  "./testing/build-stub-clock": "./testing/platform/build-stub-clock.ts",
@@ -41112,7 +41113,8 @@ function createImpContext(deps) {
41112
41113
  const records = {
41113
41114
  config: deps.config,
41114
41115
  db: deps.db,
41115
- identity: deps.identity
41116
+ identity: deps.identity,
41117
+ readHostLoad: deps.readHostLoad
41116
41118
  };
41117
41119
  const clock = {
41118
41120
  now,
@@ -43497,6 +43499,22 @@ ${readLogTail(plan.paths.logFile, 5)}`, step.fault, error);
43497
43499
  }
43498
43500
  }
43499
43501
 
43502
+ // packages/daemon/src/imps/imps/format-host-stall.ts
43503
+ var STALL_FIGURES = [
43504
+ ["cpu", "cpuStallUs"],
43505
+ ["io", "ioStallUs"],
43506
+ ["memory", "memoryStallUs"],
43507
+ ["steal", "stealUs"]
43508
+ ];
43509
+ function formatHostStall(before, after) {
43510
+ const figures = STALL_FIGURES.flatMap(([name, field]) => {
43511
+ const startUs = before[field];
43512
+ const endUs = after[field];
43513
+ return startUs === null || endUs === null ? [] : [`${name}=${String(Math.round((endUs - startUs) / 1000))}ms`];
43514
+ });
43515
+ return figures.length === 0 ? "" : `; host stall ${figures.join(" ")}`;
43516
+ }
43517
+
43500
43518
  // packages/daemon/src/imps/imps/start-cold-vm.ts
43501
43519
  var CLAIM_SEED_BYTES = 64;
43502
43520
  async function startColdVm(context, start) {
@@ -43552,11 +43570,12 @@ async function startColdVm(context, start) {
43552
43570
  }
43553
43571
  });
43554
43572
  context.templates?.reportRestored(template);
43555
- getImpdLogger("imps").with({ imp: imp.name }).info("restored boot template {key} as pid {pid} {timings}{guestSteps}", {
43573
+ getImpdLogger("imps").with({ imp: imp.name }).info("restored boot template {key} as pid {pid} {timings}{guestSteps}{hostStall}", {
43556
43574
  key: template.key.slice(0, 12),
43557
43575
  pid: String(vm.pid),
43558
43576
  timings: formatTimings({ ...hostSteps, ...vm.timings }),
43559
- guestSteps: formatGuestSteps(vm.guestSteps)
43577
+ guestSteps: formatGuestSteps(vm.guestSteps),
43578
+ hostStall: formatHostStall(start.loadBefore, context.readHostLoad())
43560
43579
  });
43561
43580
  return vm;
43562
43581
  } catch (error) {
@@ -43589,10 +43608,11 @@ async function startColdVm(context, start) {
43589
43608
  isIdentityReset: imp.isIdentityResetPending,
43590
43609
  jail: context.findJailUser(imp)
43591
43610
  });
43592
- getImpdLogger("imps").with({ imp: imp.name }).info("booted pid {pid} {timings}{guestSteps}", {
43611
+ getImpdLogger("imps").with({ imp: imp.name }).info("booted pid {pid} {timings}{guestSteps}{hostStall}", {
43593
43612
  pid: String(vm.pid),
43594
43613
  timings: formatTimings({ ...hostSteps, ...vm.timings }),
43595
- guestSteps: formatGuestSteps(vm.guestSteps)
43614
+ guestSteps: formatGuestSteps(vm.guestSteps),
43615
+ hostStall: formatHostStall(start.loadBefore, context.readHostLoad())
43596
43616
  });
43597
43617
  return vm;
43598
43618
  }
@@ -43673,6 +43693,7 @@ function createImpVmOps(host) {
43673
43693
  hugePagesMib: hugePages === "2M" ? imp.memoryMib : 0
43674
43694
  });
43675
43695
  const setupStarted = performance.now();
43696
+ const loadBefore = context.readHostLoad();
43676
43697
  try {
43677
43698
  removeSnapshot(paths);
43678
43699
  await context.egress.requireImp(imp.id);
@@ -43690,6 +43711,7 @@ function createImpVmOps(host) {
43690
43711
  cgroup,
43691
43712
  hugePages,
43692
43713
  hostSteps,
43714
+ loadBefore,
43693
43715
  diskReady
43694
43716
  });
43695
43717
  startCounting(context, imp, vm.pid);
@@ -44394,6 +44416,56 @@ function createImpService(deps, createWatchdog) {
44394
44416
  };
44395
44417
  }
44396
44418
 
44419
+ // packages/daemon/src/platform/process/read-host-load.ts
44420
+ import { join as join22 } from "path";
44421
+
44422
+ // packages/daemon/src/platform/process/find-unexpected-read-code.ts
44423
+ var UNSUPPORTED_CODES = new Set(["ENOENT", "EOPNOTSUPP"]);
44424
+ function findUnexpectedReadCode(error) {
44425
+ const code = error instanceof Error && "code" in error ? String(error.code) : "unknown";
44426
+ return UNSUPPORTED_CODES.has(code) ? null : code;
44427
+ }
44428
+
44429
+ // packages/daemon/src/platform/process/read-host-load.ts
44430
+ function readHostLoad(sources) {
44431
+ const readProc = (...names) => readProcFile(sources, join22(sources.procRoot, ...names));
44432
+ return {
44433
+ cpuStallUs: parsePressureTotal(readProc("pressure", "cpu")),
44434
+ ioStallUs: parsePressureTotal(readProc("pressure", "io")),
44435
+ memoryStallUs: parsePressureTotal(readProc("pressure", "memory")),
44436
+ stealUs: parseStealUs(readProc("stat"))
44437
+ };
44438
+ }
44439
+ function readProcFile(sources, path) {
44440
+ try {
44441
+ return sources.readFile(path);
44442
+ } catch (error) {
44443
+ const code = findUnexpectedReadCode(error);
44444
+ if (code !== null) {
44445
+ sources.logger.warning("cannot read {path} for the host stall: {code}", { path, code });
44446
+ }
44447
+ return null;
44448
+ }
44449
+ }
44450
+ function parsePressureTotal(pressure) {
44451
+ const total = pressure === null ? undefined : /^some .*total=(?<us>\d+)$/mv.exec(pressure);
44452
+ return total?.groups?.["us"] === undefined ? null : Number(total.groups["us"]);
44453
+ }
44454
+ var STEAL_FIELD = 8;
44455
+ var US_PER_TICK = 1e4;
44456
+ function parseStealUs(stat) {
44457
+ const fields = stat?.split(`
44458
+ `).find((line) => line.startsWith("cpu "))?.split(/\s+/v);
44459
+ const steal = fields?.[STEAL_FIELD];
44460
+ return steal === undefined ? null : Number(steal) * US_PER_TICK;
44461
+ }
44462
+
44463
+ // packages/daemon/src/platform/process/read-text.ts
44464
+ import { readFileSync as readFileSync22 } from "fs";
44465
+ function readText(path) {
44466
+ return readFileSync22(path, "utf8");
44467
+ }
44468
+
44397
44469
  // packages/daemon/src/platform/telemetry/imp-telemetry.ts
44398
44470
  import { ROOT_CONTEXT, metrics as metrics2, trace } from "@opentelemetry/api";
44399
44471
  var SPAN_NAMES = {
@@ -44770,12 +44842,12 @@ function createMemoryController(deps) {
44770
44842
  import {
44771
44843
  existsSync as existsSync14,
44772
44844
  mkdirSync as mkdirSync16,
44773
- readFileSync as readFileSync22,
44845
+ readFileSync as readFileSync23,
44774
44846
  readdirSync as readdirSync8,
44775
44847
  rmdirSync as rmdirSync2,
44776
44848
  writeFileSync as writeFileSync5
44777
44849
  } from "fs";
44778
- import { join as join22 } from "path";
44850
+ import { join as join23 } from "path";
44779
44851
  var PERIOD_US = 1e5;
44780
44852
  var MEMORY_MIN_OVERHEAD_MIB = 256;
44781
44853
  var MEMORY_OVERHEAD_DIVISOR = 8;
@@ -44803,18 +44875,18 @@ function parseOomKills(text) {
44803
44875
  return match?.groups === undefined ? null : Number(match.groups["count"]);
44804
44876
  }
44805
44877
  function createCpuCgroups(options) {
44806
- const imps = join22(options.root, "imps");
44878
+ const imps = join23(options.root, "imps");
44807
44879
  const procRoot = options.procRoot ?? "/proc";
44808
44880
  const rmdir = options.rmdir ?? rmdirSync2;
44809
44881
  const sleep = options.sleep ?? Bun.sleep;
44810
44882
  const isEnforced = probeControllerDelegated(imps, "cpu");
44811
44883
  const isMemoryEnforced = isEnforced && probeControllerDelegated(imps, "memory");
44812
- const getDir = (impId) => join22(imps, impId);
44884
+ const getDir = (impId) => join23(imps, impId);
44813
44885
  const guestMibs = new Map;
44814
44886
  const oomBaselines = new Map;
44815
44887
  const readOomKills = (impId) => {
44816
44888
  try {
44817
- const events = readFileSync22(join22(getDir(impId), "memory.events"), "utf8");
44889
+ const events = readFileSync23(join23(getDir(impId), "memory.events"), "utf8");
44818
44890
  return parseOomKills(events);
44819
44891
  } catch {
44820
44892
  return null;
@@ -44824,8 +44896,8 @@ function createCpuCgroups(options) {
44824
44896
  oomBaselines.set(impId, readOomKills(impId) ?? 0);
44825
44897
  };
44826
44898
  const writeSettings = (impId, cpu, limit) => {
44827
- writeFileSync5(join22(getDir(impId), "cpu.weight"), String(cpu.weight));
44828
- writeFileSync5(join22(getDir(impId), "cpu.max"), formatCpuMax(limit));
44899
+ writeFileSync5(join23(getDir(impId), "cpu.weight"), String(cpu.weight));
44900
+ writeFileSync5(join23(getDir(impId), "cpu.max"), formatCpuMax(limit));
44829
44901
  };
44830
44902
  const writeMemory = (impId) => {
44831
44903
  const guestMib = guestMibs.get(impId);
@@ -44833,10 +44905,10 @@ function createCpuCgroups(options) {
44833
44905
  return;
44834
44906
  }
44835
44907
  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");
44908
+ writeFileSync5(join23(directory, "memory.max"), buildMemoryMax(guestMib));
44909
+ writeFileSync5(join23(directory, "memory.high"), "max");
44910
+ writeFileSync5(join23(directory, "memory.swap.max"), "0");
44911
+ writeFileSync5(join23(directory, "memory.oom.group"), "1");
44840
44912
  };
44841
44913
  const setup = (impId, cpu, memoryMib) => {
44842
44914
  if (!isEnforced) {
@@ -44858,7 +44930,7 @@ function createCpuCgroups(options) {
44858
44930
  return null;
44859
44931
  }
44860
44932
  return {
44861
- procsPath: join22(getDir(impId), "cgroup.procs"),
44933
+ procsPath: join23(getDir(impId), "cgroup.procs"),
44862
44934
  liftLimit: () => {
44863
44935
  tryWrite(impId, "lift the limit", () => {
44864
44936
  writeSettings(impId, cpu, null);
@@ -44942,7 +45014,7 @@ function createCpuCgroups(options) {
44942
45014
  kill: (impId) => {
44943
45015
  if (isEnforced && existsSync14(getDir(impId))) {
44944
45016
  tryWrite(impId, "kill", () => {
44945
- writeFileSync5(join22(getDir(impId), "cgroup.kill"), "1");
45017
+ writeFileSync5(join23(getDir(impId), "cgroup.kill"), "1");
44946
45018
  });
44947
45019
  }
44948
45020
  },
@@ -44953,7 +45025,7 @@ function createCpuCgroups(options) {
44953
45025
  },
44954
45026
  readCpuStat: (impId) => {
44955
45027
  try {
44956
- const stat = readFileSync22(join22(getDir(impId), "cpu.stat"), "utf8");
45028
+ const stat = readFileSync23(join23(getDir(impId), "cpu.stat"), "utf8");
44957
45029
  return parseCpuStat(stat);
44958
45030
  } catch {
44959
45031
  return null;
@@ -44963,7 +45035,7 @@ function createCpuCgroups(options) {
44963
45035
  }
44964
45036
  function probeControllerDelegated(imps, controller) {
44965
45037
  try {
44966
- const delegated = readFileSync22(join22(imps, "cgroup.subtree_control"), "utf8");
45038
+ const delegated = readFileSync23(join23(imps, "cgroup.subtree_control"), "utf8");
44967
45039
  return delegated.split(/\s+/u).includes(controller);
44968
45040
  } catch {
44969
45041
  return false;
@@ -44996,13 +45068,13 @@ function probeUffdDevice(path = "/dev/userfaultfd") {
44996
45068
  }
44997
45069
 
44998
45070
  // packages/daemon/src/vm/vmm/read-huge-page-pool.ts
44999
- import { readFileSync as readFileSync23 } from "fs";
45000
- import { join as join23 } from "path";
45071
+ import { readFileSync as readFileSync24 } from "fs";
45072
+ import { join as join24 } from "path";
45001
45073
  var HUGE_PAGE_MIB = 2;
45002
45074
  function readHugePagePool(sysRoot = "/sys") {
45003
- const directory = join23(sysRoot, "kernel", "mm", "hugepages", "hugepages-2048kB");
45075
+ const directory = join24(sysRoot, "kernel", "mm", "hugepages", "hugepages-2048kB");
45004
45076
  try {
45005
- const readCount = (name) => Number(readFileSync23(join23(directory, name), "utf8").trim());
45077
+ const readCount = (name) => Number(readFileSync24(join24(directory, name), "utf8").trim());
45006
45078
  const total = readCount("nr_hugepages");
45007
45079
  const free = readCount("free_hugepages") - readCount("resv_hugepages");
45008
45080
  if (!Number.isSafeInteger(total) || !Number.isSafeInteger(free)) {
@@ -45581,6 +45653,7 @@ function resolveImpBoundaries(boundaries) {
45581
45653
  kernelOops: boundaries.kernelOops ?? createKernelOopsWatch(),
45582
45654
  readThreadIds: boundaries.readThreadIds ?? ((pid) => readThreadIds(pid)),
45583
45655
  readNetBytes: boundaries.readNetBytes ?? ((tap) => readGuestNetBytes(tap)),
45656
+ readHostLoad: boundaries.readHostLoad ?? (() => readHostLoad({ procRoot: "/proc", readFile: readText, logger: getImpdLogger("imps") })),
45584
45657
  ...boundaries.openTap !== undefined && { openTap: boundaries.openTap },
45585
45658
  ...boundaries.now !== undefined && { now: boundaries.now }
45586
45659
  };
@@ -45595,7 +45668,7 @@ function makeStandInVmRam(readRam) {
45595
45668
 
45596
45669
  // packages/daemon/src/imp-ops/moves/move-receiver.ts
45597
45670
  import { existsSync as existsSync16, rmSync as rmSync24 } from "fs";
45598
- import { join as join25 } from "path";
45671
+ import { join as join26 } from "path";
45599
45672
 
45600
45673
  // packages/daemon/src/platform/db/probe-slot-free.ts
45601
45674
  async function probeSlotFree(db, slot, now) {
@@ -45920,7 +45993,7 @@ function readReceipt(receipt, secret) {
45920
45993
  // packages/daemon/src/imp-ops/moves/read-move-stream.ts
45921
45994
  import { mkdirSync as mkdirSync19, rmSync as rmSync23 } from "fs";
45922
45995
  import { open as open7 } from "fs/promises";
45923
- import { join as join24 } from "path";
45996
+ import { join as join25 } from "path";
45924
45997
  import invariant5 from "tiny-invariant";
45925
45998
 
45926
45999
  // packages/daemon/src/imp-ops/moves/build-received-digest.ts
@@ -46545,7 +46618,7 @@ async function readMoveStream(deps, options) {
46545
46618
  const count = createByteCounter(row.bytes);
46546
46619
  const files = [];
46547
46620
  mkdirSync19(options.tempDir, { recursive: true, mode: 448 });
46548
- const temp = join24(options.tempDir, `${row.id}.part`);
46621
+ const temp = join25(options.tempDir, `${row.id}.part`);
46549
46622
  const writeDisk = async (impId) => {
46550
46623
  if (header.streams !== null) {
46551
46624
  await writeMoveStreams(deps, {
@@ -46760,7 +46833,7 @@ async function requireMoveTicket(db, request) {
46760
46833
  // packages/daemon/src/imp-ops/moves/move-receiver.ts
46761
46834
  var STREAM_WINDOW_MS = 10 * 60 * 1000;
46762
46835
  function createMoveReceiver(deps) {
46763
- const tempDir = join25(deps.dataDir, "moves");
46836
+ const tempDir = join26(deps.dataDir, "moves");
46764
46837
  const sessions = new Map;
46765
46838
  const writeTicketRow = async (name, bytes, fields, write = (row) => writeMoveTicket(deps.db, row)) => {
46766
46839
  const created = mintOpaqueToken(MOVE_TICKET_PREFIX);
@@ -47935,12 +48008,12 @@ function toPeerError2(procedure, error) {
47935
48008
  // packages/daemon/src/vm/storage/write-image-files.ts
47936
48009
  import { writeFileSync as writeFileSync6 } from "fs";
47937
48010
  import { copyFile } from "fs/promises";
47938
- import { join as join26 } from "path";
48011
+ import { join as join27 } from "path";
47939
48012
  async function writeImageFiles(files, directory) {
47940
- const rootfs = join26(directory, "rootfs.ext4");
48013
+ const rootfs = join27(directory, "rootfs.ext4");
47941
48014
  writeFileSync6(rootfs, "");
47942
48015
  await writeChangedBlocks(files.rootfsPath, rootfs);
47943
- await copyFile(files.configPath, join26(directory, "config.json"));
48016
+ await copyFile(files.configPath, join27(directory, "config.json"));
47944
48017
  }
47945
48018
 
47946
48019
  // packages/daemon/src/create-impd-moves.ts
@@ -47980,7 +48053,7 @@ function createImpdMoves(config, deps, parts, hooks) {
47980
48053
 
47981
48054
  // packages/daemon/src/imps/images/template-service.ts
47982
48055
  import { copyFileSync as copyFileSync3, existsSync as existsSync17, statSync as statSync11, writeFileSync as writeFileSync7 } from "fs";
47983
- import { join as join27 } from "path";
48056
+ import { join as join28 } from "path";
47984
48057
 
47985
48058
  // packages/daemon/src/imps/images/read-held-image.ts
47986
48059
  async function readHeldImage(db, name, at) {
@@ -48268,7 +48341,7 @@ function createTemplateService(deps) {
48268
48341
  });
48269
48342
  const writeConfig = async (imageId, directory) => {
48270
48343
  const image = await readImageById(deps.db, imageId);
48271
- const target = join27(directory, "config.json");
48344
+ const target = join28(directory, "config.json");
48272
48345
  const config = image === undefined ? undefined : buildImagePaths(deps.config.dataDir, image.digest).config;
48273
48346
  if (config !== undefined && existsSync17(config)) {
48274
48347
  copyFileSync3(config, target);
@@ -48656,7 +48729,7 @@ function createImpdServices(config, deps, parts) {
48656
48729
 
48657
48730
  // packages/daemon/src/imps/images/build/create-image-builds.ts
48658
48731
  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";
48732
+ import { join as join30, posix as posix3 } from "path";
48660
48733
 
48661
48734
  // packages/local-tar/src/extract-local.ts
48662
48735
  import tar from "tar-stream";
@@ -48664,7 +48737,7 @@ import * as z83 from "zod";
48664
48737
  // packages/local-tar/src/pack-build-context.ts
48665
48738
  import { existsSync as existsSync18 } from "fs";
48666
48739
  import { lstat, readFile as readFile4, readdir } from "fs/promises";
48667
- import { join as join28, posix as posix2 } from "path";
48740
+ import { join as join29, posix as posix2 } from "path";
48668
48741
  import ignore from "@balena/dockerignore";
48669
48742
 
48670
48743
  // packages/local-tar/src/write-build-context.ts
@@ -48948,7 +49021,7 @@ class MissingDockerfileError extends Error {
48948
49021
  name = "MissingDockerfileError";
48949
49022
  }
48950
49023
  function listContextEntries(root, dockerfile) {
48951
- const found = listDockerfileCandidates(posix2.normalize(dockerfile)).find((candidate) => existsSync18(join28(root, candidate)));
49024
+ const found = listDockerfileCandidates(posix2.normalize(dockerfile)).find((candidate) => existsSync18(join29(root, candidate)));
48952
49025
  if (found === undefined) {
48953
49026
  return Promise.reject(new MissingDockerfileError(`there is no ${dockerfile} in ${root}`));
48954
49027
  }
@@ -48960,8 +49033,8 @@ var ENTRY_KINDS = [
48960
49033
  ["file", "isFile"]
48961
49034
  ];
48962
49035
  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") : "";
49036
+ const ignoreName = existsSync18(join29(root, `${dockerfile}.dockerignore`)) ? `${dockerfile}.dockerignore` : ".dockerignore";
49037
+ const patterns = existsSync18(join29(root, ignoreName)) ? await readFile4(join29(root, ignoreName), "utf8") : "";
48965
49038
  const matcher = ignore().add(patterns);
48966
49039
  const hasExceptions = patterns.split(`
48967
49040
  `).some((line) => line.trim().startsWith("!"));
@@ -48971,7 +49044,7 @@ async function listEntries(root, dockerfile) {
48971
49044
  const entries = [];
48972
49045
  const children = await readdir(directory);
48973
49046
  for (const child of children.toSorted()) {
48974
- const path = join28(directory, child);
49047
+ const path = join29(directory, child);
48975
49048
  const name = prefix === "" ? child : `${prefix}/${child}`;
48976
49049
  const stats = await lstat(path);
48977
49050
  const ignored = matcher.ignores(name) && name !== dockerfileName;
@@ -50026,7 +50099,7 @@ function planRootfsOverhead(treeBytes) {
50026
50099
  }
50027
50100
 
50028
50101
  // packages/daemon/src/imps/images/rootfs/unpack-export.ts
50029
- import { readFileSync as readFileSync24 } from "fs";
50102
+ import { readFileSync as readFileSync25 } from "fs";
50030
50103
  var CAP_SETFCAP_BIT = 31n;
50031
50104
  var SETFCAP_HELP = "imp-host needs CAP_SETFCAP (docs/architecture/host.md#privileges)";
50032
50105
  var UNPACK_TAR_ARGS = [
@@ -50068,7 +50141,7 @@ function findXattrFailure(stderr) {
50068
50141
  });
50069
50142
  return failures.find((failure) => failure.missingSetfcap) ?? failures[0] ?? null;
50070
50143
  }
50071
- function readSetfcapWarning(status = readFileSync24("/proc/self/status", "utf8")) {
50144
+ function readSetfcapWarning(status = readFileSync25("/proc/self/status", "utf8")) {
50072
50145
  const effective = /^CapEff:\s*(?<mask>[0-9a-f]+)$/mu.exec(status)?.groups?.["mask"] ?? "0";
50073
50146
  if (BigInt(`0x${effective}`) >> CAP_SETFCAP_BIT & 1n) {
50074
50147
  return null;
@@ -50492,7 +50565,7 @@ function createImageBuilds(deps, writer) {
50492
50565
  });
50493
50566
  }
50494
50567
  const uploadsDir = buildUploadsDir(deps.config.dataDir);
50495
- const tarPath = join29(uploadsDir, `${Bun.randomUUIDv7()}.tar`);
50568
+ const tarPath = join30(uploadsDir, `${Bun.randomUUIDv7()}.tar`);
50496
50569
  mkdirSync20(uploadsDir, { recursive: true, mode: 448 });
50497
50570
  return deps.diskBudget.withRoom(tarBytes, async () => {
50498
50571
  try {
@@ -50649,7 +50722,7 @@ function buildImageRuntimeConfig(ociConfig) {
50649
50722
 
50650
50723
  // packages/daemon/src/imps/images/rootfs/create-image-writer.ts
50651
50724
  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";
50725
+ import { join as join32 } from "path";
50653
50726
 
50654
50727
  // packages/daemon/src/imps/images/rootfs/read-oci-config.ts
50655
50728
  import * as z88 from "zod";
@@ -50669,13 +50742,13 @@ async function readOciConfig(ref, signal, run) {
50669
50742
 
50670
50743
  // packages/daemon/src/imps/images/rootfs/write-image-config.ts
50671
50744
  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";
50745
+ import { join as join31 } from "path";
50673
50746
  function writeImageConfig(root, contents) {
50674
- const etc = join30(root, "etc");
50675
- const directory = join30(etc, "imp");
50747
+ const etc = join31(root, "etc");
50748
+ const directory = join31(etc, "imp");
50676
50749
  createDirectory(etc, "/etc");
50677
50750
  createDirectory(directory, "/etc/imp");
50678
- const file = join30(directory, "image.json");
50751
+ const file = join31(directory, "image.json");
50679
50752
  rmSync26(file, { recursive: true, force: true });
50680
50753
  const fd = openSync9(file, constants6.O_WRONLY | constants6.O_CREAT | constants6.O_EXCL | constants6.O_NOFOLLOW, 420);
50681
50754
  try {
@@ -50722,8 +50795,8 @@ function createImageWriter(deps) {
50722
50795
  const guestRootfsLock = buildKeyedMutex();
50723
50796
  const makeWorkDir = () => {
50724
50797
  const images = buildImagesDir(deps.config.dataDir);
50725
- const work = join31(images, `.build-${Bun.randomUUIDv7()}`);
50726
- const root = join31(work, "root");
50798
+ const work = join32(images, `.build-${Bun.randomUUIDv7()}`);
50799
+ const root = join32(work, "root");
50727
50800
  mkdirSync22(images, { recursive: true });
50728
50801
  mkdirSync22(work, { mode: 448 });
50729
50802
  mkdirSync22(root, { mode: 493 });
@@ -50734,7 +50807,7 @@ function createImageWriter(deps) {
50734
50807
  const usage = await readTreeUsage(root);
50735
50808
  const plan = planRootfs(usage);
50736
50809
  await deps.storage.createImage(digest, async (directory) => {
50737
- const image = join31(directory, "rootfs.ext4");
50810
+ const image = join32(directory, "rootfs.ext4");
50738
50811
  await runChecked(["truncate", "-s", String(plan.bytes), image]);
50739
50812
  await runChecked([
50740
50813
  "mkfs.ext4",
@@ -50747,7 +50820,7 @@ function createImageWriter(deps) {
50747
50820
  root,
50748
50821
  image
50749
50822
  ]);
50750
- writeFileSync8(join31(directory, "config.json"), JSON.stringify(ociConfig ?? {}, null, 2));
50823
+ writeFileSync8(join32(directory, "config.json"), JSON.stringify(ociConfig ?? {}, null, 2));
50751
50824
  });
50752
50825
  return readDiskUsage(buildImagePaths(deps.config.dataDir, digest).rootfs);
50753
50826
  };
@@ -51298,7 +51371,7 @@ async function runStreamed(argv, onStdout, signal) {
51298
51371
 
51299
51372
  // packages/daemon/src/vm/storage/count-tree-bytes.ts
51300
51373
  import { lstat as lstat3, readdir as readdir3 } from "fs/promises";
51301
- import { join as join32 } from "path";
51374
+ import { join as join33 } from "path";
51302
51375
  async function countTreeBytes(root, deps = {}) {
51303
51376
  const readDir = deps.readDir ?? readDirEntries;
51304
51377
  const inodes = new Map;
@@ -51307,11 +51380,11 @@ async function countTreeBytes(root, deps = {}) {
51307
51380
  const entries = await readEntries2(readDir, directory);
51308
51381
  for (const entry of entries) {
51309
51382
  if (entry.isDirectory()) {
51310
- dirs.push(join32(directory, entry.name));
51383
+ dirs.push(join33(directory, entry.name));
51311
51384
  }
51312
51385
  }
51313
51386
  const files = entries.filter((entry) => entry.isFile());
51314
- const stats = await Promise.all(files.map((entry) => readFileStats(join32(directory, entry.name))));
51387
+ const stats = await Promise.all(files.map((entry) => readFileStats(join33(directory, entry.name))));
51315
51388
  for (const stat of stats) {
51316
51389
  if (stat !== undefined) {
51317
51390
  inodes.set(`${String(stat.dev)}:${String(stat.ino)}`, Math.max(0, stat.blocks - 1) * 512);
@@ -51554,12 +51627,12 @@ function createTailnetAccess(config, deps, readStatus) {
51554
51627
  }
51555
51628
 
51556
51629
  // 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";
51630
+ import { existsSync as existsSync21, readFileSync as readFileSync26, writeFileSync as writeFileSync9 } from "fs";
51631
+ import { join as join34 } from "path";
51559
51632
  function loadOrCreateToken(dataDir) {
51560
- const path = join33(dataDir, "token");
51633
+ const path = join34(dataDir, "token");
51561
51634
  if (existsSync21(path)) {
51562
- return readFileSync25(path, "utf8").trim();
51635
+ return readFileSync26(path, "utf8").trim();
51563
51636
  }
51564
51637
  const token = mintSecret();
51565
51638
  writeFileSync9(path, `${token}
@@ -51681,13 +51754,13 @@ import { basename as basename4 } from "path";
51681
51754
 
51682
51755
  // packages/daemon/src/vm/storage/remove-unused-system-drives.ts
51683
51756
  import { readdirSync as readdirSync9, rmSync as rmSync28 } from "fs";
51684
- import { join as join34 } from "path";
51757
+ import { join as join35 } from "path";
51685
51758
  function removeUnusedSystemDrives(dataDir, keep) {
51686
51759
  const directory = buildSystemDrivesDir(dataDir);
51687
51760
  const removed = [];
51688
51761
  for (const name of readNames(directory)) {
51689
51762
  if (!keep.has(name)) {
51690
- rmSync28(join34(directory, name), { force: true });
51763
+ rmSync28(join35(directory, name), { force: true });
51691
51764
  removed.push(name);
51692
51765
  }
51693
51766
  }
@@ -52896,13 +52969,13 @@ function createPublicRecordsLink() {
52896
52969
 
52897
52970
  // packages/daemon/src/network/tailnet-names/host-id.ts
52898
52971
  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";
52972
+ import { existsSync as existsSync22, mkdirSync as mkdirSync23, readFileSync as readFileSync27, writeFileSync as writeFileSync10 } from "fs";
52973
+ import { join as join36 } from "path";
52901
52974
  function loadOrCreateHostId(dataDir) {
52902
- const directory = join35(dataDir, "tailnet-names");
52903
- const path = join35(directory, "host-id");
52975
+ const directory = join36(dataDir, "tailnet-names");
52976
+ const path = join36(directory, "host-id");
52904
52977
  if (existsSync22(path)) {
52905
- return readFileSync26(path, "utf8").trim();
52978
+ return readFileSync27(path, "utf8").trim();
52906
52979
  }
52907
52980
  mkdirSync23(directory, { recursive: true });
52908
52981
  const id = randomBytes11(16).toString("hex");
@@ -52912,7 +52985,7 @@ function loadOrCreateHostId(dataDir) {
52912
52985
  }
52913
52986
 
52914
52987
  // packages/daemon/src/network/tailnet-names/oauth-credential.ts
52915
- import { readFileSync as readFileSync27, statSync as statSync14 } from "fs";
52988
+ import { readFileSync as readFileSync28, statSync as statSync14 } from "fs";
52916
52989
  import * as z92 from "zod";
52917
52990
  var CredentialSchema = z92.object({ clientId: z92.string().min(1), clientSecret: z92.string().min(1) });
52918
52991
  function readOAuthCredential(path) {
@@ -52928,7 +53001,7 @@ function readOAuthCredential(path) {
52928
53001
  }
52929
53002
  function readJson(path) {
52930
53003
  try {
52931
- return JSON.parse(readFileSync27(path, "utf8"));
53004
+ return JSON.parse(readFileSync28(path, "utf8"));
52932
53005
  } catch {
52933
53006
  return null;
52934
53007
  }
@@ -53325,7 +53398,7 @@ async function startOtlpExport(env, version) {
53325
53398
  }
53326
53399
 
53327
53400
  // packages/daemon/src/network/https/wire-https-service.ts
53328
- import { readFileSync as readFileSync29 } from "fs";
53401
+ import { readFileSync as readFileSync30 } from "fs";
53329
53402
 
53330
53403
  // packages/daemon/src/platform/db/exposure.ts
53331
53404
  async function readPublicImp(db, name) {
@@ -53520,8 +53593,8 @@ function formatAcmeError(error) {
53520
53593
  }
53521
53594
 
53522
53595
  // 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";
53596
+ import { existsSync as existsSync23, mkdirSync as mkdirSync24, readFileSync as readFileSync29, rmSync as rmSync29 } from "fs";
53597
+ import { join as join37 } from "path";
53525
53598
  import * as z95 from "zod";
53526
53599
  var AttemptStateSchema = z95.object({
53527
53600
  failures: z95.int().nonnegative(),
@@ -53532,11 +53605,11 @@ var AccountSchema = z95.object({ directoryUrl: z95.string(), url: z95.string(),
53532
53605
  var LegacyAccountSchema = z95.object({ directoryUrl: z95.string(), url: z95.string() });
53533
53606
  var NO_ATTEMPTS = { failures: 0, lastAttemptAt: null, lastError: null };
53534
53607
  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");
53608
+ const directory = join37(dataDir, "tls");
53609
+ const certificatePath = join37(directory, "certificate.pem");
53610
+ const attemptsPath = join37(directory, "attempts.json");
53611
+ const accountPath = join37(directory, "account.json");
53612
+ const legacyKeyPath = join37(directory, "account.key");
53540
53613
  const warned = { account: false };
53541
53614
  const write = (path, content) => {
53542
53615
  mkdirSync24(directory, { recursive: true, mode: 448 });
@@ -53602,7 +53675,7 @@ ${certificate.chainPem.trimEnd()}
53602
53675
  };
53603
53676
  }
53604
53677
  function readIfExists(path) {
53605
- return existsSync23(path) ? readFileSync28(path, "utf8") : null;
53678
+ return existsSync23(path) ? readFileSync29(path, "utf8") : null;
53606
53679
  }
53607
53680
  function parseJson(text) {
53608
53681
  try {
@@ -54408,7 +54481,7 @@ function wireHttpsService(options) {
54408
54481
  const issue = createAcmeIssuer({
54409
54482
  directoryUrl: config.acmeDirectory,
54410
54483
  email: config.acmeEmail,
54411
- caPem: config.acmeCaFile === null ? null : readFileSync29(config.acmeCaFile, "utf8"),
54484
+ caPem: config.acmeCaFile === null ? null : readFileSync30(config.acmeCaFile, "utf8"),
54412
54485
  store,
54413
54486
  dns
54414
54487
  });
@@ -54995,17 +55068,17 @@ function buildTooMany() {
54995
55068
 
54996
55069
  // packages/daemon/src/surface/ssh/host-key.ts
54997
55070
  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";
55071
+ import { existsSync as existsSync24, mkdirSync as mkdirSync25, readFileSync as readFileSync31, writeFileSync as writeFileSync11 } from "fs";
55072
+ import { join as join38 } from "path";
55000
55073
  function setupSshDir(dataDir) {
55001
- const directory = join37(dataDir, "ssh");
55074
+ const directory = join38(dataDir, "ssh");
55002
55075
  mkdirSync25(directory, { recursive: true, mode: 448 });
55003
55076
  return directory;
55004
55077
  }
55005
55078
  function loadOrCreateHostKey(sshDir) {
55006
- const path = join37(sshDir, "host_key");
55079
+ const path = join38(sshDir, "host_key");
55007
55080
  if (existsSync24(path)) {
55008
- return readFileSync30(path, "utf8");
55081
+ return readFileSync31(path, "utf8");
55009
55082
  }
55010
55083
  const pair = generateEd25519Key();
55011
55084
  writeFileSync11(path, pair.private, { mode: 384, flag: "wx" });
@@ -56170,8 +56243,8 @@ async function stopImpd(parts, options) {
56170
56243
  }
56171
56244
 
56172
56245
  // 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";
56246
+ import { existsSync as existsSync31, readFileSync as readFileSync35, readdirSync as readdirSync14, writeFileSync as writeFileSync14 } from "fs";
56247
+ import { join as join47 } from "path";
56175
56248
 
56176
56249
  // packages/daemon/src/vm/storage/xfs-backend.ts
56177
56250
  import {
@@ -56184,7 +56257,7 @@ import {
56184
56257
  statfsSync as statfsSync2,
56185
56258
  writeFileSync as writeFileSync12
56186
56259
  } from "fs";
56187
- import { basename as basename6, dirname as dirname13, join as join41 } from "path";
56260
+ import { basename as basename6, dirname as dirname13, join as join42 } from "path";
56188
56261
 
56189
56262
  // packages/daemon/src/vm/storage/count-owner-bytes.ts
56190
56263
  function countOwnerBytes(files) {
@@ -56241,13 +56314,13 @@ import {
56241
56314
  copyFileSync as copyFileSync4,
56242
56315
  existsSync as existsSync25,
56243
56316
  mkdirSync as mkdirSync26,
56244
- readFileSync as readFileSync31,
56317
+ readFileSync as readFileSync32,
56245
56318
  readdirSync as readdirSync10,
56246
56319
  renameSync as renameSync6,
56247
56320
  rmSync as rmSync30,
56248
56321
  statSync as statSync15
56249
56322
  } from "fs";
56250
- import { basename as basename5, dirname as dirname11, join as join38 } from "path";
56323
+ import { basename as basename5, dirname as dirname11, join as join39 } from "path";
56251
56324
  import * as z97 from "zod";
56252
56325
  var CopiesSchema = z97.record(z97.string(), z97.object({ ino: z97.string(), ctimeNs: z97.string(), size: z97.string() }));
56253
56326
  function createXfsBackups(ctx) {
@@ -56255,7 +56328,7 @@ function createXfsBackups(ctx) {
56255
56328
  const freshCopies = new Set;
56256
56329
  const readCopies = () => {
56257
56330
  try {
56258
- return CopiesSchema.parse(JSON.parse(readFileSync31(backup.copies, "utf8")));
56331
+ return CopiesSchema.parse(JSON.parse(readFileSync32(backup.copies, "utf8")));
56259
56332
  } catch {
56260
56333
  return {};
56261
56334
  }
@@ -56278,7 +56351,7 @@ function createXfsBackups(ctx) {
56278
56351
  return {
56279
56352
  createBackupCopy: async (impId, _runId, options) => {
56280
56353
  const source = ctx.resolveImpPaths(impId).disk;
56281
- const target = join38(backup.tree, BACKUP_TREE.buildDisk(impId));
56354
+ const target = join39(backup.tree, BACKUP_TREE.buildDisk(impId));
56282
56355
  const stats = statSync15(source, { bigint: true });
56283
56356
  const record = {
56284
56357
  ino: String(stats.ino),
@@ -56306,34 +56379,34 @@ function createXfsBackups(ctx) {
56306
56379
  const checkpointIds = new Set;
56307
56380
  const imageDigests = new Set;
56308
56381
  for (const imp of request.imps) {
56309
- if (!existsSync25(join38(backup.tree, BACKUP_TREE.buildDisk(imp.impId)))) {
56382
+ if (!existsSync25(join39(backup.tree, BACKUP_TREE.buildDisk(imp.impId)))) {
56310
56383
  continue;
56311
56384
  }
56312
56385
  impIds.add(imp.impId);
56313
56386
  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)));
56387
+ const isCopied = await createTreeClone(ctx.buildCheckpointDisk(imp.impId, checkpointId), join39(backup.tree, BACKUP_TREE.buildCheckpointDisk(imp.impId, checkpointId)));
56315
56388
  if (isCopied) {
56316
56389
  checkpointIds.add(checkpointId);
56317
56390
  }
56318
56391
  }
56319
- removeUnlisted(join38(backup.tree, BACKUP_TREE.buildImpDir(imp.impId), "checkpoints"), new Set(imp.checkpointIds.filter((id) => checkpointIds.has(id))));
56392
+ removeUnlisted(join39(backup.tree, BACKUP_TREE.buildImpDir(imp.impId), "checkpoints"), new Set(imp.checkpointIds.filter((id) => checkpointIds.has(id))));
56320
56393
  }
56321
56394
  for (const digest of request.imageDigests) {
56322
56395
  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"));
56396
+ const directory = join39(backup.tree, BACKUP_TREE.buildImageDir(digest));
56397
+ const isCopied = await createTreeClone(source.rootfs, join39(directory, "rootfs.ext4"));
56325
56398
  if (isCopied) {
56326
- copyFileSync4(source.config, join38(directory, "config.json"));
56399
+ copyFileSync4(source.config, join39(directory, "config.json"));
56327
56400
  imageDigests.add(digest);
56328
56401
  }
56329
56402
  }
56330
- removeUnlisted(join38(backup.tree, "imps"), impIds);
56331
- removeUnlisted(join38(backup.tree, "images"), new Set([...imageDigests].map((digest) => basename5(BACKUP_TREE.buildImageDir(digest)))));
56403
+ removeUnlisted(join39(backup.tree, "imps"), impIds);
56404
+ removeUnlisted(join39(backup.tree, "images"), new Set([...imageDigests].map((digest) => basename5(BACKUP_TREE.buildImageDir(digest)))));
56332
56405
  const copies = readCopies();
56333
56406
  writeCopies(Object.fromEntries(Object.entries(copies).filter(([id]) => impIds.has(id))));
56334
56407
  const removeFreshCopies = () => {
56335
56408
  for (const impId of freshCopies) {
56336
- rmSync30(join38(backup.tree, BACKUP_TREE.buildDisk(impId)), { force: true });
56409
+ rmSync30(join39(backup.tree, BACKUP_TREE.buildDisk(impId)), { force: true });
56337
56410
  }
56338
56411
  freshCopies.clear();
56339
56412
  return Promise.resolve();
@@ -56345,18 +56418,18 @@ function createXfsBackups(ctx) {
56345
56418
  function removeUnlisted(directory, keep) {
56346
56419
  const names = existsSync25(directory) ? readdirSync10(directory) : [];
56347
56420
  for (const name of names.filter((entry) => !keep.has(entry))) {
56348
- rmSync30(join38(directory, name), { recursive: true, force: true });
56421
+ rmSync30(join39(directory, name), { recursive: true, force: true });
56349
56422
  }
56350
56423
  }
56351
56424
 
56352
56425
  // 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";
56426
+ import { readFileSync as readFileSync33, realpathSync, statfsSync } from "fs";
56427
+ import { dirname as dirname12, join as join40 } from "path";
56355
56428
  var HOST_DIRS = { procDir: "/proc", sysDir: "/sys" };
56356
56429
  function readLoopBackingFile(directory, hostDirs = HOST_DIRS) {
56357
56430
  try {
56358
56431
  const target = realpathSync(directory);
56359
- const mountInfo = readFileSync32(join39(hostDirs.procDir, "self", "mountinfo"), "utf8");
56432
+ const mountInfo = readFileSync33(join40(hostDirs.procDir, "self", "mountinfo"), "utf8");
56360
56433
  for (const line of mountInfo.split(`
56361
56434
  `)) {
56362
56435
  const [mounts = "", fields = ""] = line.split(" - ");
@@ -56364,8 +56437,8 @@ function readLoopBackingFile(directory, hostDirs = HOST_DIRS) {
56364
56437
  const [, source = ""] = fields.split(" ");
56365
56438
  const loop = /^\/dev\/(?<name>loop\d+)$/u.exec(source)?.groups?.["name"];
56366
56439
  if (mountPoint === target && loop !== undefined) {
56367
- const backing = join39(hostDirs.sysDir, "block", loop, "loop", "backing_file");
56368
- return readFileSync32(backing, "utf8").trim();
56440
+ const backing = join40(hostDirs.sysDir, "block", loop, "loop", "backing_file");
56441
+ return readFileSync33(backing, "utf8").trim();
56369
56442
  }
56370
56443
  }
56371
56444
  } catch {}
@@ -56386,7 +56459,7 @@ function readLoopHostFreeBytes(directory, hostDirs = HOST_DIRS) {
56386
56459
 
56387
56460
  // packages/daemon/src/vm/storage/orphan-files.ts
56388
56461
  import { existsSync as existsSync26, readdirSync as readdirSync11, statSync as statSync16 } from "fs";
56389
- import { join as join40 } from "path";
56462
+ import { join as join41 } from "path";
56390
56463
  function probeHoldingFiles(directory) {
56391
56464
  return existsSync26(directory) && readdirSync11(directory, { recursive: true, withFileTypes: true }).some((entry) => !entry.isDirectory());
56392
56465
  }
@@ -56394,7 +56467,7 @@ function listFilesUnder(directory) {
56394
56467
  if (!existsSync26(directory)) {
56395
56468
  return [];
56396
56469
  }
56397
- return readdirSync11(directory, { recursive: true, withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => join40(entry.parentPath, entry.name));
56470
+ return readdirSync11(directory, { recursive: true, withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => join41(entry.parentPath, entry.name));
56398
56471
  }
56399
56472
  function readDirectoryOrphan(kind, id, directory, snapshots) {
56400
56473
  const birth = statSync16(directory).birthtimeMs;
@@ -56420,7 +56493,7 @@ function createXfsBackend(deps) {
56420
56493
  const cloneFile = deps.cloneFile ?? createReflinkClone;
56421
56494
  const readFileExtents = deps.readFileExtents ?? readExtents;
56422
56495
  const resolveImpPaths = (impId) => buildImpPaths(deps.dataDir, impId);
56423
- const buildCheckpointDisk = (impId, checkpointId) => join41(resolveImpPaths(impId).checkpointsDir, checkpointId, "disk.ext4");
56496
+ const buildCheckpointDisk = (impId, checkpointId) => join42(resolveImpPaths(impId).checkpointsDir, checkpointId, "disk.ext4");
56424
56497
  const getSourceFile = (source) => {
56425
56498
  if (source.kind === "image") {
56426
56499
  return buildImagePaths(deps.dataDir, source.digest).rootfs;
@@ -56435,7 +56508,7 @@ function createXfsBackend(deps) {
56435
56508
  };
56436
56509
  const createImage = async (digest, write) => {
56437
56510
  const paths = buildImagePaths(deps.dataDir, digest);
56438
- const staged = join41(buildImagesDir(deps.dataDir), `${STAGING_PREFIX}${Bun.randomUUIDv7()}`);
56511
+ const staged = join42(buildImagesDir(deps.dataDir), `${STAGING_PREFIX}${Bun.randomUUIDv7()}`);
56439
56512
  mkdirSync27(staged, { recursive: true });
56440
56513
  try {
56441
56514
  await write(staged);
@@ -56456,13 +56529,13 @@ function createXfsBackend(deps) {
56456
56529
  return listEntries2(directory).map((id) => ({
56457
56530
  kind: "checkpoint",
56458
56531
  id,
56459
- directory: join41(directory, id)
56532
+ directory: join42(directory, id)
56460
56533
  }));
56461
56534
  }).filter((checkpoint) => !live.checkpointIds.has(checkpoint.id));
56462
56535
  const unknownImages = listEntries2(buildImagesDir(deps.dataDir)).filter((name) => !name.startsWith(".") && !liveDigests.has(name)).map((name) => ({
56463
56536
  kind: "image",
56464
56537
  id: name,
56465
- directory: join41(buildImagesDir(deps.dataDir), name)
56538
+ directory: join42(buildImagesDir(deps.dataDir), name)
56466
56539
  }));
56467
56540
  const unknownImps = impIds.filter((impId) => !live.impIds.has(impId)).map((impId) => ({
56468
56541
  kind: "imp",
@@ -56482,14 +56555,14 @@ function createXfsBackend(deps) {
56482
56555
  };
56483
56556
  const removeLeftover = (dropped, live) => {
56484
56557
  if (dropped.kind === "image") {
56485
- rmSync31(join41(buildImagesDir(deps.dataDir), dropped.id), { recursive: true, force: true });
56558
+ rmSync31(join42(buildImagesDir(deps.dataDir), dropped.id), { recursive: true, force: true });
56486
56559
  }
56487
56560
  if (dropped.kind === "imp") {
56488
56561
  rmSync31(resolveImpPaths(dropped.id).directory, { recursive: true, force: true });
56489
56562
  }
56490
56563
  if (dropped.kind === "checkpoint") {
56491
56564
  for (const impId of live.impIds) {
56492
- rmSync31(join41(resolveImpPaths(impId).checkpointsDir, dropped.id), {
56565
+ rmSync31(join42(resolveImpPaths(impId).checkpointsDir, dropped.id), {
56493
56566
  recursive: true,
56494
56567
  force: true
56495
56568
  });
@@ -56504,7 +56577,7 @@ function createXfsBackend(deps) {
56504
56577
  const listOtherFiles = () => {
56505
56578
  const images = listEntries2(buildImagesDir(deps.dataDir)).filter((name) => !name.startsWith(".")).map((name) => ({
56506
56579
  owner: `image:${name}`,
56507
- path: join41(buildImagesDir(deps.dataDir), name, "rootfs.ext4")
56580
+ path: join42(buildImagesDir(deps.dataDir), name, "rootfs.ext4")
56508
56581
  }));
56509
56582
  const tree = listFilesUnder(backup.tree).map((path) => ({ owner: "backup", path }));
56510
56583
  return [...images, ...tree].filter((file) => existsSync27(file.path));
@@ -56512,7 +56585,7 @@ function createXfsBackend(deps) {
56512
56585
  const usageState = { resumeImpId: null };
56513
56586
  const setupReserveFile = async () => {
56514
56587
  const bytes = deps.reserveFileBytes ?? 0;
56515
- const file = join41(deps.dataDir, "reserve");
56588
+ const file = join42(deps.dataDir, "reserve");
56516
56589
  if (bytes === 0 || existsSync27(file)) {
56517
56590
  return;
56518
56591
  }
@@ -56542,7 +56615,7 @@ function createXfsBackend(deps) {
56542
56615
  start: (live) => {
56543
56616
  const imagesDir = buildImagesDir(deps.dataDir);
56544
56617
  for (const name of listEntries2(imagesDir).filter((entry) => entry.startsWith("."))) {
56545
- rmSync31(join41(imagesDir, name), { recursive: true, force: true });
56618
+ rmSync31(join42(imagesDir, name), { recursive: true, force: true });
56546
56619
  }
56547
56620
  const swept = removeUnnamed(live, { isDryRun: false, isOrphans: false });
56548
56621
  printSweep(getImpdLogger("storage"), swept, "each");
@@ -56564,7 +56637,7 @@ function createXfsBackend(deps) {
56564
56637
  receiveMoveSnapshots: () => Promise.reject(new Error("xfs: only a ZFS host receives ZFS streams")),
56565
56638
  createImage,
56566
56639
  createImageFromImp: (digest, impId, steps) => createImage(digest, async (directory) => {
56567
- await steps.hold(() => cloneFile(resolveImpPaths(impId).disk, join41(directory, "rootfs.ext4")));
56640
+ await steps.hold(() => cloneFile(resolveImpPaths(impId).disk, join42(directory, "rootfs.ext4")));
56568
56641
  await steps.write(directory);
56569
56642
  }),
56570
56643
  removeImage: (digest) => {
@@ -56706,8 +56779,8 @@ function isSharedExtent(extent) {
56706
56779
  }
56707
56780
 
56708
56781
  // 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";
56782
+ import { existsSync as existsSync30, mkdirSync as mkdirSync28, readFileSync as readFileSync34, rmdirSync as rmdirSync3, writeFileSync as writeFileSync13 } from "fs";
56783
+ import { join as join46 } from "path";
56711
56784
 
56712
56785
  // packages/daemon/src/platform/process/run-stream.ts
56713
56786
  function createStreamRunner() {
@@ -56996,7 +57069,7 @@ function formatUiomoveWarning(version) {
56996
57069
 
56997
57070
  // packages/daemon/src/vm/storage/zfs/create-zfs-backups.ts
56998
57071
  import { rmSync as rmSync32 } from "fs";
56999
- import { dirname as dirname14, join as join42 } from "path";
57072
+ import { dirname as dirname14, join as join43 } from "path";
57000
57073
  function createZfsBackups(ctx) {
57001
57074
  return {
57002
57075
  createBackupCopy: (impId, runId) => ctx.runSnapshot(() => ctx.zfs.snapshot(`${ctx.buildDiskName(impId)}@bk-${runId}-${impId}`)),
@@ -57023,7 +57096,7 @@ function createZfsBackups(ctx) {
57023
57096
  ctx.startReclaim();
57024
57097
  };
57025
57098
  const createTreeClone = async (snapshot, name, relativeDir) => {
57026
- const directory = join42(tree, relativeDir);
57099
+ const directory = join43(tree, relativeDir);
57027
57100
  await ctx.zfs.clone(snapshot, name, { readonly: "on" });
57028
57101
  clones.push({ name, directory });
57029
57102
  await ctx.setupMount(name, directory, true);
@@ -57033,8 +57106,8 @@ function createZfsBackups(ctx) {
57033
57106
  if (mounted !== undefined) {
57034
57107
  throw new Error(`zfs: ${mounted} in the backup tree is still mounted`);
57035
57108
  }
57036
- rmSync32(join42(tree, "imps"), { recursive: true, force: true });
57037
- rmSync32(join42(tree, "images"), { recursive: true, force: true });
57109
+ rmSync32(join43(tree, "imps"), { recursive: true, force: true });
57110
+ rmSync32(join43(tree, "images"), { recursive: true, force: true });
57038
57111
  const entries = await ctx.listAll();
57039
57112
  for (const imp of request.imps) {
57040
57113
  const copy = entries.find((entry) => entry.type === "snapshot" && entry.name.endsWith(`@bk-${request.runId}-${imp.impId}`));
@@ -57167,7 +57240,7 @@ function createZfsCheckpoints(ctx) {
57167
57240
  }
57168
57241
 
57169
57242
  // packages/daemon/src/vm/storage/zfs/create-zfs-moves.ts
57170
- import { join as join43 } from "path";
57243
+ import { join as join44 } from "path";
57171
57244
  function createZfsMoves(ctx) {
57172
57245
  const openMoveFiles = async (snapshots, removeMoveSnapshot) => {
57173
57246
  const moveId = Bun.randomUUIDv7();
@@ -57196,7 +57269,7 @@ function createZfsMoves(ctx) {
57196
57269
  await removeClones();
57197
57270
  throw error;
57198
57271
  }
57199
- const paths = clones.map((clone) => join43(clone.directory, ctx.rootfsFile));
57272
+ const paths = clones.map((clone) => join44(clone.directory, ctx.rootfsFile));
57200
57273
  return {
57201
57274
  kind: "files",
57202
57275
  checkpointPaths: paths.slice(0, -1),
@@ -57452,7 +57525,7 @@ function createZfsReclaim(ctx) {
57452
57525
 
57453
57526
  // packages/daemon/src/vm/storage/zfs/create-zfs-sweep.ts
57454
57527
  import { existsSync as existsSync28, readdirSync as readdirSync13, rmSync as rmSync33 } from "fs";
57455
- import { join as join44 } from "path";
57528
+ import { join as join45 } from "path";
57456
57529
  var FORK_SNAPSHOT = /@fork-[^@]+$/u;
57457
57530
  var BACKUP_SNAPSHOT = /@bk-[^@]+$/u;
57458
57531
  var MOVE_SNAPSHOT = /@mv-[^@]+$/u;
@@ -57477,10 +57550,10 @@ function createZfsSweep(ctx) {
57477
57550
  const orphanCheckpoints = isOrphans ? [] : unmarked.filter((entry) => !isOnOrphan(entry) && isOrphanCheckpoint(entry));
57478
57551
  const keptDisks = isOrphans ? [] : unknownDisks;
57479
57552
  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) }));
57553
+ 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
57554
  const unknownDirs = [
57482
57555
  ...listUnknownDirs("imp", buildImpsDir(ctx.dataDir)),
57483
- ...listUnknownDirs("memory", join44(ctx.dataDir, "mem"))
57556
+ ...listUnknownDirs("memory", join45(ctx.dataDir, "mem"))
57484
57557
  ];
57485
57558
  const probeDirDropped = (entry) => isOrphans || !probeHoldingFiles(entry.directory);
57486
57559
  const droppedDirs = unknownDirs.filter((entry) => probeDirDropped(entry));
@@ -57569,7 +57642,7 @@ function createZfsSweep(ctx) {
57569
57642
  }
57570
57643
  }
57571
57644
  for (const impId of plan.memDirs) {
57572
- rmSync33(join44(ctx.dataDir, "mem", impId), { recursive: true, force: true });
57645
+ rmSync33(join45(ctx.dataDir, "mem", impId), { recursive: true, force: true });
57573
57646
  }
57574
57647
  return { dropped: toDropped(plan), kept };
57575
57648
  };
@@ -57657,13 +57730,13 @@ function createZfsBackend(deps) {
57657
57730
  const buildDiskName = (impId) => `${datasets.disks}/${impId}`;
57658
57731
  const buildImageName = (digest) => `${datasets.images}/${toDigestHex(digest)}`;
57659
57732
  const buildRestoreName = (impId) => `${datasets.staging}/restore-${impId}`;
57660
- const buildDiskDir = (impId) => join45(buildImpPaths(deps.dataDir, impId).directory, "disk");
57733
+ const buildDiskDir = (impId) => join46(buildImpPaths(deps.dataDir, impId).directory, "disk");
57661
57734
  const buildImageDir = (digest) => buildImagePaths(deps.dataDir, digest).directory;
57662
- const buildStagingDir = (name) => join45(deps.dataDir, "staging", name.slice(datasets.staging.length + 1));
57735
+ const buildStagingDir = (name) => join46(deps.dataDir, "staging", name.slice(datasets.staging.length + 1));
57663
57736
  const resolveImpPaths = (impId) => ({
57664
57737
  ...buildImpPaths(deps.dataDir, impId),
57665
- disk: join45(buildDiskDir(impId), ROOTFS_FILE),
57666
- ...buildSnapshotPaths(join45(deps.dataDir, "mem", impId))
57738
+ disk: join46(buildDiskDir(impId), ROOTFS_FILE),
57739
+ ...buildSnapshotPaths(join46(deps.dataDir, "mem", impId))
57667
57740
  });
57668
57741
  const listAll = () => zfs.list(deps.root);
57669
57742
  const setupMount = async (name, directory, isReadOnly = false) => {
@@ -57806,7 +57879,7 @@ function createZfsBackend(deps) {
57806
57879
  throw new Error(`zfs: ${deps.root} is not mounted on ${deps.dataDir} (host/scripts/setup-storage.sh mounts it)`);
57807
57880
  }
57808
57881
  await createMissingDatasets();
57809
- await setupMount(datasets.mem, join45(deps.dataDir, "mem"));
57882
+ await setupMount(datasets.mem, join46(deps.dataDir, "mem"));
57810
57883
  await resolveStaging();
57811
57884
  const swept = await sweep.removeLeftovers(live, { isDryRun: false, isOrphans: false });
57812
57885
  printSweep(getImpdLogger("storage"), swept, "each");
@@ -57891,7 +57964,7 @@ function createZfsBackend(deps) {
57891
57964
  await zfs.create(target);
57892
57965
  await setupMount(target, buildDiskDir(impId));
57893
57966
  });
57894
- writeFileSync13(join45(buildDiskDir(impId), ROOTFS_FILE), "");
57967
+ writeFileSync13(join46(buildDiskDir(impId), ROOTFS_FILE), "");
57895
57968
  return;
57896
57969
  }
57897
57970
  await runSerial(async () => {
@@ -57968,7 +58041,7 @@ function createZfsBackend(deps) {
57968
58041
  }
57969
58042
  function readZfsModuleVersion() {
57970
58043
  try {
57971
- return readFileSync33("/sys/module/zfs/version", "utf8").trim();
58044
+ return readFileSync34("/sys/module/zfs/version", "utf8").trim();
57972
58045
  } catch {
57973
58046
  return null;
57974
58047
  }
@@ -58011,14 +58084,14 @@ function createBackend(config, boundaries) {
58011
58084
  });
58012
58085
  }
58013
58086
  function checkStorageMarker(dataDir, kind) {
58014
- const marker = join46(dataDir, MARKER_FILE);
58015
- const recorded = existsSync31(marker) ? readFileSync34(marker, "utf8").trim() : readUnmarked(dataDir);
58087
+ const marker = join47(dataDir, MARKER_FILE);
58088
+ const recorded = existsSync31(marker) ? readFileSync35(marker, "utf8").trim() : readUnmarked(dataDir);
58016
58089
  if (recorded !== null && recorded !== kind) {
58017
58090
  throw new Error(`${dataDir} holds ${recorded} storage, but IMP_STORAGE_BACKEND is ${kind}; moving imps between backends is not supported`);
58018
58091
  }
58019
58092
  }
58020
58093
  function writeStorageMarker(dataDir, kind) {
58021
- const marker = join46(dataDir, MARKER_FILE);
58094
+ const marker = join47(dataDir, MARKER_FILE);
58022
58095
  if (!existsSync31(marker)) {
58023
58096
  writeFileSync14(marker, `${kind}
58024
58097
  `);
@@ -58031,7 +58104,7 @@ function readUnmarked(dataDir) {
58031
58104
  }
58032
58105
 
58033
58106
  // packages/daemon/src/vm/storage/setup-system-files.ts
58034
- import { existsSync as existsSync32, mkdirSync as mkdirSync29, readFileSync as readFileSync35 } from "fs";
58107
+ import { existsSync as existsSync32, mkdirSync as mkdirSync29, readFileSync as readFileSync36 } from "fs";
58035
58108
  import { dirname as dirname15 } from "path";
58036
58109
 
58037
58110
  // packages/daemon/src/vm/storage/system-file-info.ts
@@ -58067,7 +58140,7 @@ async function setupSystemFiles(config) {
58067
58140
  const missing = config.kernelSource === null ? " and no source is configured" : "";
58068
58141
  throw new Error(`${kernelSource} does not exist${missing}`);
58069
58142
  }
58070
- const kernel = readFileSync35(kernelSource);
58143
+ const kernel = readFileSync36(kernelSource);
58071
58144
  const guestKernel = readKernelInfo(kernel);
58072
58145
  if (config.kernelSource !== null && !probeContent(config.kernelPath, kernel)) {
58073
58146
  writeCopy(config.kernelSource, config.kernelPath);
@@ -58087,7 +58160,7 @@ async function setupSystemFiles(config) {
58087
58160
  };
58088
58161
  }
58089
58162
  function probeContent(path, content) {
58090
- return existsSync32(path) && Buffer.from(content).equals(readFileSync35(path));
58163
+ return existsSync32(path) && Buffer.from(content).equals(readFileSync36(path));
58091
58164
  }
58092
58165
  function writeCopy(source, target) {
58093
58166
  mkdirSync29(dirname15(target), { recursive: true });
@@ -58139,7 +58212,7 @@ async function startImpdParts(config, boundaries, plan) {
58139
58212
  }
58140
58213
  return files;
58141
58214
  });
58142
- const db = await runStep("database", () => boundaries.db ?? openDatabase(join47(config.dataDir, "db", "imp.sqlite")));
58215
+ const db = await runStep("database", () => boundaries.db ?? openDatabase(join48(config.dataDir, "db", "imp.sqlite")));
58143
58216
  plan.db = boundaries.db === undefined ? db : null;
58144
58217
  const kernelOops = boundaries.imps?.kernelOops ?? createKernelOopsWatch();
58145
58218
  const storage = boundaries.storage ?? createStorageBackend(config, { zfs: { isKernelOopsed: kernelOops.isOopsed } });
@@ -58246,7 +58319,7 @@ async function startImpdParts(config, boundaries, plan) {
58246
58319
  secretFiles
58247
58320
  });
58248
58321
  const state = { ready: false };
58249
- const authorizedKeys = createAuthorizedKeys(join47(setupSshDir(config.dataDir), "authorized_keys"));
58322
+ const authorizedKeys = createAuthorizedKeys(join48(setupSshDir(config.dataDir), "authorized_keys"));
58250
58323
  const access = await runStep("access", () => loadImpdAccess(config, deps, authorizedKeys.probeListed));
58251
58324
  const backups = config.backup === null ? null : createBackupService({
58252
58325
  dataDir: config.dataDir,
@@ -58312,7 +58385,7 @@ async function startImpdParts(config, boundaries, plan) {
58312
58385
  readTailnetNames: tailnetNames === null ? null : tailnetNames.readStatus,
58313
58386
  hostReaders: {
58314
58387
  readKernel: () => deps.hostKernelRelease ?? release2(),
58315
- readCpuInfo: deps.readCpuInfo ?? (() => readFileSync36("/proc/cpuinfo", "utf8")),
58388
+ readCpuInfo: deps.readCpuInfo ?? (() => readFileSync37("/proc/cpuinfo", "utf8")),
58316
58389
  readHugePagePool: deps.imps?.readHugePagePool ?? (() => readHugePagePool())
58317
58390
  },
58318
58391
  isReady: () => state.ready,
@@ -58431,6 +58504,11 @@ function buildStubTickerTimer() {
58431
58504
  };
58432
58505
  }
58433
58506
 
58507
+ // packages/daemon/testing/platform/format-run-prefix.ts
58508
+ function formatRunPrefix(owner) {
58509
+ return `pid${String(owner.pid)}-ns${owner.namespace}-`;
58510
+ }
58511
+
58434
58512
  // packages/daemon/testing/platform/open-migrated-copy.ts
58435
58513
  import { Database as Database4 } from "bun:sqlite";
58436
58514
  var TEMPLATE = {};
@@ -58453,6 +58531,15 @@ function pickImpdPort(draw) {
58453
58531
  return FIRST_PORT + Math.floor(draw * PORT_SPAN);
58454
58532
  }
58455
58533
 
58534
+ // packages/daemon/testing/platform/read-run-owner.ts
58535
+ import { readlinkSync as readlinkSync2 } from "fs";
58536
+ function readRunOwner() {
58537
+ return {
58538
+ pid: process.pid,
58539
+ namespace: readlinkSync2("/proc/self/ns/pid").replaceAll(/\D/gu, "")
58540
+ };
58541
+ }
58542
+
58456
58543
  // packages/daemon/testing/platform/start-impd-log-capture.ts
58457
58544
  import { resetSync } from "@logtape/logtape";
58458
58545
 
@@ -58918,7 +59005,7 @@ var NO_FREEZER = { freeze: () => Promise.resolve(), thaw: () => Promise.resolve(
58918
59005
  var KSM_KERNEL = "6.12.0";
58919
59006
  var IDLE_KSM = { running: true, sharedMib: 0, profitMib: 0, zeroMib: 0 };
58920
59007
  async function startTestImpd(stack, options = {}) {
58921
- const dataDir = options.dataDir ?? mkdtempSync(`${tmpdir()}/impd-test-`);
59008
+ const dataDir = options.dataDir ?? mkdtempSync(`${tmpdir()}/${formatRunPrefix(readRunOwner())}impd-test-`);
58922
59009
  if (options.dataDir === undefined) {
58923
59010
  stack.defer(() => rm2(dataDir, { recursive: true, force: true }));
58924
59011
  }
@@ -58989,6 +59076,7 @@ async function startTestImpd(stack, options = {}) {
58989
59076
  });
58990
59077
  const cgroups = options.cgroups ?? createCpuCgroups({ root: "/nonexistent" });
58991
59078
  const extra = options.boundaries ?? {};
59079
+ const procRoot = options.procRoot;
58992
59080
  const buildBoundaries = (identity, runner, storage) => {
58993
59081
  const jails = options.jails;
58994
59082
  return {
@@ -59088,6 +59176,9 @@ async function startTestImpd(stack, options = {}) {
59088
59176
  hostCpus: options.hostCpus ?? 8,
59089
59177
  kernelOops,
59090
59178
  readThreadIds: (pid) => options.procRoot === undefined ? null : readThreadIds(pid, options.procRoot),
59179
+ ...procRoot !== undefined && {
59180
+ readHostLoad: () => readHostLoad({ procRoot, readFile: readText, logger: getImpdLogger("imps") })
59181
+ },
59091
59182
  ...options.readUnsharedRamMib !== undefined && {
59092
59183
  readUnsharedRamMib: options.readUnsharedRamMib
59093
59184
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@impz/testing",
3
- "version": "6.4.2",
3
+ "version": "6.5.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.5.0"
47
47
  },
48
48
  "engines": {
49
49
  "bun": ">=1.4.3"