@camstack/system 1.2.164 → 1.2.166

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 (68) hide show
  1. package/dist/addon-runner.js +1 -1
  2. package/dist/addon-runner.mjs +1 -1
  3. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  4. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  5. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  6. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  7. package/dist/builtins/alerts/alerts.addon.js +1 -1
  8. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  9. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
  10. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
  11. package/dist/builtins/console-logging/index.js +1 -1
  12. package/dist/builtins/console-logging/index.mjs +1 -1
  13. package/dist/builtins/core-blocks/core-blocks.addon.js +1 -1
  14. package/dist/builtins/core-blocks/core-blocks.addon.mjs +1 -1
  15. package/dist/builtins/device-manager/device-manager.addon.js +2 -2
  16. package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
  17. package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
  18. package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
  19. package/dist/builtins/hub-forwarder/index.js +1 -1
  20. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  21. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  22. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  23. package/dist/builtins/local-auth/local-auth.addon.js +1 -1
  24. package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
  25. package/dist/builtins/local-network/local-network.addon.js +1 -1
  26. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  27. package/dist/builtins/loki-logging/index.js +1 -1
  28. package/dist/builtins/loki-logging/index.mjs +1 -1
  29. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  30. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  31. package/dist/builtins/platform-probe/index.js +1 -1
  32. package/dist/builtins/platform-probe/index.mjs +1 -1
  33. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  34. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  35. package/dist/builtins/snapshot/index.js +1 -1
  36. package/dist/builtins/snapshot/index.mjs +1 -1
  37. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  38. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  39. package/dist/builtins/sqlite-storage/index.d.ts +1 -1
  40. package/dist/builtins/sqlite-storage/index.js +2 -0
  41. package/dist/builtins/sqlite-storage/index.mjs +2 -2
  42. package/dist/builtins/sqlite-storage/query-profiler.d.ts +21 -0
  43. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
  44. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
  45. package/dist/builtins/storage-orchestrator/location-occupancy.d.ts +19 -0
  46. package/dist/builtins/storage-orchestrator/storage-cleanup-coordinator.d.ts +68 -0
  47. package/dist/builtins/storage-orchestrator/storage-migration-coordinator.d.ts +14 -0
  48. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +13 -8
  49. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +441 -100
  50. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +443 -100
  51. package/dist/builtins/storage-orchestrator/storage-orchestrator.service.d.ts +11 -13
  52. package/dist/builtins/system-config/system-config.addon.js +1 -1
  53. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  54. package/dist/builtins/winston-logging/index.js +1 -1
  55. package/dist/builtins/winston-logging/index.mjs +1 -1
  56. package/dist/{dist-BhE8zNfY.js → dist-CFTKQGym.js} +185 -7
  57. package/dist/{dist-BpsHt11f.mjs → dist-Dw9cm1NS.mjs} +180 -8
  58. package/dist/index.js +2 -2
  59. package/dist/index.mjs +2 -2
  60. package/dist/kernel/deps/manifest-system-deps.d.ts +5 -2
  61. package/dist/kernel/deps/system-package-allowlist.d.ts +12 -0
  62. package/dist/kernel/deps/system-package-broker.d.ts +31 -0
  63. package/dist/kernel/deps/system-package-client.d.ts +9 -0
  64. package/dist/{manifest-system-deps-CJLqfJUs.js → manifest-system-deps-BIxY1Y5e.js} +140 -5
  65. package/dist/{manifest-system-deps-Bk_XLYbB.mjs → manifest-system-deps-DTz_zNQf.mjs} +142 -6
  66. package/dist/{retired-settings-keys-CqDbI-vK.js → retired-settings-keys-dehyu2N3.js} +1 -1
  67. package/dist/{retired-settings-keys-DLwieFXR.mjs → retired-settings-keys-diW1NmyP.mjs} +1 -1
  68. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import "./dist-BpsHt11f.mjs";
1
+ import "./dist-Dw9cm1NS.mjs";
2
2
  import * as crypto$1 from "node:crypto";
3
3
  import { randomBytes, randomUUID } from "node:crypto";
4
4
  import { ensureBinary, ensureFfmpeg, ensurePython, installPythonPackages, installPythonRequirements } from "@camstack/types/node";
@@ -8,6 +8,7 @@ import { isAbsolute, join } from "node:path";
8
8
  import { execFile } from "node:child_process";
9
9
  import { promisify } from "node:util";
10
10
  import * as fs from "node:fs";
11
+ import { existsSync } from "node:fs";
11
12
  import * as os from "node:os";
12
13
  import { tmpdir } from "node:os";
13
14
  import { createServer } from "node:http";
@@ -15,7 +16,7 @@ import * as v8 from "node:v8";
15
16
  import { monitorEventLoopDelay } from "node:perf_hooks";
16
17
  import * as vm from "node:vm";
17
18
  import { BOOT_RECOVERY_BACKOFF_MS, DATAPLANE_SECRET_HEADER, DeviceType, DisposerChain, EventCategory, ReadinessRegistry, asJsonObject, asString, createDeviceProxy, createEventBusSliceSource, deviceOpsCapability, emitReadiness, errMsg, expandCapMethods, readNodePin, scopeKey, sleep, withCapInputDefaults } from "@camstack/types/addon";
18
- import { connect, createServer as createServer$1 } from "node:net";
19
+ import { connect, createConnection, createServer as createServer$1 } from "node:net";
19
20
  import { TRPCClientError, createTRPCClient } from "@trpc/client";
20
21
  //#region src/kernel/event-plane-report.ts
21
22
  /**
@@ -9694,6 +9695,106 @@ async function installManifestPythonDeps(declaration, addonDir, deps, logger) {
9694
9695
  await deps.installPythonRequirements(reqAbs);
9695
9696
  }
9696
9697
  //#endregion
9698
+ //#region src/kernel/deps/system-package-allowlist.ts
9699
+ var DISTRO_PACKAGE_ALLOWLIST = {
9700
+ apt: ["smbclient"],
9701
+ apk: ["samba-client"],
9702
+ dnf: ["samba-client"]
9703
+ };
9704
+ function packageIsAllowlisted(manager, packageName) {
9705
+ if (manager === "brew") return true;
9706
+ if (packageName.length === 0) return false;
9707
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9+._-]*$/.test(packageName)) return false;
9708
+ return DISTRO_PACKAGE_ALLOWLIST[manager].includes(packageName);
9709
+ }
9710
+ //#endregion
9711
+ //#region src/kernel/deps/system-package-broker.ts
9712
+ /**
9713
+ * Who is allowed to run the package manager for this request.
9714
+ *
9715
+ * Apt/apk/dnf need root. In the CamStack container that is the
9716
+ * `camstack-pkgd` helper, not the runner and not hub-main (both uid
9717
+ * 1001). Brew is owned by the logged-in user, so it stays in-process.
9718
+ */
9719
+ function decidePackageInstall(input) {
9720
+ if (input.manager === "brew") return { kind: "local" };
9721
+ if (!packageIsAllowlisted(input.manager, input.packageName)) return {
9722
+ kind: "refuse",
9723
+ reason: "not-allowlisted"
9724
+ };
9725
+ if (!input.helperAvailable) return {
9726
+ kind: "refuse",
9727
+ reason: "helper-unavailable"
9728
+ };
9729
+ return { kind: "helper" };
9730
+ }
9731
+ function pkgdSocketPath() {
9732
+ return process.env["CAMSTACK_PKGD_SOCKET"] ?? "/run/camstack/pkgd.sock";
9733
+ }
9734
+ function privilegedHelperAvailable(socketPath = pkgdSocketPath()) {
9735
+ return existsSync(socketPath);
9736
+ }
9737
+ /**
9738
+ * One JSON object per line. The helper answers one request per connection.
9739
+ */
9740
+ function requestPrivilegedInstall(req, socketPath = pkgdSocketPath(), timeoutMs = 360 * 1e3) {
9741
+ return new Promise((resolve) => {
9742
+ const socket = createConnection({ path: socketPath });
9743
+ const chunks = [];
9744
+ const finish = (result) => {
9745
+ socket.destroy();
9746
+ resolve(result);
9747
+ };
9748
+ const timer = setTimeout(() => {
9749
+ finish({
9750
+ ok: false,
9751
+ error: `privileged helper timed out after ${timeoutMs}ms`
9752
+ });
9753
+ }, timeoutMs);
9754
+ socket.on("connect", () => {
9755
+ socket.write(`${JSON.stringify({
9756
+ v: 1,
9757
+ ...req
9758
+ })}\n`);
9759
+ });
9760
+ socket.on("data", (data) => {
9761
+ chunks.push(data);
9762
+ const text = Buffer.concat(chunks).toString("utf8");
9763
+ const nl = text.indexOf("\n");
9764
+ if (nl === -1) return;
9765
+ clearTimeout(timer);
9766
+ try {
9767
+ const parsed = JSON.parse(text.slice(0, nl));
9768
+ finish({
9769
+ ok: parsed.ok === true,
9770
+ ...parsed.error !== void 0 ? { error: parsed.error } : {}
9771
+ });
9772
+ } catch (err) {
9773
+ finish({
9774
+ ok: false,
9775
+ error: err instanceof Error ? err.message : String(err)
9776
+ });
9777
+ }
9778
+ });
9779
+ socket.on("error", (err) => {
9780
+ clearTimeout(timer);
9781
+ finish({
9782
+ ok: false,
9783
+ error: err.message
9784
+ });
9785
+ });
9786
+ socket.on("end", () => {
9787
+ if (chunks.length === 0) {
9788
+ clearTimeout(timer);
9789
+ finish({
9790
+ ok: false,
9791
+ error: "privileged helper closed without a reply"
9792
+ });
9793
+ }
9794
+ });
9795
+ });
9796
+ }
9797
+ //#endregion
9697
9798
  //#region src/kernel/deps/manifest-system-deps.ts
9698
9799
  /**
9699
9800
  * Auto-install the host binaries declared in an addon's manifest
@@ -9724,6 +9825,9 @@ async function installManifestPythonDeps(declaration, addonDir, deps, logger) {
9724
9825
  * 4. **Platform reality is stated, not assumed.** An unsupported host logs
9725
9826
  * which manager it looked for and continues. Silence would read as
9726
9827
  * "installed".
9828
+ * 5. **Apt is not the runner's.** Distro package managers need root. The
9829
+ * runner and hub-main are uid 1001 (`gosu` in the entrypoint). Apt/apk/dnf
9830
+ * go through `camstack-pkgd` (allowlisted). Brew stays in-process.
9727
9831
  *
9728
9832
  * Every branch that declines to install SAYS SO. A dependency step that
9729
9833
  * produced no line at all is indistinguishable from one that never ran, and
@@ -9746,12 +9850,16 @@ async function installManifestSystemDeps(declaration, logger, options = {}) {
9746
9850
  const detectManager = options.detectManager ?? defaultDetectManager;
9747
9851
  const run = options.run ?? defaultRun;
9748
9852
  const platform = options.platform ?? process.platform;
9853
+ const helperAvailable = options.helperAvailable ?? (async () => privilegedHelperAvailable());
9854
+ const requestInstall = options.requestInstall ?? ((req) => requestPrivilegedInstall(req));
9749
9855
  for (const dep of deps) try {
9750
9856
  await satisfyOne(dep, declaration.id, {
9751
9857
  hasBinary,
9752
9858
  detectManager,
9753
9859
  run,
9754
- platform
9860
+ platform,
9861
+ helperAvailable,
9862
+ requestInstall
9755
9863
  }, logger);
9756
9864
  } catch (err) {
9757
9865
  logger.warn("system dependency step failed", { meta: {
@@ -9789,15 +9897,43 @@ async function satisfyOne(dep, addonId, rt, logger) {
9789
9897
  } });
9790
9898
  return;
9791
9899
  }
9792
- const plan = planFor(manager, packageName);
9900
+ const decision = decidePackageInstall({
9901
+ manager,
9902
+ packageName,
9903
+ helperAvailable: await rt.helperAvailable()
9904
+ });
9905
+ if (decision.kind === "refuse") {
9906
+ const message = decision.reason === "helper-unavailable" ? "system dependency missing and the privileged helper is not running — apt cannot run as uid 1001" : "system dependency missing and the package is not on the helper allowlist";
9907
+ logger.warn(message, { meta: {
9908
+ addonId,
9909
+ binary: dep.binary,
9910
+ manager,
9911
+ package: packageName,
9912
+ reason: decision.reason,
9913
+ ...dep.reason !== void 0 ? { reason: dep.reason } : {}
9914
+ } });
9915
+ return;
9916
+ }
9793
9917
  logger.info("installing system dependency", { meta: {
9794
9918
  addonId,
9795
9919
  binary: dep.binary,
9796
9920
  manager,
9797
- package: packageName
9921
+ package: packageName,
9922
+ via: decision.kind
9798
9923
  } });
9799
9924
  try {
9800
- for (const [command, args] of plan.steps) await rt.run(command, args);
9925
+ if (decision.kind === "helper") {
9926
+ const result = await rt.requestInstall({
9927
+ addonId,
9928
+ binary: dep.binary,
9929
+ manager,
9930
+ packageName
9931
+ });
9932
+ if (!result.ok) throw new Error(result.error ?? "privileged helper refused");
9933
+ } else {
9934
+ const plan = planFor(manager, packageName);
9935
+ for (const [command, args] of plan.steps) await rt.run(command, args);
9936
+ }
9801
9937
  } catch (err) {
9802
9938
  logger.warn("system dependency install failed — the addon loads, its capability must refuse", { meta: {
9803
9939
  addonId,
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-BhE8zNfY.js");
1
+ const require_dist = require("./dist-CFTKQGym.js");
2
2
  //#region src/builtins/sqlite-storage/retired-settings-keys.ts
3
3
  /**
4
4
  * Is THIS node the one whose settings store is the cluster's authority?
@@ -1,4 +1,4 @@
1
- import { Ht as asJsonObject } from "./dist-BpsHt11f.mjs";
1
+ import { Ut as asJsonObject } from "./dist-Dw9cm1NS.mjs";
2
2
  //#region src/builtins/sqlite-storage/retired-settings-keys.ts
3
3
  /**
4
4
  * Is THIS node the one whose settings store is the cluster's authority?
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/system",
3
- "version": "1.2.164",
3
+ "version": "1.2.166",
4
4
  "description": "Core addon for CamStack — builtins, pipeline, process management, auth, logging, events",
5
5
  "keywords": [
6
6
  "camstack",