summaryrefslogtreecommitdiffstats
path: root/packaging/rpm
Commit message (Collapse)AuthorAgeFilesLines
* feat(packaging): ship a node firewall profile for inbound WebRTCChristophe Besson2026-09-041-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | The packages carried a profile for LAN casting and none for the node's own peer traffic, on the reasoning that the node exposes only a loopback admin API. That is true of its administration surface and false of its transport. WebRTC binds an ephemeral UDP port per connection, so there is no fixed port to open, and a connection succeeds only if one side can initiate. Browsers publish their host candidate as an mDNS `<uuid>.local` name, which aioice cannot resolve on any platform and discards — so the node can never call a browser back, and the browser must call the node. A node that refuses unsolicited inbound UDP is unreachable from every browser on its own LAN, leaving reflexive candidates, which fail whenever both peers share one public IP and the router will not hairpin. Hit twice in one session on two different hosts: a firewalld zone narrowed to mdns + 19550-19553/tcp, and a ufw host with default deny-incoming. Both presented as "the app cannot connect", neither as a firewall message. Passive like the cast profile: packaged, not activated. The guide says to scope it to a LAN zone or source, including the libvirt case, where traffic from a guest to its own hypervisor is not masqueraded and so must be scoped to the guest subnet rather than the LAN. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtfG7z6wHWj8RKHCvxQtY1
* fix(packaging): ship the example hub config, and stop leaving /etc/meshbay openChristophe Besson2026-09-021-1/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Three defects, found while answering whether installing the .deb would land where the production server was just moved to by hand. - **The example config was never packaged.** `build-hub.sh` copied `packaging/conf/hub.toml.example` under `if [ -f ]`, and that path does not exist in this repo — so every package ever built shipped no example at all and said nothing about it. The postinst places no config either, on purpose (a shipped hub.toml is overwritten on upgrade; a shipped secret gets run in production), which left an installed hub with nothing to copy from. The file now exists, documents every key `config.py` reads including the captcha `allowed_hosts` the desktop client needs, and the copy is a hard failure rather than a silent skip. - **`/etc/meshbay` was created 0755.** It holds the hub's Ed25519 private key and its database password. The file modes protect the contents, but a world-listable config directory tells anyone with a shell what a hub keeps and where. Now 0750 root:meshbay, in both the deb postinst and the rpm scriptlet; the service reads it by group. - **The rpm would have failed to build on the new file.** `%files` claimed nothing under /etc, and rpmbuild refuses an installed file no line claims. It now declares the directory and the example, with explicit `%attr` and `%config` so an operator's edits become .rpmsave rather than vanishing. Package modes no longer follow the builder's umask either — the same source tree produced 775/664 on a machine with umask 002 and 755/644 with 022. `install -m` sets them. Verified by building: the deb now carries ./etc/meshbay/ at drwxr-x--- with hub.toml.example at 0644, and the embedded postinst tightens the directory as belt and braces rather than as the only thing making it right. The rpm path is unverified — no rpmbuild on this machine. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014UtzVrzM7e2tG9fSpkR9ML
* refactor(node): JSON-only control API, Node page absorbs the admin dashboardChristophe Besson2026-09-011-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Remove the node daemon's server-rendered admin UI (GET / and /audit, the _render_* helpers and inline templates) and the `meshbay-node ui` CLI verb. The loopback control API stays; it is now JSON only, ruff-clean, and 453 lines (was 1074). Also drop three never-wired endpoints (/api/config, /api/chat/history, /ws/chat, plus broadcast_chat) and the pointless 18000/tcp firewall profiles. The desktop client's Node page (static/node-page.js) takes over what the dashboard showed, reorganised into six tabs (Overview, Groups, Roster, Peers, Audit, Settings): - Overview: version, node id, QUIC port, hub, index-cache maintenance - Roster: node-wide view with unpin - Peers and Audit: auto-load on open, no Load button - Audit: real usernames and group names (resolved from the roster and node.toml), Previous/Next pagination newest-first, Export CSV of every matching row - Settings: node settings, STUN, ICE, denylist, then Unlink from hub Backend: audit.get_entries gains `offset`; /api/audit and /api/peers resolve ids to names via a new _display_names helper; CSP tightened to default-src 'none' now that no HTML is served. draft-v6 sections 2.11 and 2.12 corrected -- the Node page uses the loopback API, not MNP. One capability is intentionally dropped: browser-based admin on a headless server. The CLI covers every operation there. See docs/refactor-node-ui.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MQCaZnde4Bjjdu84dhSuF5
* feat(packaging): 4-package .deb/.rpm build system under /optChristophe Besson2026-08-315-216/+127
| | | | | | | | | | | | | | | | | | Shared venv architecture: meshbay-common owns the Python venv with all pip deps pre-installed; hub and node add only their code into it. Client is a standalone Electron app. No pip runs at install time. - Add build scripts (packaging/build/) for common, hub, node, client - Add orchestrator build-packages.sh with deb/rpm auto-detection - Add .deb control/postinst for all 4 packages - Add .rpm specs for all 4 packages (replaces python3-meshbay-common) - Add Gnome .desktop launcher and icon resizing - Add firewalld services (meshbay-cast, meshbay-node) and UFW profiles - Update systemd units to use /opt/meshbay-common/venv/bin/ paths - TMDB token baked into node package at build time via QE/node.env - Fix package-lock.json sync for protobufjs override Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: release 0.6.00.6Christophe Besson2026-08-233-3/+22
| | | | | | | | | | | | | The group UI's applications split, and the two missing-import bugs it surfaced and fixed along the way. MNP goes to 0.4: apps_enabled/apps_enabled_ack, and enabled_apps on the handshake ack, for the group-applications registry. Additive — a node that predates it is never sent the op, and a client that predates it never looks for the field. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016SF6RKNBKg9qejmoMJ9ybA
* feat(client): the platform seam, and an Electron shell that has never been runChristophe Besson2026-08-181-1/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Stage D, and the honest half of it. D1 — the seam (done, and verified) ---------------------------------- `static/platform.js`. `HUB` becomes `platform.hubBase()` and the transport is built with the same base, so one address has one source. In a browser it returns '' and every path stays relative to the origin that served the page — the acceptance criterion for this split was "the browser SPA behaves identically", and it does. `platform.js` joins `_ASSETS`, or a change to it would not move the content hash and a cached browser would never ask for it. D2 — the shell (written, never launched) ----------------------------------------- **There is no npm on this machine. Electron was never installed and `packages/meshbay-client/` has not been run once.** That is stated here rather than discovered later. What is there: a main process serving the packaged interface over a privileged `app://` scheme (`secure` and `standard` are not cosmetic — without them the service worker refuses to register and streamed downloads break silently), a preload exposing an enumerated bridge that never passes a filesystem path, a window with `sandbox`, `contextIsolation` and no node integration, navigation away from the package refused, and a CSP where the hub is reachable over connect-src and is not a script source. The hub address arrives as a process argument because `platform.hubBase()` runs before anything can await. `test_desktop_shell.py` pins each of those by reading the source — the treatment `test_downloads.py` already gives the three browser save paths. It catches a property being removed and proves nothing about the application running. Two were checked by breaking them. The interface is *copied* into the package by `build/sync-ui.js` from the hub's static directory, and `ui/` is gitignored: a silent fork is the only real way to end up maintaining the interface twice. D3 — partial ------------ The bridge, and the part worth having now: safeStorage's backend is reported rather than assumed. On Linux it falls back to a fixed key when no keyring is running, silently — someone who believes the OS is holding their keys is told when it is not. The native key lifecycle belongs with D4 and needs a running application to mean anything. D8 — partial, and a real defect found -------------------------------------- `meshbay-node.spec` installed the SYSTEM template — the one carrying `User=%i` — into `%{_userunitdir}`. A user unit already runs as its owner and cannot carry `User=`; systemd refuses the file, so the packaged unit could never have started. Nothing noticed because nobody had built and installed the RPM. Two units now: the template to `%{_unitdir}`, and a new `meshbay-node-user.service` that a person enables themselves without a password — which is what lets the desktop client install a node without asking for one. It carries ExecReload, so `meshbay-node reload` does not have to stop a service somebody is streaming from, and documents the drop-in for a drive outside the home, RequiresMountsFor included. 798 tests pass; e2e.py still passes end to end. Nothing here was built or launched: no npm, no rpmbuild. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* chore: release 0.5.0Christophe Besson2026-08-163-3/+22
| | | | | | | | | | | | | | | | | | | | | | | Two rounds of features and one long hunt. The hub gained leaving a group, a cap of ten live public groups per owner, and the rule that a group is listed only once a node has announced it — with `prune-groups` to collect the ones that never got one. Presence rides on the group list, from the registry the hub already keeps for signaling. The web client speaks ten languages, splits Profile from Settings, and reads chat the way it is written: newest first, paging backwards. The rest was one symptom — "close the viewer, the next video hangs" — with three independent causes underneath, none of which the test suite or e2e.py could see. A background task the loop only weakly referenced, collected while it held a transcode slot. A connection-state handler that forgot a peer without stopping it. And `await proc.wait()` deadlocking on ffmpeg's own unread output, which no amount of SIGKILL resolves. Found by instrumenting the node and reading the log, after two confident fixes that addressed real but different bugs. MNP goes to 0.2: PING/PONG and backward chat paging, both additive. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* chore: release 0.4.00.4Christophe Besson2026-08-163-3/+16
| | | | | | | | | | | | | | | | | | | | | | | | The web client speaks ten languages instead of one: French, Spanish, Brazilian Portuguese, Simplified Chinese, Japanese, German, Italian, Dutch and Polish, all formal, with `hub`, `node` and `GEK` deliberately left in English so the interface still matches the CLI and the docs. Catalogues are fetched per language rather than shipped together, plural forms go through Intl.PluralRules because Polish needs four of them, and locale matching keeps the region so pt-BR and zh-CN resolve to the files written for them. Splitting one module into a loader and ten catalogues gave the SPA a version dependency it did not have before, and the hub was serving static assets with no explicit freshness at all. A browser that cached half a deploy either rendered every string as its own key or, in the other direction, failed to link the module graph and showed nothing. Static responses now carry no-cache, which costs one conditional request and answers 304 with no body. The node and common packages carry no functional change; they move with the version because the three are released together. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* chore: release 0.3.00.3Christophe Besson2026-08-153-3/+19
| | | | | | | | | | | | | | | | | | | | | | | Twenty-one commits since 0.2, and enough of them change what the thing does that moving the old tag would have been the wrong description. Node: video streaming paced by the client rather than pushed at it, and a stream that ends when the viewer closes instead of holding a transcode slot for two minutes. An operator can remove an empty directory and revoke a member over MNP. `meshbay-node group add` attaches another hub group without hand-editing node.toml. The node.toml operator key is gone; the roster is the only source of authority. Hub and web client: transfers outlive the page that started them, with a widget that shows the rate and can cancel them; downloads stream to disk in every browser, through the File System Access API where it exists and a service worker where it does not; a folder can be taken as a zip built in the browser. A group owner can remove a member and edit the description. Nodes are recorded at the address their signed announcement arrived from, not the one STUN told them about. Deleted accounts stop being counted while the connection log keeps their name. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* chore: release 0.2.00.2Christophe Besson2026-08-143-3/+19
| | | | | | | | | | | | All three packages together, as the conventions require, plus the RPM and DEB metadata and their changelogs. The tag said 0.2 while every package announced 0.1.0, which would have shipped an RPM claiming to be the reviewed build while containing a different protocol: the hub schema lost the user identity keys, tokens lost pk_user, and gek_bundle_store left the wire. Pre-1.0, a breaking change bumps MINOR. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* chore: add RPM/DEB packaging artifacts — 5.10Christophe Besson2026-08-093-0/+177
3 packages: python3-meshbay-common (dep), meshbay-hub, meshbay-node. RPM: spec files with pre/post scriptlets (useradd, systemd macros). DEB: DEBIAN/control + postinst for hub, control for node + common. Systemd: hub.service (system, security hardening) + node.service (user template @%i, EnvironmentFile for MESHBAY_UNLOCK_KEY). packaging/README.md: build + install instructions. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>