Tautulli reached plex at 172.18.0.1, the gateway of a HAL network that goes away with HAL, and the plan was to retype it by hand in the window. Tautulli now requires plex-api, and where plex is comes from the binding. Tautulli keeps the connection only in config.ini, reads it at start and writes its whole config back on every shutdown; its API cannot set it and its settings form needs an admin login. So a step after start would be overwritten the moment the container is recreated. The write is made where nothing can overwrite it: the linuxserver image's custom-init runs plex/mesh-plex.py as root before Tautulli starts, and the server restarts on its binding and credential, so a moved plex or an accepted token lands. It writes only [PMS] keys, only when they differ, every other line byte for byte: pms_ip, pms_port, pms_ssl and pms_url from the binding; pms_identifier from plex's /identity; pms_token only when plex takes it. A minted value - before the operator accepts the server's X-Plex-Token for this pair - is never written, while the address still is, so Tautulli's own working token keeps working at plex's new address. A failure in custom-init is a log line nobody reads, so a run-once `plex` step, declared last so it gates nothing (ADR 0136), checks what the mesh can report: plex takes the credential (else it names the secret accept), Tautulli holds the bound URL, and Tautulli says it is connected. It writes nothing. The script is kept as plex/mesh-plex.py and plex/50-mesh-plex; module.json carries copies, and a test fails when they differ. Tests run the script with python3 against a fake plex (skipped where there is none) and the step against fakes; `npm test` builds first.
28 lines
1.5 KiB
Docker
28 lines
1.5 KiB
Docker
# tautulli's runtime: the tool runtime, carrying this module's compiled code.
|
|
#
|
|
# **Built from this module's own directory and nothing else.** The sdk and the tool runtime are in
|
|
# the base images, published like any other artifact — which is what makes this buildable by the
|
|
# mesh from a repository and a path (novox/hq ADR 0069) rather than only on a workstation that
|
|
# happens to have the siblings.
|
|
#
|
|
# Two bases, named rather than pinned (novox/hq issue 044): the image this is COMPILED in and the
|
|
# image it RUNS in — the second must not carry a compiler. Declared in module.json's `build.on`.
|
|
ARG BUILD_BASE
|
|
ARG RUNTIME_BASE
|
|
|
|
FROM ${BUILD_BASE} AS build
|
|
WORKDIR /app/modules/tautulli
|
|
COPY . .
|
|
RUN node /app/node_modules/typescript/bin/tsc client.ts index.ts tools/index.ts plex/check.ts plex/index.ts \
|
|
--module NodeNext --moduleResolution NodeNext --target ES2022 --outDir dist
|
|
|
|
FROM ${RUNTIME_BASE}
|
|
COPY --from=build /app/modules/tautulli/dist /app/modules/tautulli/dist
|
|
# Every serve-time entrypoint, loaded by the runtime in serve mode: tools and events serve, and a
|
|
# provider's provisioner runs its reconcile loop in the same process, with the broker connected —
|
|
# the convention novox/hq issues 060/061 settled.
|
|
ENV MESH_TOOL_MODULES=/app/modules/tautulli/dist/index.js,/app/modules/tautulli/dist/tools/index.js
|
|
# NOT dist/plex/index.js: that is a step the host runs to completion, named by the `plex`
|
|
# container's args as `mesh-tools run …` (novox/hq ADR 0052). Listed here it would run inside the
|
|
# serving sidecar too, and exit it.
|