docs: DIAG-sharing addendum — S-1/S-2/S-4-core/S-5 shipped in controller v0.151.0; S-3 stays open
Also records against R-45 the lesson the loop taught: a phase a client answers with a one-shot action must be an EDGE the registry serves once, never a level synthesised into the phase channel.
This commit is contained in:
@@ -216,11 +216,11 @@ starts with "which network am I actually on".
|
||||
|
||||
| # | Sev | Finding | Evidence | Proposed fix | GO needed? |
|
||||
|---|---|---|---|---|---|
|
||||
| **S-1** | **HIGH** | `/sharing` reload-loops forever for every customer with sharing enabled — the page is unusable. `sharingStatusHandler` reports `running` as a level; the JS treats it as a one-shot success edge and calls `location.reload()`. | `sharing_handlers.go:246` (blame `b5d78d1`), `sharing.html` L320–326, 6× identical `phase:"running"` poll | **XS.** Make the JS reload only when it has *observed a transition* — latch a `sawInFlight` flag on the first tick and reload on `running` only if it is set; otherwise just paint the success alert and stop. Server-side alternative (also XS): report the coerced level as a distinct phase (`running_steady`) the JS renders but never reloads on. Prefer the JS latch — it keeps the honest "liveness wins" contract the handler comment states. **Needs a red-proof:** a template/JS test or handler test asserting a fresh page load with a live container does not schedule a reload. | no — plain bug fix |
|
||||
| **S-2** | **MED** | The UI never tells the customer *where* to connect. `sharing.html` L32/L61 show only `\\FELHOM`; there is no IP anywhere on the page, so a customer who cannot resolve the name has nothing to fall back on and will guess (Viktor guessed the Proxmox host IP). | `sharing.html` L30–32, L61; symptom 1 itself | **S.** Render the guest's current LAN address beside the name: `\\FELHOM` *(vagy `smb://192.168.0.104`)*, sourced from the same place the dashboard already knows the guest IP. Add a one-line macOS hint (Finder → Ugrás → Csatlakozás a szerverhez). | no |
|
||||
| **S-3** | **MED** | No mDNS/Bonjour advertisement. `smbd + nmbd + wsdd` covers Windows (WSD) and legacy NetBIOS, but macOS Finder's preferred path is Bonjour — `FELHOM.local` does not resolve and the share never appears in the Finder sidebar. Likely the whole of symptom 1b. | nothing on udp/5353 (§ Phase A); container log daemon list; `infra/samba.go` header comment citing the R-6 spike | **S–M.** Add avahi-daemon (or `wsdd`'s mDNS sibling) to the felhom-samba image publishing `_smb._tcp`, host-net so multicast reaches the LAN. Re-runs the R-6 spike's constraint set — treat as a slice, not a hotfix. Confirm with the Mac matrix first (below) so we fix the mechanism that is actually failing. | yes — image change + republish |
|
||||
| **S-4** | **LOW** | Success-state semantics: the ensure job's phase never returns to `idle` after a terminal phase, and `SambaRunning()` masks that anyway. Harmless today only because S-1's fix removes the consumer that cared. Worth folding into the **unified async-job feedback** roadmap item the `samba_ensure_job.go` header already names. | `samba_ensure_job.go` (no reset path); handler line 246 | Fold into the roadmap item; no standalone task. | no |
|
||||
| **S-5** | **INFO** | The guest holds its LAN address by **DHCP** (`ip=dhcp`, lease ~54 min at probe). Any printed IP is not stable across a lease change or a site move, which weakens S-2 unless the page re-reads it live (it should — render it, never persist it). | `pct config 9201`; `valid_lft 3251sec` | Render live, never cache. Consider a DHCP reservation at the customer's router as a documented install step. | no |
|
||||
| **S-1** — **FIXED v0.151.0** | **HIGH** | `/sharing` reload-loops forever for every customer with sharing enabled — the page is unusable. `sharingStatusHandler` reports `running` as a level; the JS treats it as a one-shot success edge and calls `location.reload()`. | `sharing_handlers.go:246` (blame `b5d78d1`), `sharing.html` L320–326, 6× identical `phase:"running"` poll | **XS.** Make the JS reload only when it has *observed a transition* — latch a `sawInFlight` flag on the first tick and reload on `running` only if it is set; otherwise just paint the success alert and stop. Server-side alternative (also XS): report the coerced level as a distinct phase (`running_steady`) the JS renders but never reloads on. Prefer the JS latch — it keeps the honest "liveness wins" contract the handler comment states. **Needs a red-proof:** a template/JS test or handler test asserting a fresh page load with a live container does not schedule a reload. | no — plain bug fix |
|
||||
| **S-2** — **SHIPPED v0.151.0** | **MED** | The UI never tells the customer *where* to connect. `sharing.html` L32/L61 show only `\\FELHOM`; there is no IP anywhere on the page, so a customer who cannot resolve the name has nothing to fall back on and will guess (Viktor guessed the Proxmox host IP). | `sharing.html` L30–32, L61; symptom 1 itself | **S.** Render the guest's current LAN address beside the name: `\\FELHOM` *(vagy `smb://192.168.0.104`)*, sourced from the same place the dashboard already knows the guest IP. Add a one-line macOS hint (Finder → Ugrás → Csatlakozás a szerverhez). | no |
|
||||
| **S-3** — **OPEN** | **MED** | No mDNS/Bonjour advertisement. `smbd + nmbd + wsdd` covers Windows (WSD) and legacy NetBIOS, but macOS Finder's preferred path is Bonjour — `FELHOM.local` does not resolve and the share never appears in the Finder sidebar. Likely the whole of symptom 1b. | nothing on udp/5353 (§ Phase A); container log daemon list; `infra/samba.go` header comment citing the R-6 spike | **S–M.** Add avahi-daemon (or `wsdd`'s mDNS sibling) to the felhom-samba image publishing `_smb._tcp`, host-net so multicast reaches the LAN. Re-runs the R-6 spike's constraint set — treat as a slice, not a hotfix. Confirm with the Mac matrix first (below) so we fix the mechanism that is actually failing. | yes — image change + republish |
|
||||
| **S-4** — **CORE SHIPPED v0.151.0** | **LOW** | Success-state semantics: the ensure job's phase never returns to `idle` after a terminal phase, and `SambaRunning()` masks that anyway. Harmless today only because S-1's fix removes the consumer that cared. Worth folding into the **unified async-job feedback** roadmap item the `samba_ensure_job.go` header already names. | `samba_ensure_job.go` (no reset path); handler line 246 | Fold into the roadmap item; no standalone task. | no |
|
||||
| **S-5** — **SHIPPED v0.151.0** | **INFO** | The guest holds its LAN address by **DHCP** (`ip=dhcp`, lease ~54 min at probe). Any printed IP is not stable across a lease change or a site move, which weakens S-2 unless the page re-reads it live (it should — render it, never persist it). | `pct config 9201`; `valid_lft 3251sec` | Render live, never cache. Consider a DHCP reservation at the customer's router as a documented install step. | no |
|
||||
|
||||
**Recommended packaging:** S-1 alone as an immediate patch task (it bricks a shipped page). S-2 with
|
||||
it if the guest IP is already available to the sharing handler — same page, same release. S-3 as its
|
||||
@@ -265,3 +265,35 @@ for the `/sharing/status` polls, which mutates nothing.
|
||||
is off the DooPlex segment — a handy check for the rest of the trip.
|
||||
* No secrets appear in this document: the household SMB password and the controller login password
|
||||
are stored out-of-band.
|
||||
|
||||
---
|
||||
|
||||
## Addendum — 2026-07-20, controller v0.151.0 (S-1, S-2, S-4-core, S-5 closed)
|
||||
|
||||
Shipped and live on demo guest 9201 the same day this diagnosis was written. Controller commit
|
||||
`badf17b`, image `gitea.dooplex.hu/admin/felhom-controller:0.151.0`, `Up (healthy)`.
|
||||
|
||||
| # | Status | What changed |
|
||||
|---|---|---|
|
||||
| **S-1** | **FIXED v0.151.0** | The `idle`->`running` coercion is gone from `sharingStatusHandler`. The duty it was written for — "liveness must never be contradicted by a missing job" — was always discharged by the `running` LEVEL field beside it, and is now pinned by its own named regression test instead of by a phase-channel side effect. `sharing.html`'s `<script>` block is **byte-identical** to v0.150.0: the client contract was proven fixed server-side, not papered over. |
|
||||
| **S-2** | **SHIPPED v0.151.0** | New „Csatlakozás a megosztáshoz" card: the Windows form, the Mac form, and the direct `smb://<IP>` fallback. Rendered only while sharing is enabled; the address line is absent whenever no address can be derived. |
|
||||
| **S-4** | **CORE SHIPPED v0.151.0** | `consumeIfRunning` serves a terminal `running` exactly once, so a REAL bring-up cannot re-arm the reload on the page it just caused — without it the loop returns after every future image update. `failed`, `needs_password` and in-flight phases are never consumed. **The unified async-job feedback layer stays the roadmap item (R-45)**; this is the minimal contract fix, not the framework. |
|
||||
| **S-5** | **SHIPPED v0.151.0** | The address is derived per render from the samba container's netns and stored nowhere — no settings key, no memo, no package-level cache. Deriving it *through the samba container* also avoids the trap that made the card necessary: the controller is on a docker bridge, so `net.InterfaceAddrs()` would answer `172.x`. |
|
||||
| **S-3** | **OPEN** | Unchanged — still no mDNS/Bonjour advertisement, and still awaiting the two Mac-side probes from the matrix above (`smbutil lookup FELHOM`, `dns-sd -B _smb._tcp`) before an image change is justified. Deliberately out of scope for v0.151.0. |
|
||||
|
||||
### Live validation (endpoint-level — the exact endpoints the UI invokes; no browser on DooPlex)
|
||||
|
||||
```
|
||||
GET /sharing/status x3 -> {"data":{"error":"","phase":"idle","running":true},"ok":true} (all three)
|
||||
was {"phase":"running","running":true} on every call before the fix
|
||||
GET /sharing -> connect card present; smb://FELHOM and smb://192.168.0.104
|
||||
(192.168.0.104 = the guest's real DHCP lease, derived, not a literal)
|
||||
```
|
||||
|
||||
The `phase:"idle"` triple is the server-side proof that the loop's trigger is gone: the client's
|
||||
reload path is reachable only from `phase === "running"`. The human confirmation that the page sits
|
||||
still is Viktor's to give — a browser is the one method not available here.
|
||||
|
||||
**Tests:** 23/23 packages green (twice). Three red-proofs recorded — reinstating the coercion,
|
||||
deleting the serve-once clear, and memoizing the derived address each turned the corresponding test
|
||||
red, then were restored.
|
||||
|
||||
Reference in New Issue
Block a user