Twelve media modules' code moves into bundles the node's runtime serves (hq ADR 0198, to-be 38 WP4c) #13

Merged
mesh-admin merged 12 commits from feat/0198-waves-2-3-module-code-moves into main 2026-10-03 23:01:19 +00:00
Contributor

Wave 3 of hq to-be 38 WP4c for the media catalogue, under ADR 0198, 0188, 0192 and 0193. There is one commit per module, and the branch is from main.

Each module's runtime container leaves. Its code becomes one TypeScript bundle named code, whose loads the node's runtime (node-tools) launches. Each run-once step container becomes a run-once process (node <step>/index.js). The step keeps its restart-on and carries its words, ports included, in the process's env. This relies on mesh-controller #250 and mesh-host #85, so no env-file is needed. The Dockerfile, build.on mesh-tools and the broker own-secret are removed, and mesh-state is removed where nothing else names it. Mount targets are folded back to host paths. A step's file directory (/run/downloads, /run/connections, /run/servarr, /run/plex) becomes ${dir:state}, where the mesh writes those exact files.

Module Runtime loads Step
plex handlers, tools
jackett tools
kometa tools
nzbget handlers, tools
qbittorrent handlers, tools
sonarr handlers, tools sonarr-downloads
radarr handlers, tools radarr-downloads
lidarr handlers, tools lidarr-downloads
bookshelf handlers, tools bookshelf-downloads
bazarr handlers, tools bazarr-servarr
ombi handlers, tools ombi-connections
tautulli handlers, tools tautulli-plex

One code change, in plex. The token is read from Preferences.xml under a data directory that was only the container's layout (/var/lib/plex + config/). A manifest cannot name a placed directory's parent, so the client now takes MESH_PLEX_CONFIG_DIR (${dir:config}) and keeps the old word for a hand run.

Validation

  • Builder-style build. Every module was compiled with tsc against @novox/mesh-sdk@0.1.6 and esbuilt with the builder's flags. All twelve bundle cleanly with no external.
  • Every load launched like node-tools does. All answer initialize and tools/list with their tools. Some throw at import when unconfigured (bazarr, nzbget, qbittorrent, plex), exactly as their containers crash-looped.
  • Steps run locally. Each step exits non-zero, or waits, when its app is not up, as before.
  • Module tests. sonarr, radarr, lidarr and bookshelf 15/15 each; bazarr 8/8; ombi 21/21; tautulli 11/11.
  • Controller catalogue checks. mesh-controller's catalogue tests pass with MESH_CATALOGUE pointing here.
  • Throwaway declaration test (deleted after use). Every module composes beside the node's runtime. Only its third-party server container remains. No ${…} is left except ${secret:…}, and every word and step env is filled.

Needs live proof (ace)

  • Config directories. Each app's ${dir:config} states owner: 1000:1000, mode 0700 (plex 0755). The runtime runs as the operator account, so the tools and handlers that read config.xml or config.ini there need that account to be uid 1000.
  • Steps. Each step runs as root, as its container did, and must run on apply and again on a binding change.
  • Events. grabs, completions and requests are emitted through the runtime, and plex's *.download.completed handler acts.

Nothing live was touched. Not merged.

Wave 3 of hq to-be 38 WP4c for the media catalogue, under ADR 0198, 0188, 0192 and 0193. There is one commit per module, and the branch is from main. Each module's runtime container leaves. Its code becomes one TypeScript bundle named `code`, whose loads the node's runtime (node-tools) launches. Each run-once step container becomes a run-once `process` (`node <step>/index.js`). The step keeps its restart-on and carries its words, ports included, in the process's `env`. This relies on mesh-controller #250 and mesh-host #85, so no env-file is needed. The Dockerfile, `build.on` mesh-tools and the `broker` own-secret are removed, and `mesh-state` is removed where nothing else names it. Mount targets are folded back to host paths. A step's file directory (`/run/downloads`, `/run/connections`, `/run/servarr`, `/run/plex`) becomes `${dir:state}`, where the mesh writes those exact files. | Module | Runtime loads | Step | |---|---|---| | plex | handlers, tools | | | jackett | tools | | | kometa | tools | | | nzbget | handlers, tools | | | qbittorrent | handlers, tools | | | sonarr | handlers, tools | `sonarr-downloads` | | radarr | handlers, tools | `radarr-downloads` | | lidarr | handlers, tools | `lidarr-downloads` | | bookshelf | handlers, tools | `bookshelf-downloads` | | bazarr | handlers, tools | `bazarr-servarr` | | ombi | handlers, tools | `ombi-connections` | | tautulli | handlers, tools | `tautulli-plex` | **One code change, in plex.** The token is read from Preferences.xml under a data directory that was only the container's layout (`/var/lib/plex` + `config/`). A manifest cannot name a placed directory's parent, so the client now takes `MESH_PLEX_CONFIG_DIR` (`${dir:config}`) and keeps the old word for a hand run. ## Validation - **Builder-style build.** Every module was compiled with tsc against `@novox/mesh-sdk@0.1.6` and esbuilt with the builder's flags. All twelve bundle cleanly with no `external`. - **Every load launched like node-tools does.** All answer `initialize` and `tools/list` with their tools. Some throw at import when unconfigured (bazarr, nzbget, qbittorrent, plex), exactly as their containers crash-looped. - **Steps run locally.** Each step exits non-zero, or waits, when its app is not up, as before. - **Module tests.** sonarr, radarr, lidarr and bookshelf 15/15 each; bazarr 8/8; ombi 21/21; tautulli 11/11. - **Controller catalogue checks.** mesh-controller's catalogue tests pass with `MESH_CATALOGUE` pointing here. - **Throwaway declaration test** (deleted after use). Every module composes beside the node's runtime. Only its third-party server container remains. No `${…}` is left except `${secret:…}`, and every word and step env is filled. ## Needs live proof (ace) - **Config directories.** Each app's `${dir:config}` states `owner: 1000:1000`, mode 0700 (plex 0755). The runtime runs as the operator account, so the tools and handlers that read config.xml or config.ini there need that account to be uid 1000. - **Steps.** Each step runs as root, as its container did, and must run on apply and again on a binding change. - **Events.** grabs, completions and requests are emitted through the runtime, and plex's `*.download.completed` handler acts. Nothing live was touched. Not merged.
mesh-admin added 12 commits 2026-10-03 22:51:14 +00:00
The mesh-plex container goes with its Dockerfile, build bases, bus credential and state directory. The token is still read from the server's own Preferences.xml, now under the config directory where the mesh places it: the code looked for it beneath a data directory that was only the container's layout, and a manifest cannot name a placed directory's parent, so the client takes the config directory itself (MESH_PLEX_CONFIG_DIR), keeping the old word for a hand run.
The mesh-jackett container goes with its Dockerfile, build bases and bus credential; its env becomes the bundle's words with mount targets folded back to host paths.
The mesh-kometa container goes with its Dockerfile, build bases and bus credential; its env becomes the bundle's words with mount targets folded back to host paths.
The mesh-nzbget container goes with its Dockerfile, build bases and bus credential; its env becomes the bundle's words with mount targets folded back to host paths.
The mesh-qbittorrent container goes with its Dockerfile, build bases and bus credential; its env becomes the bundle's words with mount targets folded back to host paths.
The mesh-sonarr container and the mesh-sonarr-downloads step container go with the Dockerfile, build bases and bus credential. The step runs node on the bundle with its words in the process's env, the bound clients' files, the app's config.xml and its memory read where the mesh writes them; it still runs again when a binding it reads changes.
The mesh-radarr container and the mesh-radarr-downloads step container go with the Dockerfile, build bases and bus credential. The step runs node on the bundle with its words in the process's env, the bound clients' files, the app's config.xml and its memory read where the mesh writes them; it still runs again when a binding it reads changes.
The mesh-lidarr container and the mesh-lidarr-downloads step container go with the Dockerfile, build bases and bus credential. The step runs node on the bundle with its words in the process's env, the bound clients' files, the app's config.xml and its memory read where the mesh writes them; it still runs again when a binding it reads changes.
The mesh-bookshelf container and the mesh-bookshelf-downloads step container go with the Dockerfile, build bases and bus credential. The step runs node on the bundle with its words in the process's env, the bound clients' files, the app's config.xml and its memory read where the mesh writes them; it still runs again when a binding it reads changes.
The mesh-bazarr container and the mesh-bazarr-servarr step container go with the Dockerfile, build bases, bus credential and state directory. The step runs node on the bundle and reads the sonarr and radarr bindings where the mesh writes them; it still runs again when one changes.
The mesh-ombi container and the mesh-ombi-connections step container go with the Dockerfile, build bases and bus credential. The step runs node on the bundle and reads the servarr and plex bindings and the API key where the mesh writes them; it still runs again when one changes.
The mesh-tautulli container and the mesh-tautulli-plex step container go with the Dockerfile, build bases and bus credential. The step runs node on the bundle and reads the plex binding where the mesh writes it; it still runs again when the server or the binding changes.
mesh-admin merged commit e94c3ac1a1 into main 2026-10-03 23:01:19 +00:00
mesh-admin deleted branch feat/0198-waves-2-3-module-code-moves 2026-10-03 23:01:19 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/mesh-media-catalog#13