From c4d1b0ff983706dc51ccf1c8350a14f892418e20 Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Mon, 12 Oct 2026 21:03:11 +0200 Subject: [PATCH] Website: the two download clients on the app page; the campaign's evidence; R-988 filed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The catalog published qBittorrent and Transmission today (app-catalog 9081a47). Here: - two cards in the media category on both language sets, each with the project's own logo, each saying what a closed peer port costs (slower swarms, no incoming peers) - the published count 58 -> 60 on every page that states it, FAQ JSON-LD with its visible twin - documentation/audits/qbittorrent-2026-10-12/: both bench runs, both box walks and verdicts, verify-fixes.json, teardown-newapps.json, and the README brought to its final state - the 2026-09-30 walk harness: a `type: path` deploy field is filled with the drive ROOT — the controller refuses a path inside a drive (409), so the walker could not install any app with a drive field at all - R-988: the Usenet pair (SABnzbd, NZBGet), operator request, not started - STATUS.md and REPORT-newapps-2026-10-12.md Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_0117kRTSgs3rJWUFGxyoWN6Y --- REPORT-newapps-2026-10-12.md | 75 ++ STATUS.md | 30 +- .../pg-last-six-2026-09-30/tools/walk.py | 7 +- .../audits/qbittorrent-2026-10-12/README.md | 111 +-- .../bench/MV-qbittorrent/abort-states.json | 8 + .../bench/MV-qbittorrent/compose-final.log | 4 + .../bench/MV-qbittorrent/engine-state.json | 1 + .../MV-qbittorrent/files-after-detail.json | 7 + .../bench/MV-qbittorrent/files-after.json | 3 + .../MV-qbittorrent/files-before-detail.json | 3 + .../bench/MV-qbittorrent/files-before.json | 3 + .../bench/MV-qbittorrent/memory-samples.json | 762 ++++++++++++++++++ .../bench/MV-qbittorrent/migration-lines.txt | 0 .../bench/MV-qbittorrent/run.log | 60 ++ .../bench/MV-qbittorrent/to-full.log | 4 + .../bench/MV-qbittorrent/to-states.json | 8 + .../bench/MV-qbittorrent/verdict.json | 64 ++ .../qbittorrent/box-verdict-qbittorrent.json | 18 + .../box/qbittorrent/prep.txt | 19 + .../box/qbittorrent/step.txt | 30 + .../box/teardown-newapps.json | 25 + .../box-verdict-transmission.json | 18 + .../box/transmission/prep.txt | 5 + .../box/transmission/step.txt | 29 + .../MV-transmission/abort-states.json | 8 + .../MV-transmission/compose-final.log | 35 + .../MV-transmission/engine-state.json | 1 + .../MV-transmission/files-after-detail.json | 4 + .../MV-transmission/files-after.json | 4 + .../MV-transmission/files-before-detail.json | 4 + .../MV-transmission/files-before.json | 4 + .../MV-transmission/memory-samples.json | 762 ++++++++++++++++++ .../MV-transmission/migration-lines.txt | 2 + .../MV-transmission/run.log | 58 ++ .../MV-transmission/to-full.log | 39 + .../MV-transmission/to-states.json | 8 + .../MV-transmission/verdict.json | 58 ++ documentation/backlog/OPEN-ITEMS.md | 3 +- website/CHANGELOG.md | 25 +- website/alkalmazasok.html | 54 +- website/assets/qbittorrent-logo.svg | 16 + website/assets/transmission-logo.svg | 66 ++ website/en/apps.html | 54 +- website/en/faq.html | 8 +- website/en/index.html | 6 +- website/en/services.html | 4 +- website/en/technology.html | 2 +- website/gyik.html | 8 +- website/index.html | 6 +- website/szolgaltatasok.html | 4 +- website/technologiak.html | 2 +- 51 files changed, 2442 insertions(+), 97 deletions(-) create mode 100644 REPORT-newapps-2026-10-12.md create mode 100644 documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/abort-states.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/compose-final.log create mode 100644 documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/engine-state.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/files-after-detail.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/files-after.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/files-before-detail.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/files-before.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/memory-samples.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/migration-lines.txt create mode 100644 documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/run.log create mode 100644 documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/to-full.log create mode 100644 documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/to-states.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/verdict.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/box/qbittorrent/box-verdict-qbittorrent.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/box/qbittorrent/prep.txt create mode 100644 documentation/audits/qbittorrent-2026-10-12/box/qbittorrent/step.txt create mode 100644 documentation/audits/qbittorrent-2026-10-12/box/teardown-newapps.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/box/transmission/box-verdict-transmission.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/box/transmission/prep.txt create mode 100644 documentation/audits/qbittorrent-2026-10-12/box/transmission/step.txt create mode 100644 documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/abort-states.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/compose-final.log create mode 100644 documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/engine-state.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/files-after-detail.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/files-after.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/files-before-detail.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/files-before.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/memory-samples.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/migration-lines.txt create mode 100644 documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/run.log create mode 100644 documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/to-full.log create mode 100644 documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/to-states.json create mode 100644 documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/verdict.json create mode 100644 website/assets/qbittorrent-logo.svg create mode 100644 website/assets/transmission-logo.svg diff --git a/REPORT-newapps-2026-10-12.md b/REPORT-newapps-2026-10-12.md new file mode 100644 index 00000000..174c07ad --- /dev/null +++ b/REPORT-newapps-2026-10-12.md @@ -0,0 +1,75 @@ +# REPORT — 2026-10-12 (night): the two download clients published, and the website follows them + +Operator's asks, in order: a torrent client ("no question about it"), Transmission beside it, then +"proceed with the publication steps/tests". All three are done. The Usenet pair he asked for after +that is filed as **R-988** and not started. + +## What shipped + +- **`app-catalog-felhom.eu` `9081a47`** — `templates/qbittorrent/` and `templates/transmission/` with + `onboarding/qbittorrent.md` and `onboarding/transmission.md` in ONE commit, plus the README tables, + two `FIRST-ADMIN.md` class-1 rows and the fixtures for both venues. Then `cb4ecec` — two `REUSE.md` + rows the build earned. +- **This repo** — the two app cards (both language sets) with the projects' own logos, the published + count 58 → 60 on every page that states it, `documentation/audits/qbittorrent-2026-10-12/` (the whole + campaign), and a fix to the 2026-09-30 walk harness: a `type: path` deploy field is filled with the + drive ROOT, because the controller refuses a path inside a drive (409) and the walker therefore could + not install any app with a drive field. + +## What was measured, and in which venue + +Bench LXC 9401 on demo-hp (twelve questions per app: image, telemetry, entrypoint, first admin, +storage, ownership, health, memory, a real download, the config as the app rewrote it) and scratch +guest 9202 **through the product** (deploy from the drill catalog, stranger and household through +traefik on the app's own public name, the guarded Update with its per-app backup, both remove choices). +Six defects came out of it, every one from a measurement and every one fixed before publication; they +are listed with their numbers in the catalog CHANGELOG and in the audit README. The one that reads as a +lesson rather than a bug: **a value seeded into a config file the app owns is only a request** — +qBittorrent ignores a seeded UPnP flag at first start and rewrites a semicolon host list down to a +single entry, after which the controller's own health probe is refused. Both settings now go through +the app's API in `after_install`, whose marker depends on the **readback**, not on the call's status. + +**An apparent household lock-out was my measurement, not the app.** Six wrong passwords and the +household's own request came from one machine. Re-measured from two addresses: qBittorrent bans the +address that sent the wrong tries (403) while the household signs in at the same instant (204); +Transmission does not ban at all. + +**The operator's UPnP question, answered by measurement:** with port mapping off and neither peer port +published, each client completed a 276 MB torrent through its own interface. Peer traffic leaves +through the household's router by NAT; the tunnel only carries the app's web page inbound. What a +closed port costs is incoming peers, and both app pages say so. + +## Gates + +- `catalog_gates.py qbittorrent transmission` — 12 of 14 OK. `image-resolvable` INCONCLUSIVE and + `volume-persistence` DID-NOT-RUN: the two documented periodic ones, which need network and a + container runtime (the Windows workstation has neither, and the harness refuses a host that is not a + scratch host). Both were covered on the bench during the campaign — the ladder writer resolved and + recorded both digests, and each app's storage layout was measured by hand there. +- `catalog_gates.py --fast` (whole catalog) — all OK. +- `repo_gates.py --fast` here — `instructions` and `script-tests` FAILED and `wire-contract` + INCONCLUSIVE, **all three pre-existing and none of them about this work**: the instructions gate + reports the deliberate divergence between `E:\git\CLAUDE.md` (the Windows-adapted copy, whose own + header says not to converge them) and the versioned DooPlex one, plus five component-version literals + in `app-catalog-felhom.eu/CLAUDE.md`; the script-tests failures are Windows-shaped (`os.symlink` + needs a privilege this account lacks, no `sqlite3` CLI, bash-only suites). The authority for these is + CI on the DooPlex-shaped runner, which re-runs the same entry point on this push. + +## Teardown — three layers, verified, with the control from a different channel + +- **Machine (9202):** both apps removed **through the product**, `deployed: false`, both config volumes + gone, no container left, the two download folders deleted from the scratch drive. The guest's standing + apps are untouched. `box/teardown-newapps.json`. +- **Catalog pointer:** restored from this run's own saved copy with the cache removed (R-615), and + proven **not** by the controller's „nincs változás" but by sha256: `qbittorrent`, `transmission` and + `grocy`'s `.felhom.yml` on the box equal the same files at the published `origin/main`, with a decoy + pair that must differ and does. The config names the drill repo zero times. +- **Host (demo-hp):** bench 9401 has no containers and no volumes and is stopped, as found. The drill + catalog is reset to live `main`; the DooPlex clone is clean at the published commit. +- **Hub:** nothing to undo — 9202 reports to no hub by its own configuration. + +## Register + +Rows before 116, after 117, opened 1 (**R-988**, the Usenet pair), closed 0. Fixed without a row: the +six defects above and the walk harness's drive-path filling. `unproven.py --summary` was not re-run — +nothing in this work changes a capability claim's status. diff --git a/STATUS.md b/STATUS.md index 9480e92c..e3e039fb 100644 --- a/STATUS.md +++ b/STATUS.md @@ -2,7 +2,35 @@ **Ready for the first real tester (Tester-2): yes. Tester 2 (a laptop) is off; nothing was sent to it.** -**Updated 2026-10-12 (evening): demo-hp, demo-felhom and Tester 1 run agent 0.154.0 and controller 0.309.0. The open-items list is at 116 (2026-10-12 evening; this includes the security session's new items). Reports: `REPORT-disk-evening-2026-10-12.md`, `REPORT-answers-2026-10-12.md`, `REPORT-m3-2026-10-11.md`, `REPORT-redesign-2026-10-10.md`, `REPORT-testers-2026-10-10.md`, `REPORT-register-shrink-2026-10-10.md`, `REPORT-new-apps-2026-10-10.md`, `REPORT-release-2026-10-10.md`, `REPORT-break-the-circle-2026-10-09.md`, `REPORT-dooplex-survival-2026-10-09.md`, `REPORT-day4-2026-10-09.md`.** +**Updated 2026-10-12 (evening): demo-hp, demo-felhom and Tester 1 run agent 0.154.0 and controller 0.309.0. The open-items list is at 117 (2026-10-12 night; the new row is the Usenet pair, R-988). Reports: `REPORT-newapps-2026-10-12.md`, `REPORT-disk-evening-2026-10-12.md`, `REPORT-answers-2026-10-12.md`, `REPORT-m3-2026-10-11.md`, `REPORT-redesign-2026-10-10.md`, `REPORT-testers-2026-10-10.md`, `REPORT-register-shrink-2026-10-10.md`, `REPORT-new-apps-2026-10-10.md`, `REPORT-release-2026-10-10.md`, `REPORT-break-the-circle-2026-10-09.md`, `REPORT-dooplex-survival-2026-10-09.md`, `REPORT-day4-2026-10-09.md`.** + +## Monday 2026-10-12 (night): the two download clients are live, and the Usenet pair is written down + +- **qBittorrent and Transmission are in the catalog**, offered on `torrent.` and + `transmission.`. Until today Radarr, Sonarr and Jellyseerr could decide what to fetch and had + nothing to fetch it with. qBittorrent is the full client; Transmission does the same job at a quarter + of the memory, for a household that wants the simple one. The app list now says 60 apps. +- **Each was measured twice before it went out** - once on the test box, once on the scratch box through + the product itself, installed and updated the way a household would. Six things were wrong and all six + were fixed before publication: one client could never report itself healthy, one refused its own + health check, one was unreachable on its own address, one quietly ignored the setting that stops it + asking the router to open a port, and two of my own test tools were reading the wrong thing. +- **Neither client asks your router for anything.** The box opens no port at home, and both clients are + set so they do not try. Downloads work on outgoing connections - a 276 MB film finished on each - and + the app page says what the closed port costs: slower downloads on thin swarms, and nothing uploaded + back. +- **One scare was not real.** It looked as though six wrong passwords locked the household out too. They + did not: the test was sending both from one machine. Re-measured from two, the stranger is locked out + and the household is let in at the same instant. +- **Everything is back as it was found:** both apps removed from the scratch box through the product, + its catalog pointer back on the live catalog (proven by comparing the files themselves, not by asking + the box), the test box stopped, the drill copy of the catalog reset. +- **Written down for next time (R-988):** the Usenet pair you asked for, SABnzbd and NZBGet. Both need a + paid Usenet account that the household brings, so that has to be on the app page before anyone + installs them; SABnzbd has no image of its own, so it takes the same third-party exception Transmission + got today. + +**Waiting on you:** nothing from this piece of work. ## Monday 2026-10-12 (evening): the failed disk is silenced and ready to pull out; box 0.309.0 with the simpler notification page diff --git a/documentation/audits/pg-last-six-2026-09-30/tools/walk.py b/documentation/audits/pg-last-six-2026-09-30/tools/walk.py index dccce034..36c9d444 100644 --- a/documentation/audits/pg-last-six-2026-09-30/tools/walk.py +++ b/documentation/audits/pg-last-six-2026-09-30/tools/walk.py @@ -197,6 +197,7 @@ def wait_app(sub, path="/", want=("200", "302", "303", "401", "403"), tries=60, DRIVE = "/mnt/felhom-drives/scratch_hdd/userdata" +DRIVE_ROOT = "/mnt/felhom-drives/scratch_hdd" # what a `type: path` field wants # What THIS run generated for a deploy, per app. Deploy secrets are ENCRYPTED AT REST in # `app.yaml` (`ENC:…`), which is right and which means a fixture cannot read an app's admin @@ -232,7 +233,11 @@ def deploy_values(name, sub): if not f.get("required") and ty != "password": continue # the controller generates the optional secrets itself if ty == "path": - p = f"{DRIVE}/{name}" + # A `type: path` field names a DRIVE, not a folder on one. The controller refuses a + # folder with 409 "Az alkalmazas adatainak helye egy meghajto lehet, nem egy mappa a + # meghajton belul" (measured on 9202, 2026-10-12, deploying qbittorrent) - and it then + # creates the app's own folder under the drive itself. + p = DRIVE_ROOT values[ev] = p made.append(p) elif ty in ("secret", "password"): diff --git a/documentation/audits/qbittorrent-2026-10-12/README.md b/documentation/audits/qbittorrent-2026-10-12/README.md index e49f7b0f..9ea98397 100644 --- a/documentation/audits/qbittorrent-2026-10-12/README.md +++ b/documentation/audits/qbittorrent-2026-10-12/README.md @@ -6,70 +6,83 @@ client. Radarr's own template said so in its prerequisites („Letöltő kliens qBittorrent — külön telepítendő)") while the website promised „Automatikus film letöltő… a filmek automatikusan a könyvtáradba kerülnek". Operator ruling, 2026-10-12: add them. -**Where this run got to.** Both templates are written and **measured twice** — on the bench (LXC 9401, -demo-hp) and on the scratch guest 9202 **through the product**. Neither is published: the onboarding -records are not complete, and `catalog_gates.py` refuses a new template without one. +**Where this run got to. Both are PUBLISHED** — `app-catalog-felhom.eu` `9081a47`, the two templates +and their two complete onboarding records in one commit, with the README and FIRST-ADMIN rows, the +fixtures for both venues and the website cards. Each was measured twice before that: on the bench +(LXC 9401 on demo-hp) and on scratch guest 9202 **through the product**. ## What is in here | | | |---|---| -| `bench/` | qBittorrent on LXC 9401: image, telemetry, entrypoint, first admin, storage, ownership, health, memory, a real download, the config as the app rewrote it | -| `transmission-bench/` | the same twelve questions asked of Transmission | -| `box/` | guest 9202 through the product: the two box walks, the app logs, and `verify-fixes.json` — the proof the defects below are gone | +| `bench/` | qBittorrent on LXC 9401: image, telemetry, entrypoint, first admin, storage, ownership, health, memory, a real download, the config as the app rewrote it, and `MV-qbittorrent/` — the harness verdict for the ladder step | +| `transmission-bench/` | the same twelve questions asked of Transmission, plus `MV-transmission/` | +| `box/` | guest 9202 through the product: the two box walks, the per-app box verdicts under `qbittorrent/` and `transmission/`, the app logs, `verify-fixes.json` (the proof the defects below are gone) and `teardown-newapps.json` | | `tools/` | `boxwalk_newapps.py` (deploy + stranger + sign-in + lock-out through traefik) and `verify_fixes.py` (the re-measure). Both reuse the 2026-09-30 harness for the session, CSRF and setup gate | -## Five defects, each found by measuring and fixed +## Six defects, each found by measuring and fixed before publication -1. **qBittorrent was unreachable on its own public name.** `WebUI\ServerDomains` takes **semicolons**; - with a comma list the app answers 401 „Invalid Host header" to everything, its own name included. - Nothing upstream documents the separator — measured through the app's own API - (`box/verify-fixes.json`, and the four-way test: comma 401/401, single 200/401, semicolon 200/200, - `*` 200/200). -2. **Both clients asked the household's router to open a port.** qBittorrent logs +1. **qBittorrent was unreachable on its own public name.** `WebUI\ServerDomains` with a comma list + makes the app answer 401 „Invalid Host header" to everything, its own name included; semicolons + work **through the API** (the four-way test: comma 401/401, single 200/401, semicolon 200/200, `*` + 200/200). Nothing upstream documents the separator. +2. **…and the config file's own dialect drops the extra entries anyway.** A semicolon list seeded + into `qBittorrent.conf` comes back from the app's first read-write cycle as the public name + **alone**, after which the controller's health probe — which dials by container name — is refused + („Invalid Host header … 'qbittorrent:8080'"). The list moved into `after_install`, where the API + honours it, and the marker is printed only after both the list and the UPnP flag are read back. +3. **Both clients asked the household's router to open a port.** qBittorrent logs `UPnP/NAT-PMP support: ON` and tries a mapping; Transmission ships `"port-forwarding-enabled": true`. - The box opens no port at home (`01-topology-and-trust.md` §7), so both are off now. qBittorrent's - seeded `Session\UseUPnP=false` **is written and then ignored at first start** — the app reported - `"upnp": true` with that very line in its config — so it goes through `after_install`, which the - app does honour: `ON` at 17:21:51, **`OFF` at 17:21:56**. -3. **Transmission could never become healthy.** It answers 401 on every path once authentication is + The box opens no port at home (`../architecture/01-topology-and-trust.md` §7), so both are off now. + qBittorrent's seeded `Session\UseUPnP=false` **is written and then ignored at first start** — the + app reported `"upnp": true` with that very line in its config — so it goes through `after_install`, + which the app does honour: `ON` at 17:21:51, **`OFF` at 17:21:56** (`box/verify-fixes.json`). +4. **Transmission could never become healthy.** It answers 401 on every path once authentication is on, so `curl -f` always failed (`exit 22`). The probe accepts 200 or 401 now, with a negative control that still fails. -4. **Transmission's host whitelist refused its own healthcheck** (400 to `Host: 127.0.0.1`). -5. **The first box walk looked like a lock-out and was not one.** Stranger and household ran from the - same machine, so a shared ban could not be told from a per-visitor one. Re-run from two addresses: - the stranger is banned (`401 401 401 401 401 403`, and 403 on the right password) while **the - household signs in at the same instant (204)**. qBittorrent reads the real visitor address through - the proxy headers; its log names `192.168.0.180`, not traefik. Transmission does not ban at all. +5. **Transmission's host whitelist refused its own healthcheck** (400 to `Host: 127.0.0.1`). The + local names are admitted beside the public one. +6. **Two fixtures were reading the wrong thing.** The box fixture looked for a cookie named `SID`; + qBittorrent 5.x names it `QBT_SID_`. The Transmission fixture read the session id with an + `awk` that matched the header NAME on a second line and so got 400 on every RPC; it uses an + anchored `sed` now, with the payload on stdin. + +**And one finding that was not a defect.** The first box walk looked like a household lock-out. +Stranger and household ran from the same machine, so a shared ban could not be told from a +per-visitor one. Re-run from two addresses: the stranger is banned (`401 401 401 401 401 403`, and +403 on the right password) while **the household signs in at the same instant (204)**. qBittorrent +reads the real visitor address through the proxy headers; its log names `192.168.0.180`, not traefik. +Transmission does not ban at all. ## Does a download work with no inbound port? Measured, yes -Operator's question. With UPnP off and the port confirmed closed (`"port-is-open": false`): +The operator's question. With port mapping off and neither peer port published, each client was given +one real torrent (Big Buck Bunny, Blender Foundation, CC BY) through its **own** interface: -| | after 30 s | peers | finished | -|---|---|---|---| -| qBittorrent | 98 % at **4.0 MB/s** | 34 seeds | yes, inside a minute | -| Transmission | 96 % | 48 connected, 43 sending | yes | +| | finished | where the files landed | +|---|---|---| +| qBittorrent | yes, inside a minute — `progress: 1`, `downloaded: 276610512` | `…/media/torrents/Big Buck Bunny/` (`bench/09-download.txt`) | +| Transmission | yes — `percentDone: 1.0`, `status: 6` (seeding) | `…/media/transmission/complete/Big Buck Bunny/` (`transmission-bench/05-download.txt`) | -The tunnel is not involved: Cloudflare carries the app's **web page** inbound, while peer traffic -goes out through the household's own router by NAT. What a closed port costs is incoming peers — -slower on sparse swarms, less upload — and the app text now says so and says the household can switch -it on themselves. +Both files are the completed-state snapshots, which is why their peer counts read 0: the swarm work +was over. The tunnel is not involved either way — Cloudflare carries the app's **web page** inbound, +while peer traffic goes out through the household's own router by NAT. What a closed port costs is +incoming peers (slower on sparse swarms, less upload), and the app text now says so. -## What is still open before these can be published +## State left behind — three layers, verified -- **2.5 / 2.8** — a backup and a restore through the product, data read back (the dawarich route: - the update's per-app backup → remove keeping backups → restore). -- **6.1–6.3** — an upgrade fixture, and a first ladder step proven on bench + 9202 - (`upgrade-test.py --write-ladder`). -- **8.3–8.5** — logo, screenshots, the cards on both language pages, the app count 58 → 60, and the - three *arr descriptions that promise automatic downloading. -- **The two onboarding records**, which the gate requires complete before either template may land. - -## State left behind - -Guest 9202: both apps **removed** through the product (volumes gone, containers gone, the test -downloads deleted from the scratch drive), the controller **restored to the live catalog** from this -run's own saved copy, its cache rebuilt (60 templates, neither new app present). Bench LXC 9401: -deployments down with their volumes, **stopped** as it was found. The live catalog's `main` is -untouched (`3a6e930`). The two templates live in the private drill repo as work in progress. +- **Machine (guest 9202):** both apps removed **through the product** (`POST …/stop` then + `…/remove` with the drive data), `deployed: false` for both, the two config volumes gone, no + container left, and the two download folders deleted from the scratch drive by name. The guest's + standing apps (filebrowser, paperless) are untouched and running. `box/teardown-newapps.json`. +- **Catalog pointer:** the controller is back on the **live** catalog from this run's own saved copy + (`controller.yaml.pre-newapps1012`), the cache removed with it (R-615 — `repo_url` alone is inert), + and the restoration is proven from a **different channel than the controller's own verdict** + (R-286): the sha256 of `qbittorrent`, `transmission` and `grocy`'s `.felhom.yml` on the box equals + the sha256 of the same files at the published `origin/main`, with a decoy pair that must differ and + does. The config names the drill repo zero times. +- **Host (demo-hp):** bench LXC 9401 has no containers and no volumes and is **stopped**, as it was + found. The drill catalog `admin/app-catalog-drill` is reset to the live `main` (`9081a47`), so it + carries the published templates and no work in progress. +- **Hub:** nothing to undo — 9202 reports to no hub by its own configuration (the config header says + hub reporting OFF, no tunnel, no agent local API). diff --git a/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/abort-states.json b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/abort-states.json new file mode 100644 index 00000000..e23b4d95 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/abort-states.json @@ -0,0 +1,8 @@ +{ + "qbittorrent": { + "status": "running", + "health": "healthy", + "restarts": 0, + "exit": 0 + } +} \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/compose-final.log b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/compose-final.log new file mode 100644 index 00000000..7a1f0b11 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/compose-final.log @@ -0,0 +1,4 @@ +qbittorrent | WebUI will be started shortly after internal preparations. Please wait... +qbittorrent | +qbittorrent | ******** Information ******** +qbittorrent | To control qBittorrent, access the WebUI at: http://localhost:8080 diff --git a/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/engine-state.json b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/engine-state.json new file mode 100644 index 00000000..ec747fa4 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/engine-state.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/files-after-detail.json b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/files-after-detail.json new file mode 100644 index 00000000..fd183d7b --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/files-after-detail.json @@ -0,0 +1,7 @@ +{ + "/srv/felhom-gate/hdd/userdata/media/torrents": { + "Big Buck Bunny/poster.jpg": "310380:d082c4ae86f4f8d3", + "Big Buck Bunny/Big Buck Bunny.mp4": "276134947:mtime-1791827067", + "Big Buck Bunny/Big Buck Bunny.en.srt": "140:18e9b7280644d12f" + } +} \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/files-after.json b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/files-after.json new file mode 100644 index 00000000..e30c0a9e --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/files-after.json @@ -0,0 +1,3 @@ +{ + "/srv/felhom-gate/hdd/userdata/media/torrents": "4434017b4bf24656096e6e880f4de7e8e9e34751f594c9a57af6a95094d9a8c5" +} \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/files-before-detail.json b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/files-before-detail.json new file mode 100644 index 00000000..d45948e7 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/files-before-detail.json @@ -0,0 +1,3 @@ +{ + "/srv/felhom-gate/hdd/userdata/media/torrents": {} +} \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/files-before.json b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/files-before.json new file mode 100644 index 00000000..14116584 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/files-before.json @@ -0,0 +1,3 @@ +{ + "/srv/felhom-gate/hdd/userdata/media/torrents": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" +} \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/memory-samples.json b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/memory-samples.json new file mode 100644 index 00000000..7f5d4b4f --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/memory-samples.json @@ -0,0 +1,762 @@ +[ + { + "t": 15.1, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802689024, + "peak": 803291136, + "anon": 332910592, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 300 + }, + { + "t": 30.2, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802775040, + "peak": 804659200, + "anon": 332910592, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 600 + }, + { + "t": 45.4, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 803000320, + "peak": 804659200, + "anon": 332910592, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 900 + }, + { + "t": 60.5, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 803033088, + "peak": 804937728, + "anon": 332914688, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 1200 + }, + { + "t": 75.6, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802058240, + "peak": 804937728, + "anon": 332914688, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 1496 + }, + { + "t": 90.7, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802254848, + "peak": 804937728, + "anon": 332853248, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 1796 + }, + { + "t": 105.8, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 801980416, + "peak": 804937728, + "anon": 332853248, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 2096 + }, + { + "t": 121.0, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802594816, + "peak": 805007360, + "anon": 333017088, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 2396 + }, + { + "t": 136.1, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802635776, + "peak": 805007360, + "anon": 332840960, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 2696 + }, + { + "t": 151.2, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802324480, + "peak": 805007360, + "anon": 332840960, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 2996 + }, + { + "t": 166.4, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802590720, + "peak": 805007360, + "anon": 332840960, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 3296 + }, + { + "t": 181.5, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802545664, + "peak": 805007360, + "anon": 332840960, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 3593 + }, + { + "t": 196.6, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802553856, + "peak": 805007360, + "anon": 332840960, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 3893 + }, + { + "t": 211.7, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802369536, + "peak": 805163008, + "anon": 332840960, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 4192 + }, + { + "t": 226.8, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802500608, + "peak": 805163008, + "anon": 332840960, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 4492 + }, + { + "t": 242.0, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802340864, + "peak": 805163008, + "anon": 332840960, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 4792 + }, + { + "t": 257.1, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 801964032, + "peak": 805163008, + "anon": 332840960, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 5092 + }, + { + "t": 272.2, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802725888, + "peak": 805163008, + "anon": 332840960, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 5392 + }, + { + "t": 287.3, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802803712, + "peak": 805163008, + "anon": 332857344, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 5692 + }, + { + "t": 302.5, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802516992, + "peak": 805163008, + "anon": 332840960, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 5988 + }, + { + "t": 317.6, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802443264, + "peak": 805163008, + "anon": 333021184, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 6288 + }, + { + "t": 332.7, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802164736, + "peak": 805163008, + "anon": 332996608, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 6588 + }, + { + "t": 347.9, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802287616, + "peak": 805163008, + "anon": 332988416, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 6888 + }, + { + "t": 363.0, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802058240, + "peak": 805163008, + "anon": 332988416, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 7188 + }, + { + "t": 378.1, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802795520, + "peak": 805163008, + "anon": 332988416, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 7488 + }, + { + "t": 393.3, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802807808, + "peak": 805163008, + "anon": 332984320, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 7788 + }, + { + "t": 408.4, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 803041280, + "peak": 805163008, + "anon": 332988416, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 8089 + }, + { + "t": 423.5, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802750464, + "peak": 805163008, + "anon": 332980224, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 8389 + }, + { + "t": 438.7, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802504704, + "peak": 805163008, + "anon": 332980224, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 8685 + }, + { + "t": 453.8, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802435072, + "peak": 805556224, + "anon": 332980224, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 8985 + }, + { + "t": 468.9, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802770944, + "peak": 805556224, + "anon": 332980224, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 9285 + }, + { + "t": 484.0, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802856960, + "peak": 805556224, + "anon": 332980224, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 9585 + }, + { + "t": 499.2, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802213888, + "peak": 805556224, + "anon": 332980224, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 9885 + }, + { + "t": 514.3, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 803074048, + "peak": 805556224, + "anon": 332980224, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 10185 + }, + { + "t": 529.4, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802435072, + "peak": 805556224, + "anon": 332980224, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 10485 + }, + { + "t": 544.6, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802865152, + "peak": 805556224, + "anon": 332980224, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 10781 + }, + { + "t": 559.7, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802451456, + "peak": 805556224, + "anon": 332980224, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 11081 + }, + { + "t": 574.8, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802271232, + "peak": 805883904, + "anon": 332980224, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 11381 + }, + { + "t": 590.0, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802050048, + "peak": 805883904, + "anon": 332980224, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 11681 + }, + { + "t": 605.1, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "current": 802615296, + "peak": 805883904, + "anon": 332980224, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 11981 + } +] \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/migration-lines.txt b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/migration-lines.txt new file mode 100644 index 00000000..e69de29b diff --git a/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/run.log b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/run.log new file mode 100644 index 00000000..f0aae2e9 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/run.log @@ -0,0 +1,60 @@ +[17:43:28] scratch drive folders cleared before FROM (R-656): none existed +[17:43:28] MV-qbittorrent: deploying qbittorrent at FROM {'qbittorrent': 'qbittorrentofficial/qbittorrent-nox:5.2.3-1'} +[17:44:07] FROM settled=True in 30.9s :: {"qbittorrent": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}} +[17:44:07] qbittorrent: createCategory felhom6d2253cb http=200 +[17:44:07] qbittorrent: torrents/add http=200 +[17:44:08] qbittorrent: category kept, torrent present=True +[17:44:08] C1 (seed reads back BEFORE): True +[17:44:08] MV-qbittorrent: swapping to TO {'qbittorrent': 'qbittorrentofficial/qbittorrent-nox:5.2.4-1'} +[17:44:10] TO up -d rc=0 +[17:44:41] TO settled=True in 30.9s :: {"qbittorrent": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}} +[17:44:41] migration lines observed: 0 +[17:44:42] qbittorrent: category kept, torrent present=True +[17:44:42] RESULT (seed reads back AFTER): True +[17:44:42] files_may_change — the files: ['/srv/felhom-gate/hdd/userdata/media/torrents/Big Buck Bunny/Big Buck Bunny.en.srt (added)', '/srv/felhom-gate/hdd/userdata/media/torrents/Big Buck Bunny/Big Buck Bunny.mp4 (added)', '/srv/felhom-gate/hdd/userdata/media/torrents/Big Buck Bunny/poster.jpg (added)'] +[17:44:42] files_may_change: the bind-mounted tree changed under ['/srv/felhom-gate/hdd/userdata/media/torrents'] +[17:44:42] memory watch: 600s, 4 callers on 1 path(s) at 172.18.0.2:8080 +[17:44:57] + 15s qbittorrent=765M/1024M peak=766M kills=0 rs=0 reqs=300 +[17:45:12] + 30s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=600 +[17:45:28] + 45s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=900 +[17:45:43] + 60s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=1200 +[17:45:58] + 76s qbittorrent=764M/1024M peak=767M kills=0 rs=0 reqs=1496 +[17:46:13] + 91s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=1796 +[17:46:28] + 106s qbittorrent=764M/1024M peak=767M kills=0 rs=0 reqs=2096 +[17:46:43] + 121s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=2396 +[17:46:58] + 136s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=2696 +[17:47:13] + 151s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=2996 +[17:47:29] + 166s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=3296 +[17:47:44] + 182s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=3593 +[17:47:59] + 197s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=3893 +[17:48:14] + 212s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=4192 +[17:48:29] + 227s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=4492 +[17:48:44] + 242s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=4792 +[17:48:59] + 257s qbittorrent=764M/1024M peak=767M kills=0 rs=0 reqs=5092 +[17:49:14] + 272s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=5392 +[17:49:29] + 287s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=5692 +[17:49:45] + 302s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=5988 +[17:50:00] + 318s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=6288 +[17:50:15] + 333s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=6588 +[17:50:30] + 348s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=6888 +[17:50:45] + 363s qbittorrent=764M/1024M peak=767M kills=0 rs=0 reqs=7188 +[17:51:00] + 378s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=7488 +[17:51:15] + 393s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=7788 +[17:51:31] + 408s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=8089 +[17:51:46] + 424s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=8389 +[17:52:01] + 439s qbittorrent=765M/1024M peak=767M kills=0 rs=0 reqs=8685 +[17:52:16] + 454s qbittorrent=765M/1024M peak=768M kills=0 rs=0 reqs=8985 +[17:52:31] + 469s qbittorrent=765M/1024M peak=768M kills=0 rs=0 reqs=9285 +[17:52:46] + 484s qbittorrent=765M/1024M peak=768M kills=0 rs=0 reqs=9585 +[17:53:01] + 499s qbittorrent=765M/1024M peak=768M kills=0 rs=0 reqs=9885 +[17:53:16] + 514s qbittorrent=765M/1024M peak=768M kills=0 rs=0 reqs=10185 +[17:53:32] + 529s qbittorrent=765M/1024M peak=768M kills=0 rs=0 reqs=10485 +[17:53:47] + 545s qbittorrent=765M/1024M peak=768M kills=0 rs=0 reqs=10781 +[17:54:02] + 560s qbittorrent=765M/1024M peak=768M kills=0 rs=0 reqs=11081 +[17:54:17] + 575s qbittorrent=765M/1024M peak=768M kills=0 rs=0 reqs=11381 +[17:54:32] + 590s qbittorrent=764M/1024M peak=768M kills=0 rs=0 reqs=11681 +[17:54:47] + 605s qbittorrent=765M/1024M peak=768M kills=0 rs=0 reqs=11981 +[17:54:47] memory watch: killed=False tight=[] requests=11981 codes={'200': 11981} +[17:54:47] MV-qbittorrent: ABORT — putting the FROM images back +[17:55:20] qbittorrent: category kept, torrent present=True +[17:55:20] ABORT: app came back in 30.9s; data present=True \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/to-full.log b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/to-full.log new file mode 100644 index 00000000..7a1f0b11 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/to-full.log @@ -0,0 +1,4 @@ +qbittorrent | WebUI will be started shortly after internal preparations. Please wait... +qbittorrent | +qbittorrent | ******** Information ******** +qbittorrent | To control qBittorrent, access the WebUI at: http://localhost:8080 diff --git a/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/to-states.json b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/to-states.json new file mode 100644 index 00000000..e23b4d95 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/to-states.json @@ -0,0 +1,8 @@ +{ + "qbittorrent": { + "status": "running", + "health": "healthy", + "restarts": 0, + "exit": 0 + } +} \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/verdict.json b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/verdict.json new file mode 100644 index 00000000..3ae0ed4c --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/bench/MV-qbittorrent/verdict.json @@ -0,0 +1,64 @@ +{ + "harness_version": 5, + "edge": "MV-qbittorrent", + "app": "qbittorrent", + "note": "night 2026-09-23 within-a-major move: qbittorrent=qbittorrentofficial/qbittorrent-nox:5.2.4-1", + "from": { + "qbittorrent": "qbittorrentofficial/qbittorrent-nox:5.2.3-1" + }, + "to": { + "qbittorrent": "qbittorrentofficial/qbittorrent-nox:5.2.4-1" + }, + "verdict": "proven", + "seed_read_before": true, + "seed_read_after": true, + "healthy_after": true, + "migration_observed": null, + "abort": "starts-and-serves", + "abort_detail": null, + "engine_state_after": null, + "memory": { + "soak_s": 605.3, + "requested_s": 600, + "requests": 11981, + "codes": { + "200": 11981 + }, + "first_kill": null, + "containers": { + "qbittorrent": { + "limit": 1073741824, + "peak": 805883904, + "peak_pct": 0.751, + "anon_peak_sampled": 333021184, + "anon_peak_pct": 0.31, + "swap_peak": 0, + "oom_kills": 0, + "restarts": 0, + "oomkilled_flag": false, + "measured": true + } + }, + "unmeasured": [], + "venue_swap_bytes": 0, + "load": "reached" + }, + "marks": [ + "files_may_change" + ], + "bench_overrides": null, + "duration_s": 30.9, + "measured_at": "2026-10-12T17:55:20Z", + "evidence": "evidence/MV-qbittorrent", + "scratch_cleared": [], + "files_changed": [ + "/srv/felhom-gate/hdd/userdata/media/torrents" + ], + "files_changed_detail": [ + "/srv/felhom-gate/hdd/userdata/media/torrents/Big Buck Bunny/Big Buck Bunny.en.srt (added)", + "/srv/felhom-gate/hdd/userdata/media/torrents/Big Buck Bunny/Big Buck Bunny.mp4 (added)", + "/srv/felhom-gate/hdd/userdata/media/torrents/Big Buck Bunny/poster.jpg (added)" + ], + "files_ignored": [], + "total_s": 711.8 +} \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/box/qbittorrent/box-verdict-qbittorrent.json b/documentation/audits/qbittorrent-2026-10-12/box/qbittorrent/box-verdict-qbittorrent.json new file mode 100644 index 00000000..0b3cc34f --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/box/qbittorrent/box-verdict-qbittorrent.json @@ -0,0 +1,18 @@ +{ + "app": "qbittorrent", + "venue": "box 9202 (drill catalog, controller 0.283.1), the product's guarded Update", + "from": { + "qbittorrent": "qbittorrentofficial/qbittorrent-nox:5.2.3-1" + }, + "to": { + "qbittorrent": "qbittorrentofficial/qbittorrent-nox:5.2.4-1" + }, + "verdict": "proven", + "seed_read_before": true, + "seed_read_after": true, + "healthy_after": true, + "duration_s": 19.6, + "final_phase": "done", + "measured_at": "2026-10-12T18:32:35Z", + "evidence": "felhom.eu/documentation/audits/pg-last-six-2026-09-30/box/qbittorrent/step.txt" +} \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/box/qbittorrent/prep.txt b/documentation/audits/qbittorrent-2026-10-12/box/qbittorrent/prep.txt new file mode 100644 index 00000000..1d759876 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/box/qbittorrent/prep.txt @@ -0,0 +1,19 @@ +deploy/reuse qbittorrent: False +C1 seed reads back BEFORE: False +deploy/reuse qbittorrent: True + qbittorrent: the app did not hand back a session cookie + qbittorrent: the app did not hand back a session cookie +C1 seed reads back BEFORE: False +deploy/reuse qbittorrent: True + qbittorrent: no session cookie in the response (HTTP/2 204 | content-security-policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; script-src 'self' 'unsafe-inline'; object-src 'none'; form-action 'self'; frame-src 'self' blob:; frame-ancestors 'self'; | cross-origin-opener-policy: same-origin | date: Mon, 12 Oct 20) + qbittorrent: no session cookie in the response (HTTP/2 204 | content-security-policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; script-src 'self' 'unsafe-inline'; object-src 'none'; form-action 'self'; frame-src 'self' blob:; frame-ancestors 'self'; | cross-origin-opener-policy: same-origin | date: Mon, 12 Oct 20) +C1 seed reads back BEFORE: False +deploy/reuse qbittorrent: True + qbittorrent: this run holds no generated password for the app + qbittorrent: this run holds no generated password for the app +C1 seed reads back BEFORE: False +deploy/reuse qbittorrent: True + qbittorrent: createCategory felhomed439f7e http=200 + qbittorrent: torrents/add http=200 + qbittorrent: category kept, torrent present=True +C1 seed reads back BEFORE: True diff --git a/documentation/audits/qbittorrent-2026-10-12/box/qbittorrent/step.txt b/documentation/audits/qbittorrent-2026-10-12/box/qbittorrent/step.txt new file mode 100644 index 00000000..66017e9b --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/box/qbittorrent/step.txt @@ -0,0 +1,30 @@ +before: pinned={'qbittorrent': 'qbittorrentofficial/qbittorrent-nox:5.2.3-1'} +drill: dbdf8e1 DRILL qbittorrent: {'qbittorrent': 'qbittorrentofficial/qbittorrent-nox:5.2.4-1'} (box proof) + phase +0.0s backing-up | err=None + phase +2.1s safety-dump | err=None + phase +3.1s pulling | err=None + phase +7.2s copying | err=None + phase +13.4s verifying | err=None + phase +19.6s done | err=None + qbittorrent: category kept, torrent present=True +2026/10/12 18:32:37 update.go:537: [INFO] [stacks] update qbittorrent: accepted — guarded update started +2026/10/12 18:32:37 update.go:1378: [INFO] [stacks] update qbittorrent: phase checking +2026/10/12 18:32:37 update.go:795: [INFO] [stacks] update qbittorrent: ladder — the last step (1 of 1) — the catalog's current definition +2026/10/12 18:32:37 update.go:825: [INFO] [stacks] update qbittorrent: no usable copy on any tier — younger than 24h0m0s and not older than this install's deploy (2026-10-12T18:31:43Z) (found: none) — backing up first +2026/10/12 18:32:37 update.go:1378: [INFO] [stacks] update qbittorrent: phase backing-up +2026/10/12 18:32:39 update.go:840: [INFO] [stacks] update qbittorrent: precondition met after the backup — Tier 2 (second drive) copy from 2026-10-12T18:32:38Z +2026/10/12 18:32:39 update.go:1378: [INFO] [stacks] update qbittorrent: phase safety-dump +2026/10/12 18:32:39 update.go:855: [INFO] [stacks] update qbittorrent: safety dump done (0 file(s)) [] +2026/10/12 18:32:39 undo.go:287: [INFO] [stacks] update qbittorrent: the undo copy will hold 1 named volume(s), 8.0 MiB +2026/10/12 18:32:39 update.go:1378: [INFO] [stacks] update qbittorrent: phase pinning +2026/10/12 18:32:39 pin.go:373: [INFO] [stacks] update qbittorrent: pin advanced to /opt/docker/felhom-controller/data/catalog-cache/templates/qbittorrent/docker-compose.yml (qbittorrent=qbittorrentofficial/qbittorrent-nox:5.2.4-1) +2026/10/12 18:32:39 update.go:1378: [INFO] [stacks] update qbittorrent: phase pulling +2026/10/12 18:32:43 update.go:1378: [INFO] [stacks] update qbittorrent: phase copying +2026/10/12 18:32:49 update.go:1378: [INFO] [stacks] update qbittorrent: phase copying +2026/10/12 18:32:49 undo.go:437: [INFO] [stacks] update qbittorrent: copied qbittorrent_qbittorrent_config → qbittorrent_qbittorrent_config.pre-update-20261012T183249Z in 710ms +2026/10/12 18:32:49 update.go:1378: [INFO] [stacks] update qbittorrent: phase starting +2026/10/12 18:32:50 update.go:1378: [INFO] [stacks] update qbittorrent: phase verifying +2026/10/12 18:32:55 update.go:1006: [INFO] [stacks] update qbittorrent: healthy after 5s (the app's health check passed) +2026/10/12 18:32:55 update.go:1043: [INFO] [stacks] update qbittorrent: DONE in 19s + +RESULT final_phase=done after={'qbittorrent': 'qbittorrentofficial/qbittorrent-nox:5.2.4-1'} seed_after=True verdict=proven (19.6 s) diff --git a/documentation/audits/qbittorrent-2026-10-12/box/teardown-newapps.json b/documentation/audits/qbittorrent-2026-10-12/box/teardown-newapps.json new file mode 100644 index 00000000..c5eb43d6 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/box/teardown-newapps.json @@ -0,0 +1,25 @@ +{ + "qbittorrent": { + "was_deployed": true, + "remove_code": "200", + "deployed_after": false + }, + "transmission": { + "was_deployed": true, + "remove_code": "200", + "deployed_after": false + }, + "catalog": { + "repo_url_before": "", + "repo_url_after": "", + "template_count": 0, + "qbittorrent_present": false, + "transmission_present": false + }, + "drive": { + "before": "/mnt/felhom-drives/scratch_hdd/userdata/media/torrents\n/mnt/felhom-drives/scratch_hdd/userdata/media/transmission", + "after": "" + }, + "containers": "felhom-controller filebrowser paperless-postgres paperless-redis paperless-webserver traefik", + "volumes_matching": "" +} \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/box/transmission/box-verdict-transmission.json b/documentation/audits/qbittorrent-2026-10-12/box/transmission/box-verdict-transmission.json new file mode 100644 index 00000000..a23960d4 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/box/transmission/box-verdict-transmission.json @@ -0,0 +1,18 @@ +{ + "app": "transmission", + "venue": "box 9202 (drill catalog, controller 0.283.1), the product's guarded Update", + "from": { + "transmission": "lscr.io/linuxserver/transmission:version-4.1.2-r0" + }, + "to": { + "transmission": "lscr.io/linuxserver/transmission:version-4.1.3-r0" + }, + "verdict": "proven", + "seed_read_before": true, + "seed_read_after": true, + "healthy_after": true, + "duration_s": 25.7, + "final_phase": "done", + "measured_at": "2026-10-12T18:33:51Z", + "evidence": "felhom.eu/documentation/audits/pg-last-six-2026-09-30/box/transmission/step.txt" +} \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/box/transmission/prep.txt b/documentation/audits/qbittorrent-2026-10-12/box/transmission/prep.txt new file mode 100644 index 00000000..6cdfca2b --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/box/transmission/prep.txt @@ -0,0 +1,5 @@ +deploy/reuse transmission: True + transmission: session-set speed-limit-down=700 http=200 + transmission: torrent-add http=200 ok=True + transmission: limit kept, torrent present=True +C1 seed reads back BEFORE: True diff --git a/documentation/audits/qbittorrent-2026-10-12/box/transmission/step.txt b/documentation/audits/qbittorrent-2026-10-12/box/transmission/step.txt new file mode 100644 index 00000000..c7186f15 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/box/transmission/step.txt @@ -0,0 +1,29 @@ +before: pinned={'transmission': 'lscr.io/linuxserver/transmission:version-4.1.2-r0'} +drill: 9a1bf36 DRILL transmission: {'transmission': 'lscr.io/linuxserver/transmission:version-4.1.3-r0'} (box proof) + phase +0.0s backing-up | err=None + phase +6.2s pulling | err=None + phase +12.3s copying | err=None + phase +19.5s verifying | err=None + phase +25.7s done | err=None + transmission: limit kept, torrent present=True +2026/10/12 18:33:52 update.go:537: [INFO] [stacks] update transmission: accepted — guarded update started +2026/10/12 18:33:52 update.go:1378: [INFO] [stacks] update transmission: phase checking +2026/10/12 18:33:52 update.go:795: [INFO] [stacks] update transmission: ladder — the last step (1 of 1) — the catalog's current definition +2026/10/12 18:33:52 update.go:825: [INFO] [stacks] update transmission: no usable copy on any tier — younger than 24h0m0s and not older than this install's deploy (2026-10-12T18:33:22Z) (found: none) — backing up first +2026/10/12 18:33:52 update.go:1378: [INFO] [stacks] update transmission: phase backing-up +2026/10/12 18:33:58 update.go:840: [INFO] [stacks] update transmission: precondition met after the backup — Tier 2 (second drive) copy from 2026-10-12T18:33:57Z +2026/10/12 18:33:58 update.go:1378: [INFO] [stacks] update transmission: phase safety-dump +2026/10/12 18:33:58 update.go:855: [INFO] [stacks] update transmission: safety dump done (0 file(s)) [] +2026/10/12 18:33:58 undo.go:287: [INFO] [stacks] update transmission: the undo copy will hold 1 named volume(s), 0.0 MiB +2026/10/12 18:33:58 update.go:1378: [INFO] [stacks] update transmission: phase pinning +2026/10/12 18:33:58 pin.go:373: [INFO] [stacks] update transmission: pin advanced to /opt/docker/felhom-controller/data/catalog-cache/templates/transmission/docker-compose.yml (transmission=lscr.io/linuxserver/transmission:version-4.1.3-r0) +2026/10/12 18:33:58 update.go:1378: [INFO] [stacks] update transmission: phase pulling +2026/10/12 18:34:04 update.go:1378: [INFO] [stacks] update transmission: phase copying +2026/10/12 18:34:11 update.go:1378: [INFO] [stacks] update transmission: phase copying +2026/10/12 18:34:11 undo.go:437: [INFO] [stacks] update transmission: copied transmission_transmission_config → transmission_transmission_config.pre-update-20261012T183411Z in 507ms +2026/10/12 18:34:11 update.go:1378: [INFO] [stacks] update transmission: phase starting +2026/10/12 18:34:11 update.go:1378: [INFO] [stacks] update transmission: phase verifying +2026/10/12 18:34:17 update.go:1006: [INFO] [stacks] update transmission: healthy after 5s (the app's health check passed) +2026/10/12 18:34:17 update.go:1043: [INFO] [stacks] update transmission: DONE in 25s + +RESULT final_phase=done after={'transmission': 'lscr.io/linuxserver/transmission:version-4.1.3-r0'} seed_after=True verdict=proven (25.7 s) diff --git a/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/abort-states.json b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/abort-states.json new file mode 100644 index 00000000..443eecda --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/abort-states.json @@ -0,0 +1,8 @@ +{ + "transmission": { + "status": "running", + "health": "healthy", + "restarts": 0, + "exit": 0 + } +} \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/compose-final.log b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/compose-final.log new file mode 100644 index 00000000..f36c8403 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/compose-final.log @@ -0,0 +1,35 @@ +transmission | [migrations] started +transmission | [migrations] no migrations found +transmission | ─────────────────────────────────────── +transmission | +transmission | ██╗ ███████╗██╗ ██████╗ +transmission | ██║ ██╔════╝██║██╔═══██╗ +transmission | ██║ ███████╗██║██║ ██║ +transmission | ██║ ╚════██║██║██║ ██║ +transmission | ███████╗███████║██║╚██████╔╝ +transmission | ╚══════╝╚══════╝╚═╝ ╚═════╝ +transmission | +transmission | Brought to you by linuxserver.io +transmission | ─────────────────────────────────────── +transmission | +transmission | To support LSIO projects visit: +transmission | https://www.linuxserver.io/donate/ +transmission | +transmission | ─────────────────────────────────────── +transmission | GID/UID +transmission | ─────────────────────────────────────── +transmission | +transmission | User UID: 1000 +transmission | User GID: 1000 +transmission | ─────────────────────────────────────── +transmission | Linuxserver.io version: 4.1.2-r0-ls351 +transmission | Build-date: 2026-06-30T12:27:43+00:00 +transmission | ─────────────────────────────────────── +transmission | +transmission | stat: cannot statx '/downloads/complete': No such file or directory +transmission | find: ‘/downloads/complete’: No such file or directory +transmission | **** Permissions could not be set. This is probably because your volume mounts are remote or read-only. **** +transmission | **** The app may not work properly and we will not provide support for it. **** +transmission | [custom-init] No custom files found, skipping... +transmission | Connection to localhost (::1) 9091 port [tcp/*] succeeded! +transmission | [ls.io-init] done. diff --git a/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/engine-state.json b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/engine-state.json new file mode 100644 index 00000000..ec747fa4 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/engine-state.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/files-after-detail.json b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/files-after-detail.json new file mode 100644 index 00000000..a198d3f5 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/files-after-detail.json @@ -0,0 +1,4 @@ +{ + "/srv/felhom-gate/hdd/userdata/media/transmission": {}, + "/srv/felhom-gate/hdd/userdata/media/transmission/watch": {} +} \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/files-after.json b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/files-after.json new file mode 100644 index 00000000..f135fc5c --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/files-after.json @@ -0,0 +1,4 @@ +{ + "/srv/felhom-gate/hdd/userdata/media/transmission": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "/srv/felhom-gate/hdd/userdata/media/transmission/watch": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" +} \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/files-before-detail.json b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/files-before-detail.json new file mode 100644 index 00000000..a198d3f5 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/files-before-detail.json @@ -0,0 +1,4 @@ +{ + "/srv/felhom-gate/hdd/userdata/media/transmission": {}, + "/srv/felhom-gate/hdd/userdata/media/transmission/watch": {} +} \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/files-before.json b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/files-before.json new file mode 100644 index 00000000..f135fc5c --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/files-before.json @@ -0,0 +1,4 @@ +{ + "/srv/felhom-gate/hdd/userdata/media/transmission": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "/srv/felhom-gate/hdd/userdata/media/transmission/watch": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" +} \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/memory-samples.json b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/memory-samples.json new file mode 100644 index 00000000..49bb7913 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/memory-samples.json @@ -0,0 +1,762 @@ +[ + { + "t": 15.1, + "containers": { + "transmission": { + "limit": 536870912, + "current": 29204480, + "peak": 32493568, + "anon": 3280896, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 300 + }, + { + "t": 30.2, + "containers": { + "transmission": { + "limit": 536870912, + "current": 29020160, + "peak": 32493568, + "anon": 3280896, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 600 + }, + { + "t": 45.4, + "containers": { + "transmission": { + "limit": 536870912, + "current": 29392896, + "peak": 32493568, + "anon": 3280896, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 900 + }, + { + "t": 60.5, + "containers": { + "transmission": { + "limit": 536870912, + "current": 29216768, + "peak": 32825344, + "anon": 3280896, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 1200 + }, + { + "t": 75.7, + "containers": { + "transmission": { + "limit": 536870912, + "current": 29270016, + "peak": 32825344, + "anon": 3280896, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 1500 + }, + { + "t": 90.8, + "containers": { + "transmission": { + "limit": 536870912, + "current": 29790208, + "peak": 32825344, + "anon": 3280896, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 1801 + }, + { + "t": 105.9, + "containers": { + "transmission": { + "limit": 536870912, + "current": 29487104, + "peak": 32825344, + "anon": 3280896, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 2101 + }, + { + "t": 121.0, + "containers": { + "transmission": { + "limit": 536870912, + "current": 30281728, + "peak": 32825344, + "anon": 3289088, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 2401 + }, + { + "t": 136.2, + "containers": { + "transmission": { + "limit": 536870912, + "current": 29192192, + "peak": 32825344, + "anon": 3289088, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 2701 + }, + { + "t": 151.3, + "containers": { + "transmission": { + "limit": 536870912, + "current": 29552640, + "peak": 32825344, + "anon": 3289088, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 3001 + }, + { + "t": 166.4, + "containers": { + "transmission": { + "limit": 536870912, + "current": 29335552, + "peak": 32825344, + "anon": 3293184, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 3301 + }, + { + "t": 181.5, + "containers": { + "transmission": { + "limit": 536870912, + "current": 29507584, + "peak": 33361920, + "anon": 3293184, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 3601 + }, + { + "t": 196.7, + "containers": { + "transmission": { + "limit": 536870912, + "current": 30363648, + "peak": 33361920, + "anon": 3796992, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 3905 + }, + { + "t": 211.8, + "containers": { + "transmission": { + "limit": 536870912, + "current": 31752192, + "peak": 33361920, + "anon": 5107712, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 4205 + }, + { + "t": 227.0, + "containers": { + "transmission": { + "limit": 536870912, + "current": 46772224, + "peak": 47046656, + "anon": 16809984, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 4505 + }, + { + "t": 242.1, + "containers": { + "transmission": { + "limit": 536870912, + "current": 63754240, + "peak": 63827968, + "anon": 20672512, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 4805 + }, + { + "t": 257.2, + "containers": { + "transmission": { + "limit": 536870912, + "current": 72364032, + "peak": 73076736, + "anon": 19353600, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 5105 + }, + { + "t": 272.4, + "containers": { + "transmission": { + "limit": 536870912, + "current": 89751552, + "peak": 90591232, + "anon": 19046400, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 5405 + }, + { + "t": 287.5, + "containers": { + "transmission": { + "limit": 536870912, + "current": 108511232, + "peak": 108666880, + "anon": 18542592, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 5706 + }, + { + "t": 302.7, + "containers": { + "transmission": { + "limit": 536870912, + "current": 112844800, + "peak": 114921472, + "anon": 18595840, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 6006 + }, + { + "t": 317.8, + "containers": { + "transmission": { + "limit": 536870912, + "current": 118894592, + "peak": 119459840, + "anon": 18759680, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 6306 + }, + { + "t": 332.9, + "containers": { + "transmission": { + "limit": 536870912, + "current": 129499136, + "peak": 129974272, + "anon": 20180992, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 6606 + }, + { + "t": 348.1, + "containers": { + "transmission": { + "limit": 536870912, + "current": 144572416, + "peak": 145113088, + "anon": 22351872, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 6906 + }, + { + "t": 363.2, + "containers": { + "transmission": { + "limit": 536870912, + "current": 151588864, + "peak": 151846912, + "anon": 22626304, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 7206 + }, + { + "t": 378.3, + "containers": { + "transmission": { + "limit": 536870912, + "current": 162766848, + "peak": 162770944, + "anon": 22740992, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 7510 + }, + { + "t": 393.4, + "containers": { + "transmission": { + "limit": 536870912, + "current": 171028480, + "peak": 172408832, + "anon": 22790144, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 7810 + }, + { + "t": 408.6, + "containers": { + "transmission": { + "limit": 536870912, + "current": 177917952, + "peak": 178741248, + "anon": 22781952, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 8110 + }, + { + "t": 423.7, + "containers": { + "transmission": { + "limit": 536870912, + "current": 186368000, + "peak": 186642432, + "anon": 22773760, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 8410 + }, + { + "t": 438.8, + "containers": { + "transmission": { + "limit": 536870912, + "current": 194375680, + "peak": 194772992, + "anon": 22519808, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 8710 + }, + { + "t": 454.0, + "containers": { + "transmission": { + "limit": 536870912, + "current": 200634368, + "peak": 201076736, + "anon": 22528000, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 9010 + }, + { + "t": 469.1, + "containers": { + "transmission": { + "limit": 536870912, + "current": 208633856, + "peak": 209502208, + "anon": 22544384, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 9310 + }, + { + "t": 484.2, + "containers": { + "transmission": { + "limit": 536870912, + "current": 216813568, + "peak": 217448448, + "anon": 22269952, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 9611 + }, + { + "t": 499.4, + "containers": { + "transmission": { + "limit": 536870912, + "current": 222810112, + "peak": 222810112, + "anon": 22269952, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 9911 + }, + { + "t": 514.5, + "containers": { + "transmission": { + "limit": 536870912, + "current": 229953536, + "peak": 231510016, + "anon": 22265856, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 10211 + }, + { + "t": 529.6, + "containers": { + "transmission": { + "limit": 536870912, + "current": 238043136, + "peak": 238628864, + "anon": 22286336, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 10511 + }, + { + "t": 544.7, + "containers": { + "transmission": { + "limit": 536870912, + "current": 243933184, + "peak": 244301824, + "anon": 22294528, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 10811 + }, + { + "t": 559.9, + "containers": { + "transmission": { + "limit": 536870912, + "current": 253083648, + "peak": 253677568, + "anon": 22294528, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 11111 + }, + { + "t": 575.0, + "containers": { + "transmission": { + "limit": 536870912, + "current": 258396160, + "peak": 258625536, + "anon": 22286336, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 11411 + }, + { + "t": 590.1, + "containers": { + "transmission": { + "limit": 536870912, + "current": 269279232, + "peak": 269430784, + "anon": 22286336, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 11711 + }, + { + "t": 605.2, + "containers": { + "transmission": { + "limit": 536870912, + "current": 276484096, + "peak": 277352448, + "anon": 22294528, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 12011 + } +] \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/migration-lines.txt b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/migration-lines.txt new file mode 100644 index 00000000..d80e9fd1 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/migration-lines.txt @@ -0,0 +1,2 @@ +transmission | [migrations] started +transmission | [migrations] no migrations found \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/run.log b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/run.log new file mode 100644 index 00000000..4246f2d2 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/run.log @@ -0,0 +1,58 @@ +[18:03:40] scratch drive folders cleared before FROM (R-656): ['/srv/felhom-gate/hdd/userdata/media/transmission'] +[18:03:40] MV-transmission: deploying transmission at FROM {'transmission': 'lscr.io/linuxserver/transmission:version-4.1.2-r0'} +[18:04:11] FROM settled=True in 30.9s :: {"transmission": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}} +[18:04:11] transmission: session-set speed-limit-down=690 http=200 +[18:04:11] transmission: torrent-add http=200 ok=True +[18:04:12] transmission: limit kept, torrent present=True +[18:04:12] C1 (seed reads back BEFORE): True +[18:04:12] MV-transmission: swapping to TO {'transmission': 'lscr.io/linuxserver/transmission:version-4.1.3-r0'} +[18:04:16] TO up -d rc=0 +[18:04:47] TO settled=True in 30.9s :: {"transmission": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}} +[18:04:48] migration lines observed: 2 +[18:04:48] transmission: limit kept, torrent present=True +[18:04:48] RESULT (seed reads back AFTER): True +[18:04:48] memory watch: 600s, 4 callers on 1 path(s) at 172.18.0.2:9091 +[18:05:03] + 15s transmission=27M/512M peak=30M kills=0 rs=0 reqs=300 +[18:05:18] + 30s transmission=27M/512M peak=30M kills=0 rs=0 reqs=600 +[18:05:34] + 45s transmission=28M/512M peak=30M kills=0 rs=0 reqs=900 +[18:05:49] + 60s transmission=27M/512M peak=31M kills=0 rs=0 reqs=1200 +[18:06:04] + 76s transmission=27M/512M peak=31M kills=0 rs=0 reqs=1500 +[18:06:19] + 91s transmission=28M/512M peak=31M kills=0 rs=0 reqs=1801 +[18:06:34] + 106s transmission=28M/512M peak=31M kills=0 rs=0 reqs=2101 +[18:06:49] + 121s transmission=28M/512M peak=31M kills=0 rs=0 reqs=2401 +[18:07:04] + 136s transmission=27M/512M peak=31M kills=0 rs=0 reqs=2701 +[18:07:19] + 151s transmission=28M/512M peak=31M kills=0 rs=0 reqs=3001 +[18:07:35] + 166s transmission=27M/512M peak=31M kills=0 rs=0 reqs=3301 +[18:07:50] + 182s transmission=28M/512M peak=31M kills=0 rs=0 reqs=3601 +[18:08:05] + 197s transmission=28M/512M peak=31M kills=0 rs=0 reqs=3905 +[18:08:20] + 212s transmission=30M/512M peak=31M kills=0 rs=0 reqs=4205 +[18:08:35] + 227s transmission=44M/512M peak=44M kills=0 rs=0 reqs=4505 +[18:08:50] + 242s transmission=60M/512M peak=60M kills=0 rs=0 reqs=4805 +[18:09:05] + 257s transmission=69M/512M peak=69M kills=0 rs=0 reqs=5105 +[18:09:21] + 272s transmission=85M/512M peak=86M kills=0 rs=0 reqs=5405 +[18:09:36] + 288s transmission=103M/512M peak=103M kills=0 rs=0 reqs=5706 +[18:09:51] + 303s transmission=107M/512M peak=109M kills=0 rs=0 reqs=6006 +[18:10:06] + 318s transmission=113M/512M peak=113M kills=0 rs=0 reqs=6306 +[18:10:21] + 333s transmission=123M/512M peak=123M kills=0 rs=0 reqs=6606 +[18:10:36] + 348s transmission=137M/512M peak=138M kills=0 rs=0 reqs=6906 +[18:10:51] + 363s transmission=144M/512M peak=144M kills=0 rs=0 reqs=7206 +[18:11:07] + 378s transmission=155M/512M peak=155M kills=0 rs=0 reqs=7510 +[18:11:22] + 393s transmission=163M/512M peak=164M kills=0 rs=0 reqs=7810 +[18:11:37] + 409s transmission=169M/512M peak=170M kills=0 rs=0 reqs=8110 +[18:11:52] + 424s transmission=177M/512M peak=177M kills=0 rs=0 reqs=8410 +[18:12:07] + 439s transmission=185M/512M peak=185M kills=0 rs=0 reqs=8710 +[18:12:22] + 454s transmission=191M/512M peak=191M kills=0 rs=0 reqs=9010 +[18:12:37] + 469s transmission=198M/512M peak=199M kills=0 rs=0 reqs=9310 +[18:12:52] + 484s transmission=206M/512M peak=207M kills=0 rs=0 reqs=9611 +[18:13:08] + 499s transmission=212M/512M peak=212M kills=0 rs=0 reqs=9911 +[18:13:23] + 514s transmission=219M/512M peak=220M kills=0 rs=0 reqs=10211 +[18:13:38] + 530s transmission=227M/512M peak=227M kills=0 rs=0 reqs=10511 +[18:13:53] + 545s transmission=232M/512M peak=232M kills=0 rs=0 reqs=10811 +[18:14:08] + 560s transmission=241M/512M peak=241M kills=0 rs=0 reqs=11111 +[18:14:23] + 575s transmission=246M/512M peak=246M kills=0 rs=0 reqs=11411 +[18:14:38] + 590s transmission=256M/512M peak=256M kills=0 rs=0 reqs=11711 +[18:14:53] + 605s transmission=263M/512M peak=264M kills=0 rs=0 reqs=12011 +[18:14:54] memory watch: killed=False tight=[] requests=12011 codes={'401': 12011} +[18:14:54] MV-transmission: ABORT — putting the FROM images back +[18:15:30] transmission: limit kept, torrent present=True +[18:15:30] ABORT: app came back in 30.9s; data present=True \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/to-full.log b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/to-full.log new file mode 100644 index 00000000..e639d87e --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/to-full.log @@ -0,0 +1,39 @@ +transmission | [migrations] started +transmission | [migrations] no migrations found +transmission | ─────────────────────────────────────── +transmission | +transmission | ██╗ ███████╗██╗ ██████╗ +transmission | ██║ ██╔════╝██║██╔═══██╗ +transmission | ██║ ███████╗██║██║ ██║ +transmission | ██║ ╚════██║██║██║ ██║ +transmission | ███████╗███████║██║╚██████╔╝ +transmission | ╚══════╝╚══════╝╚═╝ ╚═════╝ +transmission | +transmission | Brought to you by linuxserver.io +transmission | ─────────────────────────────────────── +transmission | +transmission | To support LSIO projects visit: +transmission | https://www.linuxserver.io/donate/ +transmission | +transmission | ─────────────────────────────────────── +transmission | GID/UID +transmission | ─────────────────────────────────────── +transmission | +transmission | User UID: 1000 +transmission | User GID: 1000 +transmission | ─────────────────────────────────────── +transmission | Linuxserver.io version: 4.1.3-r0-ls363 +transmission | Build-date: 2026-09-29T16:34:59+00:00 +transmission | ─────────────────────────────────────── +transmission | +transmission | stat: cannot statx '/downloads/complete': No such file or directory +transmission | find: ‘/downloads/complete’: No such file or directory +transmission | **** Permissions could not be set. This is probably because your volume mounts are remote or read-only. **** +transmission | **** The app may not work properly and we will not provide support for it. **** +transmission | stat: cannot statx '/downloads/incomplete': No such file or directory +transmission | find: ‘/downloads/incomplete’: No such file or directory +transmission | **** Permissions could not be set. This is probably because your volume mounts are remote or read-only. **** +transmission | **** The app may not work properly and we will not provide support for it. **** +transmission | [custom-init] No custom files found, skipping... +transmission | Connection to localhost (::1) 9091 port [tcp/*] succeeded! +transmission | [ls.io-init] done. diff --git a/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/to-states.json b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/to-states.json new file mode 100644 index 00000000..443eecda --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/to-states.json @@ -0,0 +1,8 @@ +{ + "transmission": { + "status": "running", + "health": "healthy", + "restarts": 0, + "exit": 0 + } +} \ No newline at end of file diff --git a/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/verdict.json b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/verdict.json new file mode 100644 index 00000000..37e676b5 --- /dev/null +++ b/documentation/audits/qbittorrent-2026-10-12/transmission-bench/MV-transmission/verdict.json @@ -0,0 +1,58 @@ +{ + "harness_version": 5, + "edge": "MV-transmission", + "app": "transmission", + "note": "night 2026-09-23 within-a-major move: transmission=lscr.io/linuxserver/transmission:version-4.1.3-r0", + "from": { + "transmission": "lscr.io/linuxserver/transmission:version-4.1.2-r0" + }, + "to": { + "transmission": "lscr.io/linuxserver/transmission:version-4.1.3-r0" + }, + "verdict": "proven", + "seed_read_before": true, + "seed_read_after": true, + "healthy_after": true, + "migration_observed": "\u001b[2Ktransmission | [migrations] started", + "abort": "starts-and-serves", + "abort_detail": null, + "engine_state_after": null, + "memory": { + "soak_s": 605.4, + "requested_s": 600, + "requests": 12011, + "codes": { + "401": 12011 + }, + "first_kill": null, + "containers": { + "transmission": { + "limit": 536870912, + "peak": 277352448, + "peak_pct": 0.517, + "anon_peak_sampled": 22790144, + "anon_peak_pct": 0.042, + "swap_peak": 0, + "oom_kills": 0, + "restarts": 0, + "oomkilled_flag": false, + "measured": true + } + }, + "unmeasured": [], + "venue_swap_bytes": 0, + "load": "reached" + }, + "marks": [], + "bench_overrides": null, + "duration_s": 30.9, + "measured_at": "2026-10-12T18:15:30Z", + "evidence": "evidence/MV-transmission", + "scratch_cleared": [ + "/srv/felhom-gate/hdd/userdata/media/transmission" + ], + "files_changed": [], + "files_changed_detail": [], + "files_ignored": [], + "total_s": 709.8 +} \ No newline at end of file diff --git a/documentation/backlog/OPEN-ITEMS.md b/documentation/backlog/OPEN-ITEMS.md index 667f5cb1..930caa37 100644 --- a/documentation/backlog/OPEN-ITEMS.md +++ b/documentation/backlog/OPEN-ITEMS.md @@ -122,7 +122,7 @@ stopping line that lies. | **R-494** | Install & onboarding | P4 | **NARROWED 2026-09-14 by operator ruling → [P3-LOW] the hub COULD create the tunnel at customer creation, for a domain already on Cloudflare. Not blocking: every customer has their own domain and the operator creates the tunnel per day-0 A.1 (`architecture/01-topology-and-trust.md`).** *Original finding, kept:* **[P1-HIGH] A new customer's dashboard has NO reachable address unless the operator hand-makes a Cloudflare tunnel — the link in the setup-code mail is dead.** MEASURED 2026-09-14 on a fresh install from the public ISO (drill intervention **I1**): the claim mail points at `https://felhom.drill0242.felhom.eu`; that name has **no A and no AAAA** record (`dig @1.1.1.1`, control `felhom.enkisfelhom.hu` resolves); the hub has **no tunnel- or DNS-creation code** (`hub/internal/cloudflare/` holds only geo-rule removal; `cf_tunnel_token` is a pasted, optional form field, `configs.go:1478`) — day-0 runbook A.1 makes it a manual Cloudflare-dashboard step that nothing on the customer-create page asks for; the box's own split-horizon resolver on the appliance LAN IP answered `google.com` but not the dashboard name at 13:27:39Z; the agent applied the record at **13:27:44Z** (`lanresolver: applied split-horizon record … ip=192.168.0.158`, 3 m 46 s after the controller started), so the box CAN answer the name — **but only to a device that uses the box as its DNS server, and no document, screen or mail tells a household to do that**; the router and the installer-offered DNS answer nothing. The page was reachable only at the guest's LAN address with the name forced (`curl --resolve …:443:192.168.0.158`). **A volunteer could not have done that.** **What it needs:** an operator ruling — the hub creates the tunnel and DNS at customer creation, or the product gives a household a LAN address that works with no DNS change. | **READY — rank P3-LOW; owner: CC** **Re-ranked 2026-10-03: P3→P4: operator-side automation; the operator creates the tunnel by hand per the day-0 runbook.** | — | — | CC | | **R-504** | Install & onboarding | P4 | **[P3-LOW] `iso.felhom.eu` cannot show an index page on its own — its root returns 404, and the download page lives on the website instead.** MEASURED 2026-09-14: `https://iso.felhom.eu/` and `/index.html` → 404; only named objects answer. The host is an R2 bucket behind a custom domain; whether R2 would serve an uploaded `index.html` at `/` was **not measured** (uploading anything to the public bucket is a publication). The ISO v1.27.0 task puts the Hungarian download page at `felhom.eu/letoltes` (published with the ISO, after the operator's yes). **Remaining:** a redirect from `iso.felhom.eu/` to that page needs a Cloudflare rule the session has no credential for. | **WAITING-ON-OPERATOR — rank P3-LOW; owner: operator (Cloudflare rule)** **Re-ranked 2026-10-03: P3→P4: households are sent to the website's download page; the bare address is cosmetic.** | — | — | operator | -## Apps & catalog — 6 rows (P2 1, P3 2, P4 3) +## Apps & catalog — 7 rows (P2 1, P3 2, P4 4) | ID | Category | Sev | What | State | Blocked on | Next action | Owner | |---|---|---|---|---|---|---|---| @@ -132,6 +132,7 @@ stopping line that lies. | **R-76** | Apps & catalog | P4 | **FileBrowser-created folders break the setgid chain, and a drop-zone's mode is not stable** **MIGRATED FROM `ROADMAP.md` 2026-08-22 (R-369) — originally filed 2026-07-26, size S, roadmap state `idea (surfaced by the R-75 spike, 2026-07-26)`.** Moved verbatim; nothing added or reinterpreted. The roadmap keeps its copy as history, marked moved. | **OPEN — migrated from ROADMAP 2026-08-22, rank unchanged** **2026-10-06 night: not a catalog fix** — the setgid chain is set by the controller's FileBrowser setup; a controller row. | — | Two related findings from `audits/SPIKE-catalog-data-paths-2026-07-26.md` P3/P5, both **pre-existing** and deliberately left alone by that spike. **(a)** FileBrowser Quantum 1.3.3 creates files `0644` and folders `0755` and does **not** propagate the setgid bit — even though the entrypoint wrapper's `umask 002` really is in effect (`/proc/1/status` `Umask: 0002`). Group inheritance itself works (a file uploaded into a 2775 group-100 dir landed group 100, not the process gid 1000), so the convention's *group* half holds and only its *mode* half is lost. The consequence is proven with a control: inside a UI-created `0755` folder a gid-1000 process's file landed group **1000**, while the identical write into the 2775 parent landed group **100**. So **any folder a customer creates through FileBrowser breaks the shared-group chain one level down.** Latent today — every userdata-touching catalog app that declares an identity declares uid/gid **1000**, the same uid FileBrowser runs as, so owner permissions mask it; it bites the day a content app runs as a different non-root uid with gid 1000. The comment at `infra/infra.go:156` is right that the image ignores `-e UMASK` but does not say t | CC | | **R-707** | Apps & catalog | P4 | **[P2] 37 apps still start with a login a stranger can take (`09` §3 decision 45).** Audit of all 53 apps: `app-catalog-felhom.eu/FIRST-ADMIN.md` (class, fix route, status, measured or read). Open: **3 hard-coded defaults** — calibre-web (`admin / admin123`, measured working on demo-hp and 9202; its own `cps.py -s` route needs a generated password WITH a special character — our generator is letters+digits, a controller change), mealie (`changeme@example.com / MyPassword`), wger (`admin / adminadmin`); **34 open first-run screens** (the first visitor creates the admin: actualbudget, adventurelog, audiobookshelf, calcom, docmost, emby, ghost, gitea, gramps-web, home-assistant, homebox, immich, jellyfin, komga, n8n, navidrome, opengist, outline, papra, plant-it, radarr, rallly, recipe-importer, romm, seerr, sonarr, sparkyfitness, tandoor, termix, uptime-kuma, vikunja, wanderer, wishlist, zipline). **Stale notes:** romm's `default_creds` `admin / admin` answers 401 on demo-hp (like a wrong password) — the page now warns with a login that does not exist; zipline's looks stale too. **Measured on demo-hp 2026-09-28 (read-only):** bookstack's default still logs in on the INSTALLED app (the fix is for new installs; the page now warns). Each fix: route (a) env or (b) the app's own CLI/API via `after_install:`, proven on 9202 with the default failing and the generated password working; route (c) a page sentence. Several sessions (operator, 2026-09-28). **2026-09-29 (controller v0.280.0, catalog `d0e7e2e`):** every class-3 app fixed — mealie, wger, calibre-web by `after_install` (calibre-web with the new `password:24:special`), proven on 9202 fresh installs (`audits/login-gate-2026-09-29/D/`); the setup gate (decision 46, spike PASSED) built and live on immich, n8n, audiobookshelf (probes measured) and uptime-kuma (button) (`…/C/`); romm's and zipline's stale notes removed. **Left: 30 class-4 apps** — gate each (probe measured on 9202 where one exists — 11 upstream candidates listed in `…/B/B-VERDICT.md` §3; the button otherwise). **2026-09-29 afternoon (controller v0.281.0, catalog `6faf432`):** 28 more class-4 apps gated — 32 of 34 — each proven on 9202 (`audits/gate-rollout-2026-09-29/`B): stranger → gate page / 401, household reached the first-setup screen, the gate opened (9 by a measured probe, the rest by the press), the app answered after. seerr, outline, rallly: gated, their opening needs a media server / e-mail (not proven). **Left:** wanderer (R-714); plant-it is not installable. | **NARROWED** (2026-10-03 triage: the row's verdict was finished, but it names open work no other row carries — seerr, outline and rallly are gated, but the gate OPENING is not proven (needs a media server / e-mail)) — **CLOSED — 2026-09-29 (the rest → R-714)** | — | — | CC | | **R-905** | Apps & catalog | P4 | **wger's collected style files (283 MB) go into every wger backup, though the app rebuilds them at every start.** Since R-762's fix (`DJANGO_DEBUG=False` + `collectstatic`, catalog `cf1ed43`) the static files sit in a named volume that the backup legs copy like data (measured 283 MB, `audits/design-build-2026-10-06/`); `collectstatic` regenerates them, so they are rebuildable bytes in every Tier-1 unit, Tier-2 copy and off-site snapshot. wger is `lifecycle: hidden` and no box runs it (hub read 2026-10-08). Options to weigh: a non-backed-up volume class for regenerable data, or an anonymous volume. Found by the R-762 helpers 2026-10-08. | **OPEN — needs a design before wger is shown** | — | Design the „regenerable volume" exclusion (catalog + controller backup legs) | CC | +| **R-988** | Apps & catalog | P4 | **The Usenet pair the operator asked for on 2026-10-12: SABnzbd and NZBGet.** Same shape as the torrent pair published the same day (`app-catalog-felhom.eu` `9081a47`) and the same pipeline: a template each, a bench run on LXC 9401, a box walk on 9202 through the product, a first ladder step written by `upgrade-test.py --write-ladder`, a complete onboarding record, README + FIRST-ADMIN rows, and the app cards. Two things are known already and decide the shape: **SABnzbd publishes no image of its own** (so `lscr.io/linuxserver/sabnzbd`, the same third-party exception Transmission got, which the operator granted on 2026-10-12), while **NZBGet has the project's own `nzbgetcom/nzbget`**; and **both need a PAID Usenet provider (server, port, username, password), which the household must bring** - so the app page has to say so before the install, and a provider's credentials are deploy fields the household types, never generated. Neither can be exercised end to end without an account, so the record will say what was measured without one and what it cost. | OPEN - operator request, not started | - | Write both templates; bench then box, as for the torrent pair | CC | ## App updates — 4 rows (P3 4) diff --git a/website/CHANGELOG.md b/website/CHANGELOG.md index 4a877aca..ecf29803 100644 --- a/website/CHANGELOG.md +++ b/website/CHANGELOG.md @@ -1,4 +1,27 @@ -## 2026-10-12 (evening) — the privacy notice says what happens to a tester's name +## 2026-10-12 (night) — two download clients on the app page, and what they cost behind a tunnel + +The catalog gained qBittorrent and Transmission (`app-catalog-felhom.eu` CHANGELOG, same day). The +website follows them. + +- **Two new cards** in the media category on `alkalmazasok.html` and `en/apps.html`, each with the + project's own logo (`assets/qbittorrent-logo.svg`, `assets/transmission-logo.svg`): qBittorrent as + the full client, Transmission as the light one, with the sentence that says which to choose. +- **Each card states the limit the topology imposes**: the box opens no port at home, so port + mapping is off and the peer port is not published — downloads work, incoming peer connections do + not, which means slower swarms on thin torrents. It is a real limit and belongs on the page rather + than in a surprise. +- **The published count moves 58 → 60** on every page that states it (both language sets): + `index.html`, `szolgaltatasok.html`, `technologiak.html`, `gyik.html` and their twins. The FAQ's + JSON-LD answer moved with its visible answer, as the twin and FAQ gates require. +- `documentation/audits/qbittorrent-2026-10-12/` holds the whole campaign: the bench runs for both + apps, the box walk on scratch guest 9202, the six defects with their measurements, and the + re-measurement from two addresses that showed the apparent household lock-out to be an artefact of + measuring from one machine. +- `documentation/audits/pg-last-six-2026-09-30/tools/walk.py`: a `type: path` deploy field is filled + with the drive ROOT, not a folder on it — the controller refuses a path inside a drive (409), so + the walker could not install an app with a drive field at all. + +## 2026-10-12 (evening) — the privacy notice says what happens to a tester's name The first real tester answered on Prohardver today. His domain is bought **in his name** (test terms 1.1 §4), which means his name, address, e-mail and telephone number leave this house — and the diff --git a/website/alkalmazasok.html b/website/alkalmazasok.html index 186879ad..c2f99365 100644 --- a/website/alkalmazasok.html +++ b/website/alkalmazasok.html @@ -4,8 +4,8 @@ - Telepíthető alkalmazások — 58 app otthoni szerverre | Felhom.eu - + Telepíthető alkalmazások — 60 app otthoni szerverre | Felhom.eu + @@ -16,14 +16,14 @@ - + - + @@ -33,7 +33,7 @@ "@type": "ItemList", "name": "Felhom.eu — Telepíthető alkalmazások", "description": "Önhostolt alkalmazások otthoni szerverre, szinte mind nyílt forráskódú", - "numberOfItems": 58, + "numberOfItems": 60, "itemListElement": [ {"@type": "ListItem", "position": 1, "name": "Nextcloud", "description": "Fájlkezelés és irodai csomag"}, {"@type": "ListItem", "position": 2, "name": "Immich", "description": "Fotó és videó kezelés (Google Photos alternatíva)"}, @@ -101,7 +101,7 @@ -

