@impz/testing 6.8.1 → 6.9.1

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 +383 -208
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -18924,7 +18924,7 @@ var BACKUP_TREE = {
18924
18924
  };
18925
18925
 
18926
18926
  // packages/daemon/src/test-utils/start-test-impd.ts
18927
- import { copyFileSync as copyFileSync5, mkdirSync as mkdirSync31, mkdtempSync, writeFileSync as writeFileSync16 } from "fs";
18927
+ import { copyFileSync as copyFileSync5, mkdirSync as mkdirSync31, mkdtempSync, writeFileSync as writeFileSync17 } from "fs";
18928
18928
  import { rm as rm2 } from "fs/promises";
18929
18929
  import { tmpdir } from "os";
18930
18930
 
@@ -18994,7 +18994,7 @@ function readBusyPorts() {
18994
18994
  // packages/daemon/src/test-utils/start-test-impd.ts
18995
18995
  import { createORPCClient as createORPCClient2 } from "@orpc/client";
18996
18996
  import { RPCLink } from "@orpc/client/fetch";
18997
- import invariant7 from "tiny-invariant";
18997
+ import invariant8 from "tiny-invariant";
18998
18998
 
18999
18999
  // packages/daemon/src/config.ts
19000
19000
  import { join as join4 } from "path";
@@ -20210,6 +20210,7 @@ var SystemInfoSchema = z33.object({
20210
20210
  ramCommittedMib: z33.int().nonnegative(),
20211
20211
  ramPriorityKeptMib: z33.int().nonnegative().optional(),
20212
20212
  ramSleepingMib: z33.int().nonnegative().optional(),
20213
+ ramPrioritySleepingMib: z33.int().nonnegative().optional(),
20213
20214
  awakeCount: z33.int().nonnegative(),
20214
20215
  impCount: z33.int().nonnegative(),
20215
20216
  sessionCount: z33.int().nonnegative(),
@@ -21739,6 +21740,7 @@ var EnvSchema = z53.object({
21739
21740
  IMP_KSM_HEADROOM_PERCENT: z53.string().default("100"),
21740
21741
  IMP_HUGE_PAGES: z53.enum(["off", "2M"]).default("off"),
21741
21742
  IMP_UFFD_HANDLER: z53.string().default("uffd-handler"),
21743
+ IMP_WARM_CAP_MIB: CountSchema3.default(256),
21742
21744
  IMP_DNS: z53.string().default("1.1.1.1,8.8.8.8").transform(splitList).pipe(DnsServersSchema),
21743
21745
  IMP_SUBNET: z53.cidrv4().default("10.66.0.0/16"),
21744
21746
  IMP_SUBNET6: z53.string().default("auto"),
@@ -21908,7 +21910,7 @@ function loadConfig(env) {
21908
21910
  jailerBin: parsed.IMP_JAILER === "true" ? parsed.IMP_JAILER_BIN : null,
21909
21911
  jailDir: join4(parsed.IMP_DATA_DIR, "jail"),
21910
21912
  ksm: parseKsmConfig(parsed),
21911
- hugePages: parsed.IMP_HUGE_PAGES === "2M" ? { handlerBin: parsed.IMP_UFFD_HANDLER } : null,
21913
+ hugePages: parsed.IMP_HUGE_PAGES === "2M" ? { handlerBin: parsed.IMP_UFFD_HANDLER, warmCapMib: parsed.IMP_WARM_CAP_MIB } : null,
21912
21914
  kernelPath: join4(parsed.IMP_DATA_DIR, "system", "vmlinux"),
21913
21915
  kernelSource: parsed.IMP_KERNEL ?? null,
21914
21916
  systemDriveSource: parsed.IMP_SYSTEM_DRIVE ?? join4(parsed.IMP_DATA_DIR, "system", "imp-system.squashfs"),
@@ -21991,7 +21993,7 @@ import { join as join48 } from "path";
21991
21993
  // packages/daemon/package.json
21992
21994
  var package_default = {
21993
21995
  name: "@impz/daemon",
21994
- version: "6.8.1",
21996
+ version: "6.9.1",
21995
21997
  private: true,
21996
21998
  description: "impd: the imp host daemon",
21997
21999
  type: "module",
@@ -30558,7 +30560,7 @@ async function readSystemInfo(deps) {
30558
30560
  deps.images.findDefaultImage()
30559
30561
  ]);
30560
30562
  const running = imps.filter((imp) => imp.state === "running");
30561
- const sleeping = imps.filter((imp) => imp.state === "sleeping");
30563
+ const sleeping = imps.filter((imp) => imp.state === "sleeping" && !deps.governor.isAdmitted(imp.id));
30562
30564
  return {
30563
30565
  version: package_default.version,
30564
30566
  ramBudgetMib: deps.config.ramBudgetMib,
@@ -30567,6 +30569,7 @@ async function readSystemInfo(deps) {
30567
30569
  ramCommittedMib: running.reduce((sum, imp) => sum + imp.maxMemoryMib, 0),
30568
30570
  ramPriorityKeptMib: usage.priorityKeptMib,
30569
30571
  ramSleepingMib: sleeping.reduce((sum, imp) => sum + imp.memoryMib, 0),
30572
+ ramPrioritySleepingMib: sleeping.filter((imp) => deps.governor.isPriority(imp.name)).reduce((sum, imp) => sum + imp.memoryMib, 0),
30570
30573
  awakeCount: running.length,
30571
30574
  impCount: imps.length,
30572
30575
  sessionCount: imps.reduce((sum, imp) => sum + (deps.imps.countSessions(imp) ?? 0), 0),
@@ -37945,7 +37948,7 @@ function createRamGovernor(deps) {
37945
37948
  }
37946
37949
  emitAdmission(request, "admitted", usedMib);
37947
37950
  };
37948
- const readReservation = (id) => {
37951
+ const getReservationMib = (id) => {
37949
37952
  const reservation = reservations.get(id);
37950
37953
  if (reservation === undefined) {
37951
37954
  return 0;
@@ -37977,7 +37980,7 @@ function createRamGovernor(deps) {
37977
37980
  const readings = await Promise.all(awake.map((imp) => readVm(imp.pid, imp.apiSocket)));
37978
37981
  const live = [...reservations.keys()].filter((id) => id !== excludeId).map((id) => ({
37979
37982
  id,
37980
- mib: readReservation(id),
37983
+ mib: getReservationMib(id),
37981
37984
  isPriority: admittedPriority.has(id),
37982
37985
  isOnPool: pendingHugePages.has(id)
37983
37986
  }));
@@ -38205,6 +38208,8 @@ function createRamGovernor(deps) {
38205
38208
  reservations.set(id, reservation.beforeGrow);
38206
38209
  }
38207
38210
  },
38211
+ isPriority,
38212
+ isAdmitted: (id) => getReservationMib(id) > 0,
38208
38213
  readUsage: async () => {
38209
38214
  const usage = await readEffectiveUsage(null);
38210
38215
  return {
@@ -38658,6 +38663,7 @@ function createImpCommands(parts) {
38658
38663
  const leases = parts.leases;
38659
38664
  const removeLockedImp = async (imp) => {
38660
38665
  const paths = context.findPaths(imp.id);
38666
+ await context.memoryWarm?.stop(imp.id, "destroyed");
38661
38667
  if (imp.pid !== null) {
38662
38668
  await context.vms.stopVm(imp.pid, paths, false);
38663
38669
  }
@@ -39701,6 +39707,113 @@ function splitRun(run) {
39701
39707
  });
39702
39708
  }
39703
39709
 
39710
+ // packages/daemon/src/vm/vmm/create-memory-warm.ts
39711
+ import invariant5 from "tiny-invariant";
39712
+ import { match as match11 } from "ts-pattern";
39713
+ import * as z76 from "zod";
39714
+ var BLOCK_MIB2 = 2;
39715
+ var WARM_CONCURRENCY = 2;
39716
+ var WarmReportSchema = z76.object({ blocks: z76.int().nonnegative() });
39717
+ function createMemoryWarm(deps) {
39718
+ const running = new Map;
39719
+ const lifetime = { isStopped: false };
39720
+ const slots = createSemaphore(WARM_CONCURRENCY);
39721
+ const readBlocks = async (mode, memFile, signal) => {
39722
+ signal.throwIfAborted();
39723
+ const argv = [deps.handlerBin, mode, memFile];
39724
+ const stdout = await runChecked(argv, { signal }, deps.run);
39725
+ return WarmReportSchema.parse(JSON.parse(stdout)).blocks;
39726
+ };
39727
+ const runWarm = async (memFile, signal) => {
39728
+ const startedMs = performance.now();
39729
+ try {
39730
+ const blocks = await readBlocks("--count-data", memFile, signal);
39731
+ if (blocks * BLOCK_MIB2 > deps.capMib) {
39732
+ return { kind: "overCap", blocks };
39733
+ }
39734
+ const read = await readBlocks("--warm", memFile, signal);
39735
+ return { kind: "warmed", blocks: read, warmMs: Math.round(performance.now() - startedMs) };
39736
+ } catch (error) {
39737
+ return { kind: "failed", error: getErrorMessage(error) };
39738
+ }
39739
+ };
39740
+ const stop = async (impID, end) => {
39741
+ const warm = running.get(impID);
39742
+ if (warm === undefined) {
39743
+ return;
39744
+ }
39745
+ warm.state.end = end;
39746
+ warm.controller.abort();
39747
+ if (warm.state.phase === "running") {
39748
+ await warm.done;
39749
+ return;
39750
+ }
39751
+ running.delete(impID);
39752
+ const warmMs = Math.round(performance.now() - warm.startedMs);
39753
+ logWarm(warm.target, { kind: "ended", end, warmMs }, deps.capMib);
39754
+ };
39755
+ return {
39756
+ start: (target) => {
39757
+ if (lifetime.isStopped) {
39758
+ logWarm(target, { kind: "closed" }, deps.capMib);
39759
+ return;
39760
+ }
39761
+ invariant5(!running.has(target.impID), `imp ${target.impID} slept with its warm running`);
39762
+ const controller = new AbortController;
39763
+ const state = { phase: "queued", end: null };
39764
+ const startedMs = performance.now();
39765
+ const runInSlot = () => {
39766
+ if (controller.signal.aborted) {
39767
+ return Promise.resolve(null);
39768
+ }
39769
+ state.phase = "running";
39770
+ return runWarm(target.memFile, controller.signal);
39771
+ };
39772
+ const runAndLog = async () => {
39773
+ const outcome = await slots.run(runInSlot);
39774
+ if (outcome === null) {
39775
+ return;
39776
+ }
39777
+ running.delete(target.impID);
39778
+ const end = state.end;
39779
+ const warmMs = Math.round(performance.now() - startedMs);
39780
+ const isEnded = outcome.kind === "failed" && end !== null;
39781
+ const logged = isEnded ? { kind: "ended", end, warmMs } : outcome;
39782
+ logWarm(target, logged, deps.capMib);
39783
+ };
39784
+ running.set(target.impID, { target, controller, state, startedMs, done: runAndLog() });
39785
+ },
39786
+ stop,
39787
+ stopAll: async () => {
39788
+ lifetime.isStopped = true;
39789
+ await Promise.all([...running.keys()].map((impID) => stop(impID, "impdStopped")));
39790
+ }
39791
+ };
39792
+ }
39793
+ function logWarm(target, outcome, capMib) {
39794
+ const logger = getImpdLogger("imps").with({ imp: target.name });
39795
+ match11(outcome).with({ kind: "warmed" }, (warmed) => {
39796
+ logger.info("warmed the memory file in {warmMs}ms: {blocks} blocks of 2 MiB", {
39797
+ warmMs: String(warmed.warmMs),
39798
+ blocks: String(warmed.blocks)
39799
+ });
39800
+ }).with({ kind: "overCap" }, (over) => {
39801
+ logger.info("left the memory file cold: its {dataMib} MiB of data pass the warm cap of {capMib} MiB", { dataMib: String(over.blocks * BLOCK_MIB2), capMib: String(capMib) });
39802
+ }).with({ kind: "ended" }, (ended) => {
39803
+ logger.info("stopped the memory file's warm after {warmMs}ms: {reason}", {
39804
+ warmMs: String(ended.warmMs),
39805
+ reason: formatWarmEnd(ended.end)
39806
+ });
39807
+ }).with({ kind: "closed" }, () => {
39808
+ logger.info("left the memory file cold: impd is stopping");
39809
+ }).with({ kind: "failed" }, (failed) => {
39810
+ logger.warning("the memory file's warm failed: {error}", { error: failed.error });
39811
+ }).exhaustive();
39812
+ }
39813
+ function formatWarmEnd(end) {
39814
+ return match11(end).with("woke", () => "the imp woke").with("stopped", () => "the imp stopped").with("destroyed", () => "the imp is destroyed").with("impdStopped", () => "impd stopped").exhaustive();
39815
+ }
39816
+
39704
39817
  // packages/daemon/src/vm/vmm/vm-stats.ts
39705
39818
  import { readFileSync as readFileSync19, readdirSync as readdirSync4 } from "fs";
39706
39819
  import { readFile as readFile3 } from "fs/promises";
@@ -40017,7 +40130,7 @@ function readStep(last, current) {
40017
40130
  }
40018
40131
 
40019
40132
  // packages/daemon/src/imps/imps/session-logs/session-log-service.ts
40020
- import * as z77 from "zod";
40133
+ import * as z78 from "zod";
40021
40134
 
40022
40135
  // packages/daemon/src/imps/imps/session-logs/build-log-key.ts
40023
40136
  function buildLogKey(impId, generation) {
@@ -40036,7 +40149,7 @@ import { basename as basename2, dirname as dirname8, join as join20, resolve as
40036
40149
  import { existsSync as existsSync10, readFileSync as readFileSync20, readdirSync as readdirSync5, rmSync as rmSync16 } from "fs";
40037
40150
  import { mkdir, open as open4, stat, truncate, unlink } from "fs/promises";
40038
40151
  import { join as join19 } from "path";
40039
- import * as z76 from "zod";
40152
+ import * as z77 from "zod";
40040
40153
 
40041
40154
  // packages/daemon/src/imps/imps/session-logs/plan-log-read.ts
40042
40155
  function getLogBounds(segments, origin) {
@@ -40081,20 +40194,20 @@ function planLogRead(segments, origin, from, limit) {
40081
40194
  var META_FILE = "meta.json";
40082
40195
  var SEGMENT_SUFFIX = ".seg";
40083
40196
  var COMMIT_DELAY_MS = 1000;
40084
- var OffsetSchema2 = z76.int().nonnegative();
40085
- var GenerationMetaSchema = z76.object({
40086
- version: z76.literal(1),
40197
+ var OffsetSchema2 = z77.int().nonnegative();
40198
+ var GenerationMetaSchema = z77.object({
40199
+ version: z77.literal(1),
40087
40200
  session: AgentSessionNameSchema,
40088
40201
  executionGeneration: AgentGenerationSchema,
40089
40202
  bootId: AgentBootIdSchema,
40090
- startedAt: z76.int(),
40203
+ startedAt: z77.int(),
40091
40204
  origin: OffsetSchema2,
40092
- segments: z76.array(z76.object({ start: OffsetSchema2, length: OffsetSchema2 })),
40093
- state: z76.enum(["live", "ended"]),
40094
- endedAt: z76.int().optional(),
40205
+ segments: z77.array(z77.object({ start: OffsetSchema2, length: OffsetSchema2 })),
40206
+ state: z77.enum(["live", "ended"]),
40207
+ endedAt: z77.int().optional(),
40095
40208
  end: OffsetSchema2.optional(),
40096
- exitCode: z76.int().nullable().optional(),
40097
- stopped: z76.enum(["disk_full", "imp_limit"]).optional()
40209
+ exitCode: z77.int().nullable().optional(),
40210
+ stopped: z77.enum(["disk_full", "imp_limit"]).optional()
40098
40211
  });
40099
40212
  function getSegmentPath(directory, start) {
40100
40213
  return join19(directory, `${String(start)}${SEGMENT_SUFFIX}`);
@@ -40874,7 +40987,7 @@ function toExitCode(code, signal) {
40874
40987
  }
40875
40988
 
40876
40989
  // packages/daemon/src/imps/imps/session-logs/session-log-service.ts
40877
- var NoSessionPreviousSchema = z77.object({ previous: PreviousGenerationSchema.optional() });
40990
+ var NoSessionPreviousSchema = z78.object({ previous: PreviousGenerationSchema.optional() });
40878
40991
  function createSessionLogs(deps) {
40879
40992
  const openTap = deps.openTap ?? openTapStream;
40880
40993
  const createLog = deps.createLog ?? createGenerationLog;
@@ -41266,6 +41379,11 @@ function createImpContext(deps) {
41266
41379
  readNetBytes: deps.readNetBytes,
41267
41380
  readMemory: deps.readVmMemory,
41268
41381
  readThreadIds: deps.readThreadIds
41382
+ }),
41383
+ memoryWarm: deps.config.hugePages === null ? null : createMemoryWarm({
41384
+ handlerBin: deps.config.hugePages.handlerBin,
41385
+ capMib: deps.config.hugePages.warmCapMib,
41386
+ run: deps.runCommand
41269
41387
  })
41270
41388
  };
41271
41389
  const guest = {
@@ -42344,6 +42462,7 @@ function createImpRuntime(parts) {
42344
42462
  },
42345
42463
  tracker: context.tracker,
42346
42464
  bootTemplates: context.templates,
42465
+ memoryWarm: context.memoryWarm,
42347
42466
  readDiskFullError: () => lastDiskFull.error
42348
42467
  };
42349
42468
  }
@@ -42568,13 +42687,17 @@ function makeSleepImpVm(deps) {
42568
42687
  const sessions = await readSessionsForSleep(imp, paths);
42569
42688
  const services = await sendServicesList(paths.vsockSocket, SERVICES_FOR_SLEEP_MS).catch(() => null);
42570
42689
  const started = context.sleepTiming.now();
42571
- const slept = { detail: { trigger: reason } };
42690
+ const slept = {
42691
+ detail: { trigger: reason },
42692
+ isOnHugePages: false
42693
+ };
42572
42694
  removeSnapshotMeta(paths);
42573
42695
  const hasOomKill = startOomWatch(context.cgroups, imp.id);
42574
42696
  try {
42575
42697
  const cgroup = context.cgroups.setup(imp.id, imp.cpu, imp.memoryMib);
42576
42698
  const timings = await deps.withSleepSlot(() => context.vms.sleepVm(pid, paths, cgroup, paths));
42577
42699
  const booted = readVmIdentity(paths);
42700
+ slept.isOnHugePages = booted?.hugePages === "2M";
42578
42701
  writeSnapshotMeta(paths, {
42579
42702
  ...buildSnapshotIdentity(booted, context.identity),
42580
42703
  createdAt: Date.now(),
@@ -42627,13 +42750,17 @@ function makeSleepImpVm(deps) {
42627
42750
  throw isOomKill ? new Error(`sleep failed: ${OOM_KILL_TRIGGER}`, { cause: error }) : error;
42628
42751
  }
42629
42752
  context.admission.release(imp.id);
42630
- return updateState(imp, {
42753
+ const sleeping = await updateState(imp, {
42631
42754
  reason: "slept",
42632
42755
  detail: slept.detail,
42633
42756
  state: "sleeping",
42634
42757
  pid: null,
42635
42758
  sleptAt: new Date
42636
42759
  });
42760
+ if (slept.isOnHugePages) {
42761
+ context.memoryWarm?.start({ impID: imp.id, name: imp.name, memFile: paths.memFile });
42762
+ }
42763
+ return sleeping;
42637
42764
  };
42638
42765
  const sleepImpVm = async (imp, reason, youngGuest = ALWAYS_WAIT) => {
42639
42766
  requireTransition(imp.state, "sleeping", "sleep");
@@ -42710,6 +42837,7 @@ function makeWakeImpVm(deps) {
42710
42837
  throw buildStoppingError();
42711
42838
  }
42712
42839
  requireNoOopsHold(context, imp);
42840
+ await context.memoryWarm?.stop(imp.id, "woke");
42713
42841
  const paths = context.findPaths(imp.id);
42714
42842
  const meta = readSnapshotMeta(paths);
42715
42843
  const mismatch = meta === null ? "no snapshot it can load" : readColdBootReason(meta, context.identity);
@@ -42907,18 +43035,18 @@ async function waitForAgent(vsockPath, options) {
42907
43035
  }
42908
43036
 
42909
43037
  // packages/daemon/src/vm/vmm/firecracker-client.ts
42910
- import * as z78 from "zod";
42911
- var InstanceInfoSchema = z78.object({ state: z78.enum(["Not started", "Running", "Paused"]) });
42912
- var MachineConfigSchema = z78.object({
42913
- track_dirty_pages: z78.boolean().optional(),
42914
- huge_pages: z78.string().optional()
43038
+ import * as z79 from "zod";
43039
+ var InstanceInfoSchema = z79.object({ state: z79.enum(["Not started", "Running", "Paused"]) });
43040
+ var MachineConfigSchema = z79.object({
43041
+ track_dirty_pages: z79.boolean().optional(),
43042
+ huge_pages: z79.string().optional()
42915
43043
  });
42916
- var BalloonStatsSchema = z78.object({ total_memory: z78.number(), available_memory: z78.number() });
42917
- var HotplugMemorySchema = z78.object({
42918
- plugged_size_mib: z78.number(),
42919
- requested_size_mib: z78.number()
43044
+ var BalloonStatsSchema = z79.object({ total_memory: z79.number(), available_memory: z79.number() });
43045
+ var HotplugMemorySchema = z79.object({
43046
+ plugged_size_mib: z79.number(),
43047
+ requested_size_mib: z79.number()
42920
43048
  });
42921
- var VersionSchema = z78.object({ firecracker_version: z78.string() });
43049
+ var VersionSchema = z79.object({ firecracker_version: z79.string() });
42922
43050
  var DEFAULT_TIMEOUTS = { requestMs: 1e4, snapshotMs: 120000 };
42923
43051
 
42924
43052
  class FirecrackerApiError extends Error {
@@ -43909,6 +44037,7 @@ function createImpVmOps(host) {
43909
44037
  const startNewImpVm = (imp, diskReady) => startColdImpVm(imp, "start", null, diskReady);
43910
44038
  const stopImpVm = async (imp, graceful = true) => {
43911
44039
  const paths = context.findPaths(imp.id);
44040
+ await context.memoryWarm?.stop(imp.id, "stopped");
43912
44041
  if (imp.pid !== null) {
43913
44042
  await context.vms.stopVm(imp.pid, paths, graceful);
43914
44043
  }
@@ -44016,7 +44145,7 @@ function countStepsMs(timings) {
44016
44145
  }
44017
44146
 
44018
44147
  // packages/daemon/src/imps/imps/services/service-api.ts
44019
- import { match as match11 } from "ts-pattern";
44148
+ import { match as match12 } from "ts-pattern";
44020
44149
 
44021
44150
  // packages/daemon/src/imps/imps/services/create-log-decoders.ts
44022
44151
  function createLogDecoders() {
@@ -44240,7 +44369,7 @@ function handleAgentError(service) {
44240
44369
  if (!(error instanceof AgentError)) {
44241
44370
  throw error;
44242
44371
  }
44243
- throw match11(error.code).with("NO_SERVICE", () => buildNotFoundError("service", service)).with("SERVICE_EXISTS", () => buildConflictError("service", service)).with("BAD_REQUEST", () => new ImpdError("BAD_REQUEST", { message: error.detail })).with("AGENT_OUTDATED", () => buildAgentOutdatedApiError(error.message)).otherwise(() => error);
44372
+ throw match12(error.code).with("NO_SERVICE", () => buildNotFoundError("service", service)).with("SERVICE_EXISTS", () => buildConflictError("service", service)).with("BAD_REQUEST", () => new ImpdError("BAD_REQUEST", { message: error.detail })).with("AGENT_OUTDATED", () => buildAgentOutdatedApiError(error.message)).otherwise(() => error);
44244
44373
  };
44245
44374
  }
44246
44375
  function stopStreams(streams) {
@@ -45676,6 +45805,7 @@ function createImpdImps(config, deps, parts) {
45676
45805
  cgroups,
45677
45806
  memoryLimit,
45678
45807
  readExecEnv: parts.broker.readExecEnv,
45808
+ runCommand: deps.runCommand ?? runCommand,
45679
45809
  storageGate: parts.storage.storageGate,
45680
45810
  diskBudget: parts.storage.diskBudget,
45681
45811
  readDiskUsage: parts.storage.diskUsage.read,
@@ -45876,79 +46006,79 @@ function buildOfferedDigests(digest, receivedDigest) {
45876
46006
  var COMMIT_WINDOW_MS = 24 * 60 * 60 * 1000;
45877
46007
 
45878
46008
  // packages/daemon/src/imp-ops/moves/move-header.ts
45879
- import * as z79 from "zod";
45880
- var CpuSchema = z79.object({ limit: z79.number().positive().nullable(), weight: z79.int() }).readonly();
45881
- var EgressSchema = z79.object({ mode: z79.string(), allow: z79.array(z79.string()).readonly() }).readonly();
45882
- var CheckpointSchema3 = z79.object({
45883
- label: z79.string().nullable(),
45884
- createdAt: z79.coerce.date(),
45885
- diskBytes: z79.int().positive()
46009
+ import * as z80 from "zod";
46010
+ var CpuSchema = z80.object({ limit: z80.number().positive().nullable(), weight: z80.int() }).readonly();
46011
+ var EgressSchema = z80.object({ mode: z80.string(), allow: z80.array(z80.string()).readonly() }).readonly();
46012
+ var CheckpointSchema3 = z80.object({
46013
+ label: z80.string().nullable(),
46014
+ createdAt: z80.coerce.date(),
46015
+ diskBytes: z80.int().positive()
45886
46016
  }).readonly();
45887
- var MovedBootSchema = z79.object({ bootId: z79.uuid(), cause: ColdBootCauseSchema, at: z79.iso.datetime() }).readonly();
46017
+ var MovedBootSchema = z80.object({ bootId: z80.uuid(), cause: ColdBootCauseSchema, at: z80.iso.datetime() }).readonly();
45888
46018
  var MAX_MOVED_LEASES = 1024;
45889
46019
  var MAX_LEASE_REMAINING_MS = 100 * 365 * 24 * 60 * 60 * 1000;
45890
- var LeaseOwnerTextSchema = z79.string().min(1).max(256);
45891
- var MovedLeaseOwnerSchema = z79.object({
46020
+ var LeaseOwnerTextSchema = z80.string().min(1).max(256);
46021
+ var MovedLeaseOwnerSchema = z80.object({
45892
46022
  principal: LeaseOwnerTextSchema,
45893
46023
  label: LeaseLabelSchema,
45894
46024
  display: LeaseOwnerTextSchema
45895
46025
  });
45896
46026
  var MovedLeaseSchema = MovedLeaseOwnerSchema.extend({
45897
- remainingMs: z79.int().nonnegative().max(MAX_LEASE_REMAINING_MS).nullable(),
45898
- createdAt: z79.coerce.date()
46027
+ remainingMs: z80.int().nonnegative().max(MAX_LEASE_REMAINING_MS).nullable(),
46028
+ createdAt: z80.coerce.date()
45899
46029
  }).readonly();
45900
- var FilteredGrantSchema2 = z79.object({ secret: z79.string(), filter: GrantFilterSchema }).readonly();
45901
- var ImpSchema2 = z79.object({
45902
- id: z79.uuid(),
45903
- name: z79.string(),
45904
- clonedDigest: z79.string().optional(),
45905
- vcpus: z79.int().positive(),
45906
- memoryMib: z79.int().positive(),
45907
- maxMemoryMib: z79.int().positive().optional(),
45908
- httpPort: z79.int().positive(),
45909
- diskBytes: z79.int().positive(),
46030
+ var FilteredGrantSchema2 = z80.object({ secret: z80.string(), filter: GrantFilterSchema }).readonly();
46031
+ var ImpSchema2 = z80.object({
46032
+ id: z80.uuid(),
46033
+ name: z80.string(),
46034
+ clonedDigest: z80.string().optional(),
46035
+ vcpus: z80.int().positive(),
46036
+ memoryMib: z80.int().positive(),
46037
+ maxMemoryMib: z80.int().positive().optional(),
46038
+ httpPort: z80.int().positive(),
46039
+ diskBytes: z80.int().positive(),
45910
46040
  cpu: CpuSchema,
45911
46041
  egress: EgressSchema,
45912
- grants: z79.array(z79.string()).readonly(),
45913
- filteredGrants: z79.array(FilteredGrantSchema2).readonly().default([]),
45914
- isIdentityResetPending: z79.boolean(),
45915
- isDiskGrowPending: z79.boolean().default(false),
45916
- isBackedUp: z79.boolean().default(true),
45917
- coldBoots: z79.array(MovedBootSchema).max(4).readonly().default([]),
45918
- leases: z79.array(MovedLeaseSchema).max(MAX_MOVED_LEASES).readonly().optional()
46042
+ grants: z80.array(z80.string()).readonly(),
46043
+ filteredGrants: z80.array(FilteredGrantSchema2).readonly().default([]),
46044
+ isIdentityResetPending: z80.boolean(),
46045
+ isDiskGrowPending: z80.boolean().default(false),
46046
+ isBackedUp: z80.boolean().default(true),
46047
+ coldBoots: z80.array(MovedBootSchema).max(4).readonly().default([]),
46048
+ leases: z80.array(MovedLeaseSchema).max(MAX_MOVED_LEASES).readonly().optional()
45919
46049
  }).readonly();
45920
- var StreamStepSchema = z79.object({
45921
- checkpoint: z79.int().nonnegative().nullable(),
45922
- dataset: z79.int().nonnegative(),
45923
- base: z79.int().nonnegative().nullable()
46050
+ var StreamStepSchema = z80.object({
46051
+ checkpoint: z80.int().nonnegative().nullable(),
46052
+ dataset: z80.int().nonnegative(),
46053
+ base: z80.int().nonnegative().nullable()
45924
46054
  }).readonly();
45925
- var HeldAnswerSchema = z79.object({
45926
- names: z79.array(z79.string()).readonly(),
45927
- address: z79.string(),
45928
- ttlS: z79.int().positive()
46055
+ var HeldAnswerSchema = z80.object({
46056
+ names: z80.array(z80.string()).readonly(),
46057
+ address: z80.string(),
46058
+ ttlS: z80.int().positive()
45929
46059
  }).readonly();
45930
- var WarmSchema = z79.object({
46060
+ var WarmSchema = z80.object({
45931
46061
  move: WarmMoveSchema,
45932
46062
  meta: SnapshotMetaSchema.extend({ systemDrive: SystemDriveSchema }),
45933
46063
  vm: VmIdentitySchema.nullable(),
45934
- isDriveIncluded: z79.boolean(),
45935
- answers: z79.array(HeldAnswerSchema).readonly()
46064
+ isDriveIncluded: z80.boolean(),
46065
+ answers: z80.array(HeldAnswerSchema).readonly()
45936
46066
  }).readonly();
45937
- var MoveHeaderSchema = z79.object({
45938
- version: z79.literal(1),
46067
+ var MoveHeaderSchema = z80.object({
46068
+ version: z80.literal(1),
45939
46069
  imp: ImpSchema2,
45940
- image: z79.object({
45941
- name: z79.string(),
45942
- ref: z79.string(),
45943
- digest: z79.string(),
45944
- receivedDigest: z79.string().nullable().default(null),
45945
- sizeBytes: z79.int().nonnegative(),
46070
+ image: z80.object({
46071
+ name: z80.string(),
46072
+ ref: z80.string(),
46073
+ digest: z80.string(),
46074
+ receivedDigest: z80.string().nullable().default(null),
46075
+ sizeBytes: z80.int().nonnegative(),
45946
46076
  source: ImageSourceSchema,
45947
- sourceImp: z79.string().nullable(),
45948
- isIncluded: z79.boolean()
46077
+ sourceImp: z80.string().nullable(),
46078
+ isIncluded: z80.boolean()
45949
46079
  }),
45950
- checkpoints: z79.array(CheckpointSchema3).readonly(),
45951
- streams: z79.array(StreamStepSchema).readonly().nullable(),
46080
+ checkpoints: z80.array(CheckpointSchema3).readonly(),
46081
+ streams: z80.array(StreamStepSchema).readonly().nullable(),
45952
46082
  warm: WarmSchema.nullable().default(null)
45953
46083
  }).readonly();
45954
46084
  var MOVE_PART_HEADER = "x-imp-move-part";
@@ -46110,7 +46240,7 @@ class MoveRequestError extends ImpdError {
46110
46240
  }
46111
46241
 
46112
46242
  // packages/daemon/src/imp-ops/moves/move-tickets.ts
46113
- import * as z80 from "zod";
46243
+ import * as z81 from "zod";
46114
46244
  var MOVE_AUTH_SCHEME = "ImpMove";
46115
46245
  var MOVE_TICKET_PREFIX = "";
46116
46246
  function isSameHash(leftItem, rightItem) {
@@ -46124,19 +46254,19 @@ function readTicketHeader(request) {
46124
46254
  function buildTicketHeader(ticket) {
46125
46255
  return { authorization: `${MOVE_AUTH_SCHEME} ${ticket}` };
46126
46256
  }
46127
- var ReceiptFileSchema = z80.object({
46128
- kind: z80.string(),
46129
- index: z80.int().nonnegative().optional(),
46130
- sha256: z80.string(),
46131
- bytes: z80.int().nonnegative()
46257
+ var ReceiptFileSchema = z81.object({
46258
+ kind: z81.string(),
46259
+ index: z81.int().nonnegative().optional(),
46260
+ sha256: z81.string(),
46261
+ bytes: z81.int().nonnegative()
46132
46262
  });
46133
- var ReceiptBodySchema = z80.object({
46134
- ticketId: z80.string(),
46135
- name: z80.string(),
46136
- impId: z80.string(),
46137
- files: z80.array(ReceiptFileSchema)
46263
+ var ReceiptBodySchema = z81.object({
46264
+ ticketId: z81.string(),
46265
+ name: z81.string(),
46266
+ impId: z81.string(),
46267
+ files: z81.array(ReceiptFileSchema)
46138
46268
  });
46139
- var ReceiptSchema = z80.object({ body: z80.string(), mac: z80.string() });
46269
+ var ReceiptSchema = z81.object({ body: z81.string(), mac: z81.string() });
46140
46270
  function buildReceipt(body, secret) {
46141
46271
  const text = JSON.stringify(body);
46142
46272
  return { body: text, mac: sign(secret, text).toString("hex") };
@@ -46152,7 +46282,7 @@ function readReceipt(receipt, secret) {
46152
46282
  import { mkdirSync as mkdirSync19, rmSync as rmSync23 } from "fs";
46153
46283
  import { open as open7 } from "fs/promises";
46154
46284
  import { join as join25 } from "path";
46155
- import invariant5 from "tiny-invariant";
46285
+ import invariant6 from "tiny-invariant";
46156
46286
 
46157
46287
  // packages/daemon/src/imp-ops/moves/build-received-digest.ts
46158
46288
  import { createHash as createHash5 } from "crypto";
@@ -46361,7 +46491,7 @@ function createByteCounter(limit) {
46361
46491
  // packages/daemon/src/imp-ops/moves/move-frames.ts
46362
46492
  import { createHash as createHash8 } from "crypto";
46363
46493
  import { open as open6 } from "fs/promises";
46364
- import * as z81 from "zod";
46494
+ import * as z82 from "zod";
46365
46495
 
46366
46496
  // packages/daemon/src/imp-ops/moves/create-content-hash.ts
46367
46497
  import { createHash as createHash7 } from "crypto";
@@ -46399,8 +46529,8 @@ var MOVE_BLOCK_BYTES = 1024 * 1024;
46399
46529
  var OFFSET_BYTES = 8;
46400
46530
  var HEADER_BYTES3 = 5;
46401
46531
  var MAX_PAYLOAD_BYTES = MOVE_BLOCK_BYTES + OFFSET_BYTES;
46402
- var MoveFileSchema = z81.object({
46403
- kind: z81.enum([
46532
+ var MoveFileSchema = z82.object({
46533
+ kind: z82.enum([
46404
46534
  "image-rootfs",
46405
46535
  "image-config",
46406
46536
  "checkpoint",
@@ -46410,13 +46540,13 @@ var MoveFileSchema = z81.object({
46410
46540
  "vmstate",
46411
46541
  "mem"
46412
46542
  ]),
46413
- index: z81.int().nonnegative().optional(),
46414
- sizeBytes: z81.int().nonnegative()
46543
+ index: z82.int().nonnegative().optional(),
46544
+ sizeBytes: z82.int().nonnegative()
46415
46545
  });
46416
46546
  function createFileContentHash(file) {
46417
46547
  return file.kind === "image-rootfs" || file.kind === "image-config" ? createContentHash(file.sizeBytes) : null;
46418
46548
  }
46419
- var FileEndSchema = z81.object({ sha256: z81.string() });
46549
+ var FileEndSchema = z82.object({ sha256: z82.string() });
46420
46550
  function encodeFrame2(type, payload) {
46421
46551
  const frame = new Uint8Array(HEADER_BYTES3 + payload.length);
46422
46552
  const view = new DataView(frame.buffer);
@@ -46943,7 +47073,7 @@ async function requireImage(deps, options) {
46943
47073
  { kind: "image-rootfs", sha256: rootfs.sha256, bytes: rootfs.bytes },
46944
47074
  { kind: "image-config", sha256: config.sha256, bytes: config.bytes }
46945
47075
  ];
46946
- invariant5(rootfs.contentSha256 !== null && config.contentSha256 !== null);
47076
+ invariant6(rootfs.contentSha256 !== null && config.contentSha256 !== null);
46947
47077
  const digest = buildReceivedDigest(rootfs.contentSha256, config.contentSha256);
46948
47078
  const known = await readImageInUse(deps.db, [digest], deps.now());
46949
47079
  if (known !== undefined) {
@@ -47252,8 +47382,8 @@ function readSettled2(row, imp) {
47252
47382
  }
47253
47383
 
47254
47384
  // packages/daemon/src/imp-ops/moves/move-sender.ts
47255
- import invariant6 from "tiny-invariant";
47256
- import { match as match12 } from "ts-pattern";
47385
+ import invariant7 from "tiny-invariant";
47386
+ import { match as match13 } from "ts-pattern";
47257
47387
 
47258
47388
  // packages/daemon/src/platform/db/move-send-steps.ts
47259
47389
  var MOVE_SEND_STEPS = [
@@ -47816,7 +47946,7 @@ function createMoveSender(deps) {
47816
47946
  };
47817
47947
  const recoverSend = async (imp, row) => {
47818
47948
  const log = getImpdLogger("move").with({ imp: imp.name });
47819
- await match12(pickSendRecovery(imp.moveState, row?.step)).with("unmark", () => removeMark(imp)).with("wait", () => {
47949
+ await match13(pickSendRecovery(imp.moveState, row?.step)).with("unmark", () => removeMark(imp)).with("wait", () => {
47820
47950
  log.info("a prepared send waits for its send after a restart");
47821
47951
  }).with("abort", async () => {
47822
47952
  const isUndone = await resetSend(imp, row?.peer_url ?? null, row?.ticket ?? null);
@@ -47824,7 +47954,7 @@ function createMoveSender(deps) {
47824
47954
  log.info("a send cut short by a restart was undone");
47825
47955
  }
47826
47956
  }).with("commit", async () => {
47827
- invariant6(row !== undefined && row.peer_url !== null && row.ticket !== null);
47957
+ invariant7(row !== undefined && row.peer_url !== null && row.ticket !== null);
47828
47958
  const moved = imp.moveState === "moved" ? imp : await updateImpMove(deps.db, imp.id, "moved");
47829
47959
  await runCommitAfterRestart(moved, row.peer_url, row.ticket);
47830
47960
  }).with("none", () => {}).exhaustive();
@@ -47938,7 +48068,7 @@ function buildPublicError(name) {
47938
48068
  }
47939
48069
  function pickSendRecovery(moveState, step) {
47940
48070
  if (moveState === "sending") {
47941
- return match12(step).with(undefined, () => "unmark").with("prepared", () => "wait").with("streaming", () => "abort").with("sent", () => "commit").exhaustive();
48071
+ return match13(step).with(undefined, () => "unmark").with("prepared", () => "wait").with("streaming", () => "abort").with("sent", () => "commit").exhaustive();
47942
48072
  }
47943
48073
  return moveState === "moved" && step === "sent" ? "commit" : "none";
47944
48074
  }
@@ -47990,7 +48120,7 @@ function createMoveService(deps) {
47990
48120
  // packages/daemon/src/surface/moves/create-move-peer-handler.ts
47991
48121
  import { OpenAPIHandler } from "@orpc/openapi/fetch";
47992
48122
  import { ORPCError as ORPCError7, implement as implement3, onError as onError3 } from "@orpc/server";
47993
- import { match as match13 } from "ts-pattern";
48123
+ import { match as match14 } from "ts-pattern";
47994
48124
  function createMovePeerHandler(deps) {
47995
48125
  const withTicket = async (step, context, call) => {
47996
48126
  const startedAt = deps.now();
@@ -48041,7 +48171,7 @@ function createMovePeerHandler(deps) {
48041
48171
  const respondReceive = async (context) => {
48042
48172
  try {
48043
48173
  const received = await withTicket("receive", context, (checked) => deps.calls.receive(checked, context.request));
48044
- return match13(received).with({ kind: "part" }, (sent) => Response.json({ part: sent.part }, { status: 202 })).with({ kind: "receipt" }, (sent) => Response.json(sent.receipt)).exhaustive();
48174
+ return match14(received).with({ kind: "part" }, (sent) => Response.json({ part: sent.part }, { status: 202 })).with({ kind: "receipt" }, (sent) => Response.json(sent.receipt)).exhaustive();
48045
48175
  } catch (error) {
48046
48176
  const failure = toPeerError(error);
48047
48177
  return Response.json(encodePeerError(failure), { status: failure.status });
@@ -48085,7 +48215,7 @@ import {
48085
48215
  } from "@orpc/client";
48086
48216
  import { ResponseValidationPlugin } from "@orpc/contract/plugins";
48087
48217
  import { OpenAPILink } from "@orpc/openapi-client/fetch";
48088
- import * as z82 from "zod";
48218
+ import * as z83 from "zod";
48089
48219
  function makeConnectMovePeer(deps) {
48090
48220
  return (target) => {
48091
48221
  const sendLinkRequest = async (request) => {
@@ -48131,7 +48261,7 @@ function makeConnectMovePeer(deps) {
48131
48261
  };
48132
48262
  };
48133
48263
  }
48134
- var PeerErrorBodySchema = z82.looseObject({ error: z82.string().optional() });
48264
+ var PeerErrorBodySchema = z83.looseObject({ error: z83.string().optional() });
48135
48265
  function decodePeerError(body, response) {
48136
48266
  const parsed = PeerErrorBodySchema.safeParse(body);
48137
48267
  if (!parsed.success) {
@@ -48891,7 +49021,7 @@ import { join as join30, posix as posix3 } from "path";
48891
49021
 
48892
49022
  // packages/local-tar/src/extract-local.ts
48893
49023
  import tar from "tar-stream";
48894
- import * as z83 from "zod";
49024
+ import * as z84 from "zod";
48895
49025
  // packages/local-tar/src/pack-build-context.ts
48896
49026
  import { existsSync as existsSync18 } from "fs";
48897
49027
  import { lstat, readFile as readFile4, readdir } from "fs/promises";
@@ -50021,14 +50151,14 @@ function renderPinnedDockerfile(dockerfile, pins, platform) {
50021
50151
  }
50022
50152
 
50023
50153
  // packages/daemon/src/imps/images/pull/image-pin.ts
50024
- import * as z84 from "zod";
50154
+ import * as z85 from "zod";
50025
50155
  var PIN_INSPECT_FORMAT = '{"Id":{{json .Id}},"RepoDigests":{{json .RepoDigests}},"Os":{{json .Os}},"Architecture":{{json .Architecture}},"Config":{{json .Config}}}';
50026
- var ConfigSchema = z84.object({ OnBuild: z84.array(z84.unknown()).readonly().nullish() }).nullable();
50027
- var PinInspectSchema = z84.object({
50028
- Id: z84.string(),
50029
- RepoDigests: z84.array(z84.string()).readonly().nullable(),
50030
- Os: z84.string(),
50031
- Architecture: z84.string(),
50156
+ var ConfigSchema = z85.object({ OnBuild: z85.array(z85.unknown()).readonly().nullish() }).nullable();
50157
+ var PinInspectSchema = z85.object({
50158
+ Id: z85.string(),
50159
+ RepoDigests: z85.array(z85.string()).readonly().nullable(),
50160
+ Os: z85.string(),
50161
+ Architecture: z85.string(),
50032
50162
  Config: ConfigSchema
50033
50163
  }).transform((inspect) => ({
50034
50164
  Id: inspect.Id,
@@ -50090,7 +50220,7 @@ impd pinned ${pinned}. On the containerd image store a retag of a multi-platform
50090
50220
  }
50091
50221
 
50092
50222
  // packages/daemon/src/imps/images/build/build-engine.ts
50093
- import * as z85 from "zod";
50223
+ import * as z86 from "zod";
50094
50224
 
50095
50225
  // packages/daemon/src/imps/docker-contract/dockerfile-frontend.ts
50096
50226
  var DOCKERFILE_FRONTEND = "docker/dockerfile:1.28@sha256:bb22d9815c728170f72750f4e5b0d672e06176142e1d602c7e66c050100b7e5b";
@@ -50124,7 +50254,7 @@ function createBuildEngine(run) {
50124
50254
  if (version.exitCode !== 0) {
50125
50255
  throw new Error(`docker version: ${version.stderr.trim()}`);
50126
50256
  }
50127
- const [os, arch] = z85.tuple([z85.string(), z85.string()]).parse(version.stdout.trim().split(" ").map((part) => JSON.parse(part)));
50257
+ const [os, arch] = z86.tuple([z86.string(), z86.string()]).parse(version.stdout.trim().split(" ").map((part) => JSON.parse(part)));
50128
50258
  return normalizePlatform(os, arch);
50129
50259
  },
50130
50260
  loadImage: async (image, signal) => {
@@ -50226,7 +50356,7 @@ class DockerBuildError extends Error {
50226
50356
  }
50227
50357
 
50228
50358
  // packages/daemon/src/imps/images/build/guest-build.ts
50229
- import * as z86 from "zod";
50359
+ import * as z87 from "zod";
50230
50360
 
50231
50361
  // packages/daemon/src/imps/images/build/image-limit-error.ts
50232
50362
  class ImageLimitError extends ImpdError {
@@ -50498,8 +50628,8 @@ function createPlainLines(output) {
50498
50628
  // packages/daemon/src/imps/images/build/guest-build.ts
50499
50629
  var GUEST_BUILD_TAG = "imp-build:latest";
50500
50630
  var LOG_MAX_CHARS = 8000;
50501
- var ContainerIdSchema = z86.string().regex(/^[a-f0-9]{64}$/v);
50502
- var OciConfigSchema = z86.record(z86.string(), z86.unknown()).nullable();
50631
+ var ContainerIdSchema = z87.string().regex(/^[a-f0-9]{64}$/v);
50632
+ var OciConfigSchema = z87.record(z87.string(), z87.unknown()).nullable();
50503
50633
  async function runGuestBuild(exec, options) {
50504
50634
  const lines = options.output === undefined ? null : createPlainLines(options.output);
50505
50635
  const result = await exec([
@@ -50854,7 +50984,7 @@ function normalizeDockerfilePath(path) {
50854
50984
  }
50855
50985
 
50856
50986
  // packages/daemon/src/imps/images/image-naming.ts
50857
- import * as z87 from "zod";
50987
+ import * as z88 from "zod";
50858
50988
  var MAX_NAME_LENGTH2 = 31;
50859
50989
  function deriveImageName(ref) {
50860
50990
  const lastSegment = parseImageReference(ref).path.split("/").at(-1) ?? "";
@@ -50864,10 +50994,10 @@ function deriveImageName(ref) {
50864
50994
  }
50865
50995
  return name;
50866
50996
  }
50867
- var OciConfigSchema2 = z87.object({
50868
- Env: z87.array(z87.string()).nullish(),
50869
- WorkingDir: z87.string().nullish(),
50870
- User: z87.string().nullish()
50997
+ var OciConfigSchema2 = z88.object({
50998
+ Env: z88.array(z88.string()).nullish(),
50999
+ WorkingDir: z88.string().nullish(),
51000
+ User: z88.string().nullish()
50871
51001
  }).nullish();
50872
51002
  function buildImageRuntimeConfig(ociConfig) {
50873
51003
  const parsed = OciConfigSchema2.parse(ociConfig);
@@ -50883,10 +51013,10 @@ import { existsSync as existsSync20, mkdirSync as mkdirSync22, rmSync as rmSync2
50883
51013
  import { join as join32 } from "path";
50884
51014
 
50885
51015
  // packages/daemon/src/imps/images/rootfs/read-oci-config.ts
50886
- import * as z88 from "zod";
50887
- var OciConfigSchema3 = z88.object({
50888
- digest: z88.string().regex(/^sha256:[a-f0-9]{64}$/v),
50889
- config: z88.record(z88.string(), z88.unknown()).nullable()
51016
+ import * as z89 from "zod";
51017
+ var OciConfigSchema3 = z89.object({
51018
+ digest: z89.string().regex(/^sha256:[a-f0-9]{64}$/v),
51019
+ config: z89.record(z89.string(), z89.unknown()).nullable()
50890
51020
  });
50891
51021
  async function readOciConfig(ref, signal, run) {
50892
51022
  const argv = ["oci-fetch", "config", ref];
@@ -51710,11 +51840,11 @@ function createImpdStorage(config, deps) {
51710
51840
  }
51711
51841
 
51712
51842
  // packages/daemon/src/host-net/net/tailscale-status.ts
51713
- import * as z89 from "zod";
51714
- var IpListSchema = z89.array(z89.string()).nullable().optional();
51715
- var StatusSchema = z89.object({
51716
- BackendState: z89.string(),
51717
- Self: z89.object({ HostName: z89.string(), DNSName: z89.string().optional(), TailscaleIPs: IpListSchema }).optional()
51843
+ import * as z90 from "zod";
51844
+ var IpListSchema = z90.array(z90.string()).nullable().optional();
51845
+ var StatusSchema = z90.object({
51846
+ BackendState: z90.string(),
51847
+ Self: z90.object({ HostName: z90.string(), DNSName: z90.string().optional(), TailscaleIPs: IpListSchema }).optional()
51718
51848
  });
51719
51849
  var UNKNOWN = { state: null, hostname: null, dnsName: null, ip: null, ips: [] };
51720
51850
  var STATUS_TTL_MS = 30000;
@@ -51997,18 +52127,18 @@ import { getOAuthProviderApi } from "@better-auth/oauth-provider";
51997
52127
  import { createAuthEndpoint } from "better-auth/api";
51998
52128
  import { setSessionCookie } from "better-auth/cookies";
51999
52129
  import { generateRandomString } from "better-auth/crypto";
52000
- import * as z90 from "zod";
52130
+ import * as z91 from "zod";
52001
52131
  var CLIENT_SCOPES = [...ScopeSchema.options, "offline_access"];
52002
52132
  var APPROVAL_EMAIL_DOMAIN = "approval.imp.invalid";
52003
- var SignInBodySchema = z90.object({
52004
- oauth_query: z90.string(),
52005
- tokenID: z90.string().min(1),
52006
- tokenName: z90.string().min(1),
52007
- imps: z90.array(z90.string()).nullable()
52133
+ var SignInBodySchema = z91.object({
52134
+ oauth_query: z91.string(),
52135
+ tokenID: z91.string().min(1),
52136
+ tokenName: z91.string().min(1),
52137
+ imps: z91.array(z91.string()).nullable()
52008
52138
  });
52009
- var FixedClientBodySchema = z90.object({
52010
- name: z90.string().min(1),
52011
- redirectURIs: z90.array(z90.string()).min(1)
52139
+ var FixedClientBodySchema = z91.object({
52140
+ name: z91.string().min(1),
52141
+ redirectURIs: z91.array(z91.string()).min(1)
52012
52142
  });
52013
52143
  function createApproverPlugin() {
52014
52144
  return {
@@ -52034,7 +52164,7 @@ function createApproverPlugin() {
52034
52164
  }),
52035
52165
  verifyMCPAccessToken: createAuthEndpoint("/imp/verify-access-token", {
52036
52166
  method: "POST",
52037
- body: z90.object({ token: z90.string() }),
52167
+ body: z91.object({ token: z91.string() }),
52038
52168
  metadata: { SERVER_ONLY: true }
52039
52169
  }, async (ctx) => {
52040
52170
  const provider = ctx.context.getPlugin("oauth-provider");
@@ -52078,7 +52208,7 @@ function createApproverPlugin() {
52078
52208
 
52079
52209
  // packages/daemon/src/identity/oauth/create-oauth-handlers.ts
52080
52210
  import { verifyOAuthQueryParams } from "@better-auth/oauth-provider";
52081
- import * as z91 from "zod";
52211
+ import * as z92 from "zod";
52082
52212
 
52083
52213
  // packages/daemon/src/identity/oauth/build-bad-token-request.ts
52084
52214
  function buildBadTokenRequest() {
@@ -52306,14 +52436,14 @@ function expandScopes(asked) {
52306
52436
  }
52307
52437
 
52308
52438
  // packages/daemon/src/platform/http/render-html.ts
52309
- import { P as P4, match as match14 } from "ts-pattern";
52439
+ import { P as P4, match as match15 } from "ts-pattern";
52310
52440
  var MARKUP = Symbol("markup");
52311
52441
  function renderHTML(strings, ...parts) {
52312
52442
  const html = parts.reduce((text, part, index) => `${text}${toHTML(part)}${strings[index + 1] ?? ""}`, strings[0] ?? "");
52313
52443
  return { [MARKUP]: true, html };
52314
52444
  }
52315
52445
  function toHTML(part) {
52316
- return match14(part).with(P4.string, (text) => escapeHTML(text)).with(P4.array(), (list) => list.map((each) => each.html).join("")).with({ html: P4.string }, (markup) => markup.html).exhaustive();
52446
+ return match15(part).with(P4.string, (text) => escapeHTML(text)).with(P4.array(), (list) => list.map((each) => each.html).join("")).with({ html: P4.string }, (markup) => markup.html).exhaustive();
52317
52447
  }
52318
52448
  function escapeHTML(text) {
52319
52449
  return text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
@@ -52450,9 +52580,9 @@ var MINUTE_MS2 = 60000;
52450
52580
  var CONSENT_MS = 10 * MINUTE_MS2;
52451
52581
  var MAX_FORM_BYTES = 16 * 1024;
52452
52582
  var METADATA_HEADERS = { "cache-control": "no-store" };
52453
- var PKCEMissSchema = z91.object({
52454
- error: z91.literal("invalid_request"),
52455
- error_description: z91.literal("code verification failed")
52583
+ var PKCEMissSchema = z92.object({
52584
+ error: z92.literal("invalid_request"),
52585
+ error_description: z92.literal("code verification failed")
52456
52586
  });
52457
52587
  function createOAuthHandlers(deps) {
52458
52588
  const host = new URL(deps.origin).host;
@@ -53144,8 +53274,8 @@ function loadOrCreateHostId(dataDir) {
53144
53274
 
53145
53275
  // packages/daemon/src/network/tailnet-names/oauth-credential.ts
53146
53276
  import { readFileSync as readFileSync29, statSync as statSync14 } from "fs";
53147
- import * as z92 from "zod";
53148
- var CredentialSchema = z92.object({ clientId: z92.string().min(1), clientSecret: z92.string().min(1) });
53277
+ import * as z93 from "zod";
53278
+ var CredentialSchema = z93.object({ clientId: z93.string().min(1), clientSecret: z93.string().min(1) });
53149
53279
  function readOAuthCredential(path) {
53150
53280
  const mode = statSync14(path).mode & 511;
53151
53281
  if ((mode & 63) !== 0) {
@@ -53166,17 +53296,17 @@ function readJson(path) {
53166
53296
  }
53167
53297
 
53168
53298
  // packages/daemon/src/host-net/net/tailscale-serve.ts
53169
- import * as z93 from "zod";
53170
- var HandlerSchema = z93.object({ Proxy: z93.string().optional() });
53171
- var WebSchema = z93.object({
53172
- Handlers: z93.record(z93.string(), HandlerSchema).nullable().optional()
53299
+ import * as z94 from "zod";
53300
+ var HandlerSchema = z94.object({ Proxy: z94.string().optional() });
53301
+ var WebSchema = z94.object({
53302
+ Handlers: z94.record(z94.string(), HandlerSchema).nullable().optional()
53173
53303
  });
53174
- var ServiceConfigSchema = z93.object({
53175
- Web: z93.record(z93.string(), WebSchema).nullable().optional()
53304
+ var ServiceConfigSchema = z94.object({
53305
+ Web: z94.record(z94.string(), WebSchema).nullable().optional()
53176
53306
  });
53177
- var ServeStatusSchema = z93.object({
53178
- TCP: z93.record(z93.string(), z93.unknown()).optional(),
53179
- Services: z93.record(z93.string(), ServiceConfigSchema).nullable().optional()
53307
+ var ServeStatusSchema = z94.object({
53308
+ TCP: z94.record(z94.string(), z94.unknown()).optional(),
53309
+ Services: z94.record(z94.string(), ServiceConfigSchema).nullable().optional()
53180
53310
  });
53181
53311
  function parseServeStatus(json) {
53182
53312
  try {
@@ -53227,17 +53357,17 @@ function createServiceServe(run = runChecked) {
53227
53357
  }
53228
53358
 
53229
53359
  // packages/daemon/src/network/tailnet-names/services-api.ts
53230
- import * as z94 from "zod";
53360
+ import * as z95 from "zod";
53231
53361
  var TAILSCALE_API = "https://api.tailscale.com/api/v2";
53232
53362
  var TOKEN_MARGIN_MS = 60000;
53233
- var ServiceSchema2 = z94.object({
53234
- name: z94.string(),
53235
- comment: z94.string().optional(),
53236
- ports: z94.array(z94.string()).readonly().optional(),
53237
- tags: z94.array(z94.string()).readonly().nullable().optional()
53363
+ var ServiceSchema2 = z95.object({
53364
+ name: z95.string(),
53365
+ comment: z95.string().optional(),
53366
+ ports: z95.array(z95.string()).readonly().optional(),
53367
+ tags: z95.array(z95.string()).readonly().nullable().optional()
53238
53368
  }).readonly();
53239
- var ServiceListSchema2 = z94.object({ vipServices: z94.array(ServiceSchema2).nullable().optional() });
53240
- var TokenSchema3 = z94.object({ access_token: z94.string(), expires_in: z94.number().positive() });
53369
+ var ServiceListSchema2 = z95.object({ vipServices: z95.array(ServiceSchema2).nullable().optional() });
53370
+ var TokenSchema3 = z95.object({ access_token: z95.string(), expires_in: z95.number().positive() });
53241
53371
 
53242
53372
  class TailscaleApiError extends Error {
53243
53373
  status;
@@ -53326,7 +53456,7 @@ function createServicesApi(options) {
53326
53456
  }
53327
53457
  };
53328
53458
  }
53329
- var ErrorSchema = z94.object({ message: z94.string() });
53459
+ var ErrorSchema = z95.object({ message: z95.string() });
53330
53460
  function readErrorText(text) {
53331
53461
  try {
53332
53462
  return ErrorSchema.parse(JSON.parse(text)).message;
@@ -53753,14 +53883,14 @@ function formatAcmeError(error) {
53753
53883
  // packages/daemon/src/network/https/acme/cert-store.ts
53754
53884
  import { existsSync as existsSync23, mkdirSync as mkdirSync24, readFileSync as readFileSync30, rmSync as rmSync29 } from "fs";
53755
53885
  import { join as join37 } from "path";
53756
- import * as z95 from "zod";
53757
- var AttemptStateSchema = z95.object({
53758
- failures: z95.int().nonnegative(),
53759
- lastAttemptAt: z95.number().nullable(),
53760
- lastError: z95.string().nullable()
53886
+ import * as z96 from "zod";
53887
+ var AttemptStateSchema = z96.object({
53888
+ failures: z96.int().nonnegative(),
53889
+ lastAttemptAt: z96.number().nullable(),
53890
+ lastError: z96.string().nullable()
53761
53891
  });
53762
- var AccountSchema = z95.object({ directoryUrl: z95.string(), url: z95.string(), keyPem: z95.string() });
53763
- var LegacyAccountSchema = z95.object({ directoryUrl: z95.string(), url: z95.string() });
53892
+ var AccountSchema = z96.object({ directoryUrl: z96.string(), url: z96.string(), keyPem: z96.string() });
53893
+ var LegacyAccountSchema = z96.object({ directoryUrl: z96.string(), url: z96.string() });
53764
53894
  var NO_ATTEMPTS = { failures: 0, lastAttemptAt: null, lastError: null };
53765
53895
  function createCertStore(dataDir) {
53766
53896
  const directory = join37(dataDir, "tls");
@@ -53898,7 +54028,7 @@ function createChalltestsrvProvider(apiUrl) {
53898
54028
  }
53899
54029
 
53900
54030
  // packages/daemon/src/network/https/dns/cloudflare-provider.ts
53901
- import * as z96 from "zod";
54031
+ import * as z97 from "zod";
53902
54032
 
53903
54033
  // packages/daemon/src/network/https/dns/wait-for-txt.ts
53904
54034
  import { Resolver as Resolver2 } from "dns/promises";
@@ -53960,30 +54090,30 @@ var CLOUDFLARE_API = "https://api.cloudflare.com/client/v4";
53960
54090
  var TXT_TTL_S = 60;
53961
54091
  var A_TTL_S = 300;
53962
54092
  var PAGE_SIZE = 500;
53963
- var ApiErrorSchema = z96.object({ code: z96.number().optional(), message: z96.string() });
53964
- var EnvelopeSchema = z96.object({
53965
- success: z96.boolean(),
53966
- errors: z96.array(ApiErrorSchema).default([]),
53967
- result: z96.unknown().optional(),
53968
- result_info: z96.object({ page: z96.number(), total_pages: z96.number() }).optional()
54093
+ var ApiErrorSchema = z97.object({ code: z97.number().optional(), message: z97.string() });
54094
+ var EnvelopeSchema = z97.object({
54095
+ success: z97.boolean(),
54096
+ errors: z97.array(ApiErrorSchema).default([]),
54097
+ result: z97.unknown().optional(),
54098
+ result_info: z97.object({ page: z97.number(), total_pages: z97.number() }).optional()
53969
54099
  });
53970
- var ZoneSchema = z96.object({
53971
- id: z96.string(),
53972
- name: z96.string(),
53973
- name_servers: z96.array(z96.string())
54100
+ var ZoneSchema = z97.object({
54101
+ id: z97.string(),
54102
+ name: z97.string(),
54103
+ name_servers: z97.array(z97.string())
53974
54104
  });
53975
- var RecordSchema = z96.object({
53976
- id: z96.string(),
53977
- name: z96.string().optional(),
53978
- type: z96.string().optional(),
53979
- content: z96.string(),
53980
- proxied: z96.boolean().optional(),
53981
- comment: z96.string().nullable().optional()
54105
+ var RecordSchema = z97.object({
54106
+ id: z97.string(),
54107
+ name: z97.string().optional(),
54108
+ type: z97.string().optional(),
54109
+ content: z97.string(),
54110
+ proxied: z97.boolean().optional(),
54111
+ comment: z97.string().nullable().optional()
53982
54112
  });
53983
54113
  var MANAGED_COMMENT = "managed by impd";
53984
54114
  var ADDRESS_TYPES = new Set(["A", "AAAA", "CNAME"]);
53985
- var ZoneListSchema = z96.array(ZoneSchema);
53986
- var RecordListSchema = z96.array(RecordSchema);
54115
+ var ZoneListSchema = z97.array(ZoneSchema);
54116
+ var RecordListSchema = z97.array(RecordSchema);
53987
54117
  function createCloudflareProvider(options) {
53988
54118
  const base = options.apiUrl ?? CLOUDFLARE_API;
53989
54119
  const send = options.fetch ?? fetch;
@@ -56380,6 +56510,7 @@ async function stopImpd(parts, options) {
56380
56510
  if (imps !== undefined) {
56381
56511
  state.settled = options.sleepImps ? await runStep("sleep", readLeftMs(), () => imps.sleepAllImps()) : await runStep("lifecycle", readLeftMs(), () => imps.waitForLifecycle());
56382
56512
  await runStep("templates", readStepMs(), () => imps.bootTemplates?.stop());
56513
+ await runStep("memory-warms", readStepMs(), () => imps.memoryWarm?.stopAll());
56383
56514
  if (options.sleepImps) {
56384
56515
  const sleptMs = Math.round(performance.now() - started);
56385
56516
  getImpdLogger("stop").info("every imp asleep in {sleptMs}ms", { sleptMs: String(sleptMs) });
@@ -56479,8 +56610,8 @@ import {
56479
56610
  statSync as statSync15
56480
56611
  } from "fs";
56481
56612
  import { basename as basename5, dirname as dirname11, join as join39 } from "path";
56482
- import * as z97 from "zod";
56483
- var CopiesSchema = z97.record(z97.string(), z97.object({ ino: z97.string(), ctimeNs: z97.string(), size: z97.string() }));
56613
+ import * as z98 from "zod";
56614
+ var CopiesSchema = z98.record(z98.string(), z98.object({ ino: z98.string(), ctimeNs: z98.string(), size: z98.string() }));
56484
56615
  function createXfsBackups(ctx) {
56485
56616
  const backup = buildBackupPaths(ctx.dataDir);
56486
56617
  const freshCopies = new Set;
@@ -59156,6 +59287,45 @@ log tail`);
59156
59287
  };
59157
59288
  }
59158
59289
 
59290
+ // packages/daemon/src/test-utils/vm/create-stub-uffd-handler.ts
59291
+ import { existsSync as existsSync34, readFileSync as readFileSync39, writeFileSync as writeFileSync16 } from "fs";
59292
+ import { join as join49 } from "path";
59293
+ import * as z99 from "zod";
59294
+ var StartSchema = z99.object({
59295
+ options: z99.object({
59296
+ socket: z99.string().optional(),
59297
+ uid: z99.string().optional(),
59298
+ gid: z99.string().optional()
59299
+ }),
59300
+ served: z99.string()
59301
+ });
59302
+ var WarmRunSchema = z99.object({
59303
+ mode: z99.enum(["--count-data", "--warm"]),
59304
+ memFile: z99.string(),
59305
+ pid: z99.int()
59306
+ });
59307
+ function createStubUffdHandler(directory, mode = "serve") {
59308
+ const path = join49(directory, `uffd-handler-${mode}`);
59309
+ const recorded = join49(directory, `uffd-handler-${mode}.starts`);
59310
+ const warmAnswer = join49(directory, `uffd-handler-${mode}.warm.json`);
59311
+ const script = join49(import.meta.dir, "run-stub-uffd-handler.ts");
59312
+ writeFileSync16(path, `#!/bin/sh
59313
+ exec '${process.execPath}' '${script}' '${mode}' '${recorded}' '${warmAnswer}' "$@"
59314
+ `, { mode: 493 });
59315
+ return {
59316
+ path,
59317
+ readStarts: () => readRecords(recorded, StartSchema),
59318
+ readWarmRuns: () => readRecords(`${recorded}.warms`, WarmRunSchema),
59319
+ answerWarm: (answer) => {
59320
+ writeFileSync16(warmAnswer, JSON.stringify(answer));
59321
+ }
59322
+ };
59323
+ }
59324
+ function readRecords(path, schema) {
59325
+ return existsSync34(path) ? readFileSync39(path, "utf8").trimEnd().split(`
59326
+ `).map((line) => schema.parse(JSON.parse(line))) : [];
59327
+ }
59328
+
59159
59329
  // packages/daemon/src/test-utils/start-test-impd.ts
59160
59330
  var FAKE_VM_RAM_MIB = 300;
59161
59331
  var FAKE_VM_RSS_MIB = 340;
@@ -59172,6 +59342,9 @@ async function startTestImpd(stack, options = {}) {
59172
59342
  if (options.dataDir === undefined) {
59173
59343
  stack.defer(() => rm2(dataDir, { recursive: true, force: true }));
59174
59344
  }
59345
+ const handlerDir = mkdtempSync(`${tmpdir()}/${formatRunPrefix(readRunOwner())}uffd-handler-`);
59346
+ stack.defer(() => rm2(handlerDir, { recursive: true, force: true }));
59347
+ const uffdHandler = createStubUffdHandler(handlerDir);
59175
59348
  const db = await openMigratedCopy();
59176
59349
  stack.defer(async () => {
59177
59350
  await db.destroy();
@@ -59190,6 +59363,7 @@ async function startTestImpd(stack, options = {}) {
59190
59363
  IMP_BROKER_PORT: String(ports.take()),
59191
59364
  IMP_EGRESS_DNS_PORT: String(ports.take()),
59192
59365
  IMP_SSH_PORT: "0",
59366
+ IMP_UFFD_HANDLER: uffdHandler.path,
59193
59367
  ...options.env
59194
59368
  }),
59195
59369
  defaultDiskBytes: 0
@@ -59224,7 +59398,7 @@ async function startTestImpd(stack, options = {}) {
59224
59398
  const createSystemDrive = (drive) => {
59225
59399
  const identity = buildTestIdentity(dataDir, drive);
59226
59400
  mkdirSync31(buildSystemDrivesDir(dataDir), { recursive: true });
59227
- writeFileSync16(identity.systemDrivePath, drive);
59401
+ writeFileSync17(identity.systemDrivePath, drive);
59228
59402
  return identity;
59229
59403
  };
59230
59404
  const host = { identity: createSystemDrive(TEST_DRIVE) };
@@ -59398,6 +59572,7 @@ async function startTestImpd(stack, options = {}) {
59398
59572
  db,
59399
59573
  dataDir,
59400
59574
  fake,
59575
+ uffdHandler,
59401
59576
  tickers,
59402
59577
  taps,
59403
59578
  removedTaps,
@@ -59416,7 +59591,7 @@ async function startTestImpd(stack, options = {}) {
59416
59591
  clock.offsetMs += durationMs;
59417
59592
  },
59418
59593
  setClock: (nowMs) => {
59419
- invariant7(options.frozenClockMs !== undefined, "setClock needs a frozen clock");
59594
+ invariant8(options.frozenClockMs !== undefined, "setClock needs a frozen clock");
59420
59595
  clock.frozenAt = nowMs;
59421
59596
  clock.offsetMs = 0;
59422
59597
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@impz/testing",
3
- "version": "6.8.1",
3
+ "version": "6.9.1",
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.8.1"
46
+ "@impz/client": "6.9.1"
47
47
  },
48
48
  "engines": {
49
49
  "bun": ">=1.4.3"