fix(specs): report Docker resource availability accurately, not as a reservation#31
Open
Sentinel-Bluebuilder wants to merge 2 commits into
Conversation
…reservation
The specs:v1 on-chain memo exposes cr/rr alongside total host cores/RAM. Both
were labeled "reserved for the dvpn-node container", but the node container is
launched with no CPU or memory cap (no HostConfig Memory/NanoCpus), so nothing
is actually reserved. The values were sourced from `docker info` NCPU/MemTotal
(the Docker engine totals) which is the real ceiling a container can draw from,
not a reservation.
On Windows this produced a concrete inaccuracy: the engine runs inside the WSL2
VM, whose default RAM allocation is min(50% host, 8 GB). A 16 GB host therefore
published rr=16 GB while the container could only ever see ~8 GB.
This change keeps the (correct) engine-derived values and fixes the semantics:
cr/rr now mean "available to the container (Docker/WSL2 VM)", with r/c as the
host totals, so the two fields carry distinct, meaningful info instead of
looking like redundant duplicates. No runtime/behavior change; the node still
runs uncapped.
- node-specs.ts: rewrite memo schema doc; relabel captureLocalSpecs comment;
captureRemoteSpecs now probes `docker info --format {{.NCPU}}|{{.MemTotal}}`
over SSH so remote reports the engine view too (bail-safe, falls back to
/proc host totals when Docker is unreachable).
- shared/types.ts: NodeSpecsSnapshot doc updated.
- Renderer labels updated to "available": OnChainSpecs (explainer, meter,
field descs), System (Docker resource cells), ManageDocker (card title +
stats), NodeDetails (RAM available), DeployLocal (explainer bullet).
Does not set HostConfig limits; user-settable reservations is a separate,
deferred change.
better-sqlite3 is a single-ABI native addon. The shipping app builds it for Electron's ABI via `npm run rebuild:electron`, which the vitest runner (plain Node, a different NODE_MODULE_VERSION) physically cannot dlopen. When that's the case the metrics store degrades to a no-op, so the assertions silently "passed" against a disabled store before and fail (0 rows) when the binary happens to match neither runtime. Probe the binding once (open an in-memory DB to force the dlopen) and describe.skip the suite WITH A logged reason when it can't load, instead of running against a dead store. The full logic still runs whenever the runner ABI matches the built binary (`npm rebuild better-sqlite3`, or under Electron).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The
specs:v1on-chain memo publishescr/rrnext to total host cores/RAM.Both were labeled "reserved for the dvpn-node container", but nothing is
actually reserved — the node container is launched with no CPU or memory cap
(no
HostConfig.Memory/NanoCpus). The values came fromdocker infoNCPU/MemTotal, i.e. the Docker engine totals — the real ceiling acontainer can draw from, not a reservation.
On Windows this is a concrete inaccuracy: the engine runs inside the WSL2 VM,
whose default RAM allocation is
min(50% host, 8 GB). A 16 GB host thereforepublished
rr = 16 GBwhile the container could only ever see ~8 GB.This PR keeps the (correct) engine-derived values and fixes the semantics +
labels:
cr/rrnow mean "available to the container (Docker/WSL2 VM)",with
r/cas the host totals — so the two fields carry distinct, meaningfulinformation instead of looking like redundant duplicates.
No runtime/behavior change. The node still runs uncapped and earns at full
capacity. Setting real
HostConfiglimits (user-settable reservations) is aseparate, deliberately deferred change.
Changes
node-specs.ts— rewrite the memo schema doc with the host-vs-VMrationale; relabel
captureLocalSpecs(values unchanged);captureRemoteSpecsnow probes
docker info --format "{{.NCPU}}|{{.MemTotal}}"over SSH soremote nodes report the engine view too. Bail-safe — falls back to
/prochost totals when Docker isn't reachable over SSH (on a single-purpose VPS the
engine == host, so that's the right default).
shared/types.ts—NodeSpecsSnapshotdoc updated.OnChainSpecs(explainer text, themeter's "Available / Total", field descriptions),
System(Docker resourcecells),
ManageDocker(card title + stats),NodeDetails("RAM available"),DeployLocal(explainer bullet).Secondary commit
test(metrics)—better-sqlite3is a single-ABI native addon built forElectron's ABI (
npm run rebuild:electron), which the vitest runner (plainNode) can't
dlopen. The metrics suite previously ran against the no-opdegraded store and could fail with
0 rows. It now probes the binding onceand
describe.skips with a logged reason when the ABI doesn't match,while still running the full logic when it does. Keeps the suite green and
honest off
main.Verification
npx vitest run→ 43 passed, 3 skipped (the metrics suite, ABI mismatch,skip reason logged), 0 failed.