Válassz 58 alkalmazás közül. Szinte mind ingyenes, nyílt forráskódú szoftver, és mind a saját szervereden fut.

+

Válassz 60 alkalmazás közül. Szinte mind ingyenes, nyílt forráskódú szoftver, és mind a saját szervereden fut.

Fontos tudnivalók

    @@ -392,6 +392,36 @@ Open Source
+ +
+
+ +

qBittorrent

Torrent letöltő
+
+
+

Torrentek letöltése a saját meghajtódra, böngészőből vezérelve. Sorban állás, sebességkorlát és ütemezés: éjjel tölthet, nappal nem zavarja a netedet. A Radarr és a Sonarr ehhez adja át a letöltéseket.

+
Saját meghajtóraSebességkorlátÜtemezésRadarr/Sonarr
+
+ +
+ +
+
+ +

Transmission

Egyszerű torrent letöltő
+
+
+

Ugyanaz a munka, egyszerűbb felülettel és töredék erőforrásból: mérve 6 MB memória. Kisebb gépen is elfér a többi alkalmazás mellett. A kész fájlokat a fájlböngészőben és a médialejátszódban is látod.

+
Nagyon kevés erőforrásEgyszerű felületSaját meghajtóraRadarr/Sonarr
+
+ +
@@ -450,8 +480,8 @@

