@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.
- package/dist/addon-runner.js +1 -1
- package/dist/addon-runner.mjs +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +1 -1
- package/dist/builtins/device-manager/device-manager.addon.js +2 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +1 -1
- package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/index.d.ts +1 -1
- package/dist/builtins/sqlite-storage/index.js +2 -0
- package/dist/builtins/sqlite-storage/index.mjs +2 -2
- package/dist/builtins/sqlite-storage/query-profiler.d.ts +21 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
- package/dist/builtins/storage-orchestrator/location-occupancy.d.ts +19 -0
- package/dist/builtins/storage-orchestrator/storage-cleanup-coordinator.d.ts +68 -0
- package/dist/builtins/storage-orchestrator/storage-migration-coordinator.d.ts +14 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +13 -8
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +441 -100
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +443 -100
- package/dist/builtins/storage-orchestrator/storage-orchestrator.service.d.ts +11 -13
- package/dist/builtins/system-config/system-config.addon.js +1 -1
- package/dist/builtins/system-config/system-config.addon.mjs +1 -1
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{dist-BhE8zNfY.js → dist-CFTKQGym.js} +185 -7
- package/dist/{dist-BpsHt11f.mjs → dist-Dw9cm1NS.mjs} +180 -8
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/dist/kernel/deps/manifest-system-deps.d.ts +5 -2
- package/dist/kernel/deps/system-package-allowlist.d.ts +12 -0
- package/dist/kernel/deps/system-package-broker.d.ts +31 -0
- package/dist/kernel/deps/system-package-client.d.ts +9 -0
- package/dist/{manifest-system-deps-CJLqfJUs.js → manifest-system-deps-BIxY1Y5e.js} +140 -5
- package/dist/{manifest-system-deps-Bk_XLYbB.mjs → manifest-system-deps-DTz_zNQf.mjs} +142 -6
- package/dist/{retired-settings-keys-CqDbI-vK.js → retired-settings-keys-dehyu2N3.js} +1 -1
- package/dist/{retired-settings-keys-DLwieFXR.mjs → retired-settings-keys-diW1NmyP.mjs} +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "./dist-
|
|
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
|
|
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
|
-
|
|
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,
|