Cadvisor
cAdvisor container metrics for swamp — deploy a cAdvisor container over SSH, wire it in as a VictoriaMetrics scrape target, and query live and historical container resource stats (memory, CPU, network).
Model:
@magistr/cadvisor—deploy(idempotent: run the cAdvisor container and append a scrape job to the VictoriaMetrics prometheus config),status(report container + scrape-config state),current-metrics(per-container memory/CPU/network straight from the cAdvisor/api/v1.3/dockerAPI),top-memory(top memory consumers over a lookback window via the VictoriaMetrics range-query API), andremove(tear down the container and scrape config).
Global Arguments
| Argument | Type | Description |
|---|---|---|
| host | string | Docker host (IP or hostname) |
| username | string | SSH username |
| cadvisorPort | number | cAdvisor exposed port |
| vmComposeDir | string | Path to VictoriaMetrics docker-compose directory on the host |
| vmComposeFile | string | VM compose file name |
| vmScrapeConfig | string | VM prometheus scrape config file name |
| vmPort | number | VictoriaMetrics HTTP API port |
Resources
2026.08.02.1
Fixes all six remaining bugs tracked in the local cadvisor-latent-bugs
@magistr/issue-lifecycle model (never filed to the swamp.club Lab, per
CLAUDE.md's Anti-Bypass rule) — all 7 cadvisor-latent-bugs are now CLOSED. Every
characterization pin that asserted the buggy behavior is flipped to assert the
fixed behavior; benign/frozen contract tests and the LB1 shellEsc hardening
stay green, unchanged except where noted below.
- Fragile
sedteardown range-delete (bug #2, MED), fixed —remove()'s scrape-config cleanup previously chained threesed -icalls, including a range-delete keyed on thecadvisorSUBSTRING and an unanchored- .*:8080port pattern with no job-name anchoring: a differently named job that merely contained "cadvisor", or that happened to expose port 8080, was silently deleted alongside the real cadvisor job. Replaced with a job-scoped read/filter/heredoc-rewrite (mirroringdeploy()'s own read/heredoc-append idiom) built on a new pure helper,removeCadvisorJob(config), that drops only the block starting at a line matching- job_name: cadvisor(plus its more-indented children, up to the next sibling- job_name:or EOF) and the one orphaned preceding blank line.remove()stays unconditional (no existence check added) — it now issues 4 SSH calls (stop/rm, read, rewrite, VM restart) instead of 3. cpuPercentnot normalized per container core count (bug #3, MED), fixed — the computednumCores(spec.cpu.limit || per_cpu_usage.length || 1, previously named_numCoresand discarded) is now applied:cpuPercent = (cpuDelta / (timeDelta * 1e6)) * 100 / numCores. A core-limited container no longer reads as if it owned the whole host (e.g. a 2-core container's 100%-host-relative delta now reports 50%, not 100%).- Empty (but present)
aliasesarray collapsed the name to"unknown"(bug #4, LOW), fixed —info.aliases?.[0] ?? path.split("/").pop() ?? "unknown"now falls back to the cgroup path wheneveraliases[0]is missing, whetheraliasesis absent OR present-but-empty, instead of only when it's absent entirely. - Unclamped counter-reset deltas went negative (bug #5, LOW), fixed —
cpuDelta,rxDelta, andtxDeltaare now each clamped withMath.max(0, ...). A container restart or counter wraparound (current sample lower than the previous one) now reports0, never a nonsensical negative rate. Positive/happy-path deltas are unaffected. README.mddocumented a staletypeVersion(bug #6, LOW), fixed — the instance-configuration example'stypeVersionis updated to the currently shipped2026.08.02.1.top-memoryhardcoded the VictoriaMetrics port (bug #7, LOW), fixed — a newvmPortglobal argument (z.number().default(8428), mirroring the sibling@magistr/victoriametricsmodel'sportfield) replaces the hardcodedconst vmPort = 8428intop-memory. Backward-compatible: the default preserves the existing port-8428 behavior for every instance that doesn't set it.- Pin flips: the
remove()happy-path and error-path methods tests, the LB2 "SAME commands unconditionally" adversarial pin (now "SAME FOUR commands"), the counter-reset and empty-aliases adversarial pins, the coverage suite's cpuPercent core-count guard (now inverted: 1 core stays at 100%, 16 cores divides to 6.25%), and the contract suite's top-memory port message are all re-baselined to the fixed behavior. New tests: a job-scoping adversarial pin (a sibling job sharing cadvisor's port, and a job whose name merely contains the substring "cadvisor", both surviveremoveCadvisorJobintact) plus a byte-exactremoveCadvisorJob(scrape-config-after.txt) === scrape-config-before.txtround-trip unit assertion; a coverage guard for theper_cpu_usage.lengthnumCores fallback branch; and a contract test for a non-defaultvmPort. - LB2 shifts
remove()'s SSH call indices (+1 for the read, +1 for the rewrite); the LB1 "hardened: contrast" pin's positionalsshCommandOf(calls[2])read is updated tocalls[3]to keep asserting the VM-restart command post-shift — the LB1 fix itself (and its other,.find-based pins) stays green and unweakened. - Every suite's
GLOBAL_ARGStest fixture gainsvmPort: 8428sotop-memorybuilds a valid URL under the new schema (an undefinedvmPortwould throw buildinghttp://<host>:undefined/...). - Model
versionandmanifest.yamlbumped2026.08.01.1->2026.08.02.1(in sync). Added anupgrades[]array (cadvisor had none before) with a
Notes trimmed at a line boundary to fit the registry's 4900-byte per-version cap. Full section: https://github.com/umag/swamp-workspace/blob/d850d8e8372d4c0008c9245959a090b37095de7a/cadvisor/CHANGELOG.md
2026.08.01.1
Closes the HIGH remote-shell command-injection finding (bug #1) tracked in the
local cadvisor-latent-bugs @magistr/issue-lifecycle model — not filed to the
swamp.club Lab, per CLAUDE.md's Anti-Bypass rule; Lab is @swamp/* product
only.
- Remote-shell command injection (HIGH), closed —
runSsh()hands its built command string to the REMOTE shell verbatim, andvmComposeDir,vmScrapeConfig, andvmComposeFile(admin-configuredglobalArguments) were interpolated unescaped into that string at everycat/heredoc-append/cd && docker compose/sed -isite indeploy,status, andremove. A canonicalshellEschelper (copied verbatim fromfirecracker/fc-task-server: single-quote-wrap,'->'\'') is now applied to all three values at every remote-command interpolation site. Defense-in-depth, not an externally-exploitable hole: these three values are read only fromcontext.globalArgs(GlobalArgsSchema) and every method that uses them takes no per-invocation caller arguments, so this closes a hostile-admin or misconfiguration vector, not an external attack surface. The${username}@${host}ssh-destination argv element was already safe (one localDeno.Commandargv slot, never remote-shell-interpreted) and is unchanged. Thedeployheredoc BODY (file data, not a shell token) is deliberately left unescaped — only the heredoc TARGET path is wrapped. Behavior-preserving for legitimate metacharacter-free paths. - The four adversarial Site-2 characterization tests, the methods-suite
deploy/removeexact-command assertions, and everycat-equality stub matcher are re-baselined to the single-quote-wrapped expected strings. Coverage, property-invariant-flow, and contract-fixture suites usestartsWith/includesmatchers on metacharacter-free arguments and stay green unchanged, demonstrating behavior preservation. - Model
versionandmanifest.yamlbumped2026.07.16.2->2026.08.01.1(in sync). The six remaining sibling latent bugs (fragilesedrange-delete, unnormalizedcpuPercent, empty-aliases name collapse, unclamped counter-reset deltas, READMEtypeVersiondrift, hardcoded VM port) remain deferred and pinned incadvisor-latent-bugs, unchanged.
This release also carries the wave-2c five-suite test backfill
(ext-quality-test-backfill) that established the characterization suites the
hardening above re-baselines:
- Added
extensions/models/cadvisor_test.ts(contract-fixture),cadvisor_methods_test.ts(methods),cadvisor_adversarial_test.ts(adversarial),cadvisor_coverage_test.ts(coverage),cadvisor_property_test.ts(property-invariant-flow) — 0 tests before this change, 64 after.cadvisor.tsis a DUAL-boundary model (SSH viaDeno.Command("ssh")and HTTP viafetch), so every suite stubs both: thetalos-nodeDeno as unknown as Record<string, unknown>FakeCommand bridge for the SSH side, and theporkbunfetch-stub pattern for the HTTP side.deploy's 5-second verifysetTimeoutis neutralized (withSyncSetTimeout, thetalos-nodepattern) so the suite runs synchronously. - Test-review round 1 (autonomous, 0 CRIT + 1 HIGH) added: a
remove()error-path test — none of its three SSH calls are guarded by try/catch, so a mid-teardown failure throws and leaves NO status resource written at all (the HIGH finding, since the methods suite otherwise only coveredremove()'s happy path); twostatus()mixed-success/failure tests (its two SSH calls are independently try/caught); and the deploy idempotency property now also asserts on the writtenstatusresource'srunning/scrapeConfiguredfields, not just internal SSH call counts (the MEDIUM finding). - Added
fixtures/— pure doc-derived, synthetic cAdvisor/api/v1.3/dockerand VictoriaMetrics/api/v1/query_rangewire-shape fixtures (cadvisor-docker.json,vm-query-range.json) plus a prometheus scrape-config before/after text pair (scrape-config-before.txt,scrape-config-after.txt) andPROVENANCE.md. No live call was made against any real cAdvisor/VictoriaMetrics instance over either boundary (HTTP metrics or SSH config/docker-inspect); every value is synthetic (RFC 2606host.example.com, synthetic 64-hex-char container paths, the real published cAdvisor "no memory limit" sentinel constant used only as a documented value, never a live measurement). - The contract-fixture suite pins the RAW cAdvisor/VictoriaMetrics INPUT wire
keyset + types (not a written-resource-equals-fixture passthrough, unlike
porkbun—cadvisor.tstransforms bytes to MB/percent/rates, so the transform itself is pinned in the methods and coverage suites instead). - The adversarial suite separates cadvisor.ts's TWO SSH interpolation sites: the
${username}@${host}s
Release 2026.07.16.2 — align model versions with manifests
Maintenance release across the @magistr extensions. For most packages this
carries no functional change: the only edit is the model's version: field,
brought back in line with its manifest version so the published model type
version and the package version no longer drift.
Functional changes in this release are limited to:
anime-cron: normalizeTitle now strips a ": subtitle" suffix and a trailing parenthesized year before comparison, fixing dedup false-misses where the torrent title carries a subtitle or year that the AniList romaji does not.
arckit: first publish. Standalone ArcKit port — a 12-phase architecture governance state machine with 65 bundled templates, driven by a bundled skill.
Also tracks three extensions (kaiten, observability-agent, music-library) that previously existed only as untracked working-tree directories, recovered from stashes.
Added 1 models
Merge pull request #5 from umag/extensions/jscad-stl-pair
extensions: add 15 more @magistr extensions + auto-discover CI
- Has README or module doc2/2earned
- README has a code example1/1earned
- README is substantive1/1earned
- Most symbols documented1/1earned
- No slow types (deprecated)1/1earned
- Dependencies pass trust audit2/2earned
- Has description1/1earned
- Platform support declared (or universal)2/2earned
- License declared1/1earned
- Verified public repository2/2earned