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.
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.
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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
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-onceprocess(node <step>/index.js). The step keeps its restart-on and carries its words, ports included, in the process'senv. This relies on mesh-controller #250 and mesh-host #85, so no env-file is needed. The Dockerfile,build.onmesh-tools and thebrokerown-secret are removed, andmesh-stateis 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.sonarr-downloadsradarr-downloadslidarr-downloadsbookshelf-downloadsbazarr-servarrombi-connectionstautulli-plexOne 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 takesMESH_PLEX_CONFIG_DIR(${dir:config}) and keeps the old word for a hand run.Validation
@novox/mesh-sdk@0.1.6and esbuilt with the builder's flags. All twelve bundle cleanly with noexternal.initializeandtools/listwith their tools. Some throw at import when unconfigured (bazarr, nzbget, qbittorrent, plex), exactly as their containers crash-looped.MESH_CATALOGUEpointing here.${…}is left except${secret:…}, and every word and step env is filled.Needs live proof (ace)
${dir:config}statesowner: 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.*.download.completedhandler acts.Nothing live was touched. Not merged.