@kvbox/server 0.5.10 → 0.5.11

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.
@@ -484,6 +484,23 @@ var MachineUsageSchema = z3.object({
484
484
  estimatedStops: z3.number().int(),
485
485
  historyFrom: z3.string().nullable()
486
486
  });
487
+ var GuestStatsSchema = z3.object({
488
+ /** Load average over 1, 5 and 15 minutes. */
489
+ load: z3.tuple([z3.number(), z3.number(), z3.number()]),
490
+ cpus: z3.number().int(),
491
+ memTotalMib: z3.number().int(),
492
+ /** Total minus available: page cache counts as free. */
493
+ memUsedMib: z3.number().int(),
494
+ /** The box's root, which is its overlay disk: the box's own writes, not the shared base. */
495
+ diskTotalBytes: z3.number().int(),
496
+ diskUsedBytes: z3.number().int(),
497
+ uptimeSec: z3.number().int()
498
+ });
499
+ var MachineStatsSchema = z3.object({
500
+ name: z3.string(),
501
+ owner: z3.string(),
502
+ stats: GuestStatsSchema.nullable()
503
+ });
487
504
  var UsageStatusSchema = z3.enum([...BoxStatusSchema.options, "removed"]);
488
505
  var BoxUsageSchema = MachineUsageSchema.omit({ window: true, status: true }).extend({
489
506
  /** The host's box id; a name removed and recreated appears twice, with two ids. */
@@ -943,7 +960,13 @@ function setIdentity(udsPath, id, timeoutMs) {
943
960
  function setAuthorizedKeys(udsPath, lines, timeoutMs) {
944
961
  return agentCall(udsPath, { op: "authorizedKeys", lines: [...lines] }, timeoutMs);
945
962
  }
963
+ async function stats(udsPath, timeoutMs) {
964
+ const reply = GuestStatsSchema.safeParse(await agentCall(udsPath, { op: "stats" }, timeoutMs));
965
+ if (!reply.success) throw new KvboxError(`kvbox-agent sent stats kvbox does not understand: ${reply.error.issues[0]?.message ?? "invalid"}`);
966
+ return reply.data;
967
+ }
946
968
  var isUnknownOp = (err) => /unknown op/.test(err.message ?? "");
969
+ var isNoAgent = (err) => /vsock connect refused|vsock connection closed before the guest accepted|kvbox-agent unreachable: connect (ENOENT|ECONNREFUSED)/.test(err.message ?? "");
947
970
 
948
971
  // src/core/capacity.ts
949
972
  import { cpus, totalmem } from "node:os";
@@ -2548,7 +2571,7 @@ function versionOf(srcFileUrl, injected) {
2548
2571
  }
2549
2572
 
2550
2573
  // src/version.ts
2551
- var VERSION = versionOf(import.meta.url, true ? "0.5.10" : void 0);
2574
+ var VERSION = versionOf(import.meta.url, true ? "0.5.11" : void 0);
2552
2575
 
2553
2576
  // src/caller.ts
2554
2577
  import { createHash as createHash2, timingSafeEqual } from "node:crypto";
@@ -2600,6 +2623,19 @@ function capacityRoutes() {
2600
2623
  // src/routes/machines.ts
2601
2624
  import { Hono as Hono2 } from "hono";
2602
2625
 
2626
+ // src/core/stats.ts
2627
+ var STATS_REPLY_MS = 3e3;
2628
+ async function machineStats(ref, p = paths()) {
2629
+ const m = await getMachine(ref, p);
2630
+ if (m.status !== "running") throw new KvboxError(`${stateMessage(ref, m.status)}; only a running box can say how it is doing`);
2631
+ try {
2632
+ return { name: m.name, owner: m.owner, stats: await stats(p.machine(m.owner, m.name).vsock, STATS_REPLY_MS) };
2633
+ } catch (err) {
2634
+ if (isUnknownOp(err) || isNoAgent(err)) return { name: m.name, owner: m.owner, stats: null };
2635
+ throw err;
2636
+ }
2637
+ }
2638
+
2603
2639
  // src/core/usage.ts
2604
2640
  async function machineUsage(ref, since, p = paths()) {
2605
2641
  const box = await getMachine(ref, p);
@@ -2655,6 +2691,7 @@ function machineRoutes() {
2655
2691
  }
2656
2692
  return c.json(await machineUsage(parseRef(c.req.param("name"), c.get("owner")), from));
2657
2693
  });
2694
+ r.get("/:name/stats", async (c) => c.json(await machineStats(parseRef(c.req.param("name"), c.get("owner")))));
2658
2695
  r.delete("/:name", async (c) => {
2659
2696
  await destroyMachine(parseRef(c.req.param("name"), c.get("owner")));
2660
2697
  return c.body(null, 204);