Sonarr

Sorozat menedzser
-

Automatikus sorozat letöltő és rendszerező. Kövesd a kedvenc sorozataidat, és az új epizódok automatikusan letöltődnek.

-
Auto letöltésNaptárMinőség kezelésIntegráció
+

Sorozatok rendszerezője: kövesd a kedvenceidet, és az új epizódok maguktól a könyvtáradba kerülnek. Maga a letöltés a qBittorrent vagy a Transmission dolga — azt is telepítsd mellé.

+
LetöltőkliensselNaptárMinőség kezelésIntegráció
Sonarr screenshot @@ -468,8 +498,8 @@

Radarr

Film menedzser
-

Automatikus film letöltő és rendszerező. Készíts kívánságlistát, és a filmek automatikusan a könyvtáradba kerülnek.

-
KívánságlistaAuto letöltésMinőség kezelésIntegráció
+

Filmek rendszerezője: készíts kívánságlistát, és a filmek maguktól a könyvtáradba kerülnek. Maga a letöltés a qBittorrent vagy a Transmission dolga — azt is telepítsd mellé.

+
KívánságlistaLetöltőkliensselMinőség kezelésIntegráció
Radarr screenshot
@@ -485,7 +515,7 @@

Seerr

Média kérés kezelő
-

Filmek és sorozatok igénylése egyszerűen. A család/barátok kérhetnek tartalmakat, amiket automatikusan letölt a rendszer.

+

Filmek és sorozatok igénylése egyszerűen: a család kérhet tartalmakat, és a Radarr vagy a Sonarr veszi fel a listára. A letöltéshez a qBittorrent vagy a Transmission is kell.

Kérés kezelésFelhasználókÉrtesítésekIntegráció
Seerr screenshot @@ -1261,7 +1291,7 @@
-

58

+

60

Elérhető alkalmazás

diff --git a/website/assets/qbittorrent-logo.svg b/website/assets/qbittorrent-logo.svg new file mode 100644 index 00000000..7bbcf9ba --- /dev/null +++ b/website/assets/qbittorrent-logo.svg @@ -0,0 +1,16 @@ + + + qbittorrent-new-light + + + + + + + + + + + + + diff --git a/website/assets/transmission-logo.svg b/website/assets/transmission-logo.svg new file mode 100644 index 00000000..0d5fb793 --- /dev/null +++ b/website/assets/transmission-logo.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/en/apps.html b/website/en/apps.html index dcd16cd5..cdbefc0c 100644 --- a/website/en/apps.html +++ b/website/en/apps.html @@ -4,8 +4,8 @@ - Apps to install — 58 apps for a home server | Felhom.eu - + Apps to install — 60 apps for a home server | Felhom.eu + @@ -16,14 +16,14 @@ - + - + @@ -33,7 +33,7 @@ "@type": "ItemList", "name": "Felhom.eu — Apps to install", "description": "Self-hosted apps for a home server, almost all of them open source", - "numberOfItems": 58, + "numberOfItems": 60, "itemListElement": [ {"@type": "ListItem", "position": 1, "name": "Nextcloud", "description": "Files and office suite"}, {"@type": "ListItem", "position": 2, "name": "Immich", "description": "Photos and videos (a Google Photos alternative)"}, @@ -101,7 +101,7 @@ -

Choose from 58 apps. Almost all of them are free, open-source software, and every one runs on your own server.

+

Choose from 60 apps. Almost all of them are free, open-source software, and every one runs on your own server.

Good to know

    @@ -392,6 +392,36 @@ Open Source
+ +
+
+ +

qBittorrent

Torrent downloader
+
+
+

Download torrents to your own drive, driven from the browser. Queueing, speed limits and scheduling: it can download at night and leave your line alone by day. Radarr and Sonarr hand their downloads to this.

+
To your own driveSpeed limitsSchedulingRadarr/Sonarr
+
+ +
+ +
+
+ +

Transmission

A simple torrent downloader
+
+
+

The same job with a simpler interface and a fraction of the resources: 6 MB of memory, measured. It fits on a small machine beside everything else. You see the finished files in the file browser and in your media player.

+
Very lightSimple interfaceTo your own driveRadarr/Sonarr
+
+ +
@@ -450,8 +480,8 @@

Sonarr

Series manager
-

Downloads and organises series for you. Follow your favourite series and new episodes are downloaded automatically.

-
Auto downloadCalendarQuality profilesIntegrations
+

Organises your series: follow your favourites and new episodes arrive on their own. The downloading itself is done by qBittorrent or Transmission — install one of those too.

+
With a download clientCalendarQuality profilesIntegrations
Sonarr screenshot @@ -468,8 +498,8 @@

Radarr

Film manager
-

Downloads and organises films for you. Make a wish list and the films arrive in your library on their own.

-
Wish listAuto downloadQuality profilesIntegrations
+

Organises your films: make a wish list and they arrive in your library on their own. The downloading itself is done by qBittorrent or Transmission — install one of those too.

+
Wish listWith a download clientQuality profilesIntegrations
Radarr screenshot
@@ -485,7 +515,7 @@

Seerr

Media request manager
-

Ask for films and series the easy way. Family and friends can request titles, and the system downloads them for you.

+

Ask for films and series the easy way: the family requests a title and Radarr or Sonarr puts it on the list. Getting it also needs qBittorrent or Transmission.

RequestsUsersNotificationsIntegrations
Seerr screenshot @@ -1261,7 +1291,7 @@
-

58

+

60

Apps available

diff --git a/website/en/faq.html b/website/en/faq.html index 7e755775..96540397 100644 --- a/website/en/faq.html +++ b/website/en/faq.html @@ -61,7 +61,7 @@ "name": "How is Felhom.eu different from a Synology or QNAP NAS?", "acceptedAnswer": { "@type": "Answer", - "text": "Synology and QNAP make NAS (network storage) devices built mainly for storing files, with their own closed software. I offer an open, Docker-based system instead, where the catalog's apps install in a few clicks – from a photo manager to a media server to a password manager. A NAS offers a limited choice of apps and depends on the maker's software updates. With Felhom you choose from 58 apps, and if something is missing, I look at whether it can be added." + "text": "Synology and QNAP make NAS (network storage) devices built mainly for storing files, with their own closed software. I offer an open, Docker-based system instead, where the catalog's apps install in a few clicks – from a photo manager to a media server to a password manager. A NAS offers a limited choice of apps and depends on the maker's software updates. With Felhom you choose from 60 apps, and if something is missing, I look at whether it can be added." } }, { @@ -133,7 +133,7 @@ "name": "Which apps can I run?", "acceptedAnswer": { "@type": "Answer", - "text": "I offer 58 apps – the full list is on the Apps page. A few examples: Immich – a Google Photos alternative that backs up photos and videos automatically. Jellyfin/Plex – your own Netflix for films and series. Nextcloud – store and share files (instead of Google Drive). Vaultwarden – a password manager for the whole family. Paperless-ngx – scan documents and make them searchable. If something is not on the list, ask – I will look at whether it can join the catalog." + "text": "I offer 60 apps – the full list is on the Apps page. A few examples: Immich – a Google Photos alternative that backs up photos and videos automatically. Jellyfin/Plex – your own Netflix for films and series. Nextcloud – store and share files (instead of Google Drive). Vaultwarden – a password manager for the whole family. Paperless-ngx – scan documents and make them searchable. If something is not on the list, ask – I will look at whether it can join the catalog." } }, { @@ -491,7 +491,7 @@

Synology and QNAP make NAS (network storage) devices built mainly for storing files, with their own closed software. I offer an open, Docker-based system instead, where the catalog's apps install in a few clicks – from a photo manager to a media server to a password manager.

-

A NAS offers a limited choice of apps and depends on the maker's software updates. With Felhom you choose from 58 apps, and if something is missing, I look at whether it can be added.

+

A NAS offers a limited choice of apps and depends on the maker's software updates. With Felhom you choose from 60 apps, and if something is missing, I look at whether it can be added.

@@ -607,7 +607,7 @@
-

I offer 58 apps – the full list is on the Apps page. A few examples:

+

I offer 60 apps – the full list is on the Apps page. A few examples:

Immich – a Google Photos alternative that backs up photos and videos automatically. Jellyfin/Plex – your own Netflix for films and series. Nextcloud – store and share files (instead of Google Drive). Vaultwarden – a password manager for the whole family. Paperless-ngx – scan documents and make them searchable.

If something is not on the list, ask – I will look at whether it can join the catalog.

diff --git a/website/en/index.html b/website/en/index.html index 05e11322..c3544377 100644 --- a/website/en/index.html +++ b/website/en/index.html @@ -5,7 +5,7 @@ - + Felhom.eu — Your own cloud, your own rules | A home server service in Hungary @@ -139,7 +139,7 @@
  • Photos, documents, media
  • Network shares
  • -
  • 58 apps to install
  • +
  • 60 apps to install
  • @@ -245,7 +245,7 @@

    What you can install

    -

    58 apps — almost all of them open source

    +

    60 apps — almost all of them open source

    See all applications →
    diff --git a/website/en/services.html b/website/en/services.html index 477c726b..b21e5757 100644 --- a/website/en/services.html +++ b/website/en/services.html @@ -5,7 +5,7 @@ Services — what a Felhom box does today | Felhom.eu - + @@ -110,7 +110,7 @@

    The box's folders appear in Windows File Explorer and the Mac Finder — you drag files onto them like onto any other folder. Each share can be set to read-only.

  • -

    58 apps to install

    +

    60 apps to install

    You install them from the Dashboard in a few clicks — no command line. Almost all of them are open source (the exceptions are marked on the apps page), and every one runs on your machine.

  • diff --git a/website/en/technology.html b/website/en/technology.html index 7e60d04d..4358bf17 100644 --- a/website/en/technology.html +++ b/website/en/technology.html @@ -178,7 +178,7 @@
    • A web interface in English or Hungarian – the household chooses, and no command-line knowledge is needed
    • -
    • App catalog – 58 apps to install in a few clicks
    • +
    • App catalog – 60 apps to install in a few clicks
    • Resource view – memory and storage use as it happens
    • Automatic backups – databases and files, with their status watched
    • App updates – only versions we have tried, a fresh backup first, and if the new version does not start, the box goes back to the previous one by itself
    • diff --git a/website/gyik.html b/website/gyik.html index 8e9d5f1c..4cd0d378 100644 --- a/website/gyik.html +++ b/website/gyik.html @@ -61,7 +61,7 @@ "name": "Mi a különbség a Felhom.eu és a Synology/QNAP NAS szolgáltatásai között?", "acceptedAnswer": { "@type": "Answer", - "text": "A Synology és QNAP elsősorban fájltárolásra készült NAS (hálózati adattároló) eszközök, saját zárt szoftverrel. Én ezzel szemben egy nyílt, Docker-alapú rendszert kínálok, amelyre a katalógus alkalmazásai pár kattintással telepíthetők – fotókezelőtől a média szerveren át a jelszókezelőig. A NAS-ok korlátozott alkalmazás-választékot kínálnak és a gyártó szoftverfrissítéseitől függenek. A Felhomnál 58 alkalmazásból válogathatsz, és ha valami hiányzik, megnézem, felvehető-e." + "text": "A Synology és QNAP elsősorban fájltárolásra készült NAS (hálózati adattároló) eszközök, saját zárt szoftverrel. Én ezzel szemben egy nyílt, Docker-alapú rendszert kínálok, amelyre a katalógus alkalmazásai pár kattintással telepíthetők – fotókezelőtől a média szerveren át a jelszókezelőig. A NAS-ok korlátozott alkalmazás-választékot kínálnak és a gyártó szoftverfrissítéseitől függenek. A Felhomnál 60 alkalmazásból válogathatsz, és ha valami hiányzik, megnézem, felvehető-e." } }, { @@ -133,7 +133,7 @@ "name": "Milyen alkalmazásokat tudok futtatni?", "acceptedAnswer": { "@type": "Answer", - "text": "58 alkalmazást kínálok – a teljes listát az Alkalmazások oldalon találod. Néhány példa: Immich – Google Photos alternatíva fotók és videók automatikus mentésével. Jellyfin/Plex – saját Netflix filmekhez és sorozatokhoz. Nextcloud – fájlok tárolása és megosztása (Google Drive helyett). Vaultwarden – jelszókezelő az egész családnak. Paperless-ngx – dokumentumok digitalizálása és kereshetővé tétele. Ha valami nincs a listán, kérdezz – megnézem, felvehető-e a katalógusba." + "text": "60 alkalmazást kínálok – a teljes listát az Alkalmazások oldalon találod. Néhány példa: Immich – Google Photos alternatíva fotók és videók automatikus mentésével. Jellyfin/Plex – saját Netflix filmekhez és sorozatokhoz. Nextcloud – fájlok tárolása és megosztása (Google Drive helyett). Vaultwarden – jelszókezelő az egész családnak. Paperless-ngx – dokumentumok digitalizálása és kereshetővé tétele. Ha valami nincs a listán, kérdezz – megnézem, felvehető-e a katalógusba." } }, { @@ -491,7 +491,7 @@

      A Synology és QNAP elsősorban fájltárolásra készült NAS (hálózati adattároló) eszközök, saját zárt szoftverrel. Én ezzel szemben egy nyílt, Docker-alapú rendszert kínálok, amelyre a katalógus alkalmazásai pár kattintással telepíthetők – fotókezelőtől a média szerveren át a jelszókezelőig.

      -

      A NAS-ok korlátozott alkalmazás-választékot kínálnak és a gyártó szoftverfrissítéseitől függenek. A Felhomnál 58 alkalmazásból válogathatsz, és ha valami hiányzik, megnézem, felvehető-e.

      +

      A NAS-ok korlátozott alkalmazás-választékot kínálnak és a gyártó szoftverfrissítéseitől függenek. A Felhomnál 60 alkalmazásból válogathatsz, és ha valami hiányzik, megnézem, felvehető-e.

  • @@ -607,7 +607,7 @@
    -

    58 alkalmazást kínálok – a teljes listát az Alkalmazások oldalon találod. Néhány példa:

    +

    60 alkalmazást kínálok – a teljes listát az Alkalmazások oldalon találod. Néhány példa:

    Immich – Google Photos alternatíva fotók és videók automatikus mentésével. Jellyfin/Plex – saját Netflix filmekhez és sorozatokhoz. Nextcloud – fájlok tárolása és megosztása (Google Drive helyett). Vaultwarden – jelszókezelő az egész családnak. Paperless-ngx – dokumentumok digitalizálása és kereshetővé tétele.

    Ha valami nincs a listán, kérdezz – megnézem, felvehető-e a katalógusba.

    diff --git a/website/index.html b/website/index.html index 45fec303..04d1c2bd 100644 --- a/website/index.html +++ b/website/index.html @@ -5,7 +5,7 @@ - + Felhom.eu — Saját felhőd, saját szabályaid | Otthoni szerver szolgáltatás @@ -139,7 +139,7 @@
    • Fényképek, dokumentumok, média
    • Hálózati megosztás
    • -
    • 58 telepíthető alkalmazás
    • +
    • 60 telepíthető alkalmazás
  • @@ -245,7 +245,7 @@

    Amit telepíthetsz

    -

    Fájlkezelés, fotók és média, dokumentumok, jelszókezelés, okosotthon, fejlesztői eszközök. Nextcloud, Immich, Jellyfin, Paperless-ngx, Vaultwarden, Home Assistant és még 52 másik: 58 alkalmazás, szinte mind nyílt forráskódú.

    +

    Fájlkezelés, fotók és média, dokumentumok, jelszókezelés, okosotthon, fejlesztői eszközök. Nextcloud, Immich, Jellyfin, Paperless-ngx, Vaultwarden, Home Assistant és még 54 másik: 60 alkalmazás, szinte mind nyílt forráskódú.

    Összes alkalmazás megtekintése →
    diff --git a/website/szolgaltatasok.html b/website/szolgaltatasok.html index 88eacafa..b998df33 100644 --- a/website/szolgaltatasok.html +++ b/website/szolgaltatasok.html @@ -5,7 +5,7 @@ Szolgáltatások — mit tud ma a Felhom doboz | Felhom.eu - + @@ -110,7 +110,7 @@

    A doboz mappái megjelennek a Windows Intézőben és a Mac Finderben: úgy húzod rájuk a fájlokat, mint bármelyik másik mappára. Megosztásonként beállítható, hogy csak olvasható legyen.

  • -

    58 telepíthető alkalmazás

    +

    60 telepíthető alkalmazás

    A vezérlőpultból telepíthetők, pár kattintással, parancssor nélkül. Szinte mind nyílt forráskódú, és mind a te gépeden fut.

  • diff --git a/website/technologiak.html b/website/technologiak.html index 36b8bb79..677c43ab 100644 --- a/website/technologiak.html +++ b/website/technologiak.html @@ -178,7 +178,7 @@
    • Magyar vagy angol webes felület – a háztartás választ, és nincs szükség parancssor ismeretre
    • -
    • Alkalmazás katalógus – 58 app telepíthető pár kattintással
    • +
    • Alkalmazás katalógus – 60 app telepíthető pár kattintással
    • Erőforrás figyelés – memória és tárhely használat valós időben
    • Automatikus mentések – adatbázis és fájl backup, állapotfigyeléssel
    • Alkalmazás frissítések – csak kipróbált verzió, előtte friss mentés, és ha az új verzió nem indul, a doboz magától visszaáll az előzőre