// tautulli's plex step — run once by the host after Tautulli's server container, and again whenever // its binding, its pair credential or the server changed (the container's `restart-on`, novox/hq // ADR 0099). It checks; it writes nothing (plex/check.ts says why, and where the write is). // // Exits non-zero when Tautulli does not reach plex as the mesh says, so the node reports the step // failed. Declared last in the manifest, so its failing gates nothing else of tautulli's (novox/hq // ADR 0136). Never prints a key or a token. import { readFile } from "node:fs/promises"; import { join } from "node:path"; import { keyOfTautulli } from "../client.js"; import { check, tautulliReady, PROVISION, type Binding, type Http } from "./check.js"; const dir = process.env.MESH_PLEX_DIR ?? "/run/plex"; const url = process.env.MESH_TAUTULLI_URL ?? "http://127.0.0.1:8181"; const waitSeconds = Number(process.env.MESH_TAUTULLI_WAIT_SECONDS ?? "180"); const http: Http = { fetch: (u, init) => fetch(u, init) }; const read = (path: string) => readFile(path, "utf8").catch(() => undefined); const apiKey = keyOfTautulli(process.env.MESH_TAUTULLI_CONFIG_DIR); if (!apiKey) { console.error("[tautulli-plex] Tautulli's config.ini holds no API key yet — it writes one on its first start"); process.exit(1); } const tautulli = { url, apiKey }; if (!(await tautulliReady(http, tautulli, waitSeconds * 1000))) { console.error(`[tautulli-plex] Tautulli did not answer at ${url} within ${waitSeconds}s`); process.exit(1); } let binding: Binding | undefined; try { const raw = await read(join(dir, `${PROVISION}.json`)); binding = raw === undefined ? undefined : (JSON.parse(raw) as Binding); } catch { binding = undefined; } const outcome = await check(http, tautulli, binding, await read(join(dir, `${PROVISION}.secret`))); if (outcome.result === "connected") { console.log(`[tautulli-plex] Tautulli reaches plex at ${outcome.url} as the mesh says; connected`); } else { console.error(`[tautulli-plex] ${outcome.problem}`); process.exitCode = 1; }