nzbget: placed config, the build ace runs, its password a file, its API provided
The manifest named /services/nzbget/config and /var/lib/mesh/nzbget/config.json,
host paths ADR 0112 takes out of definitions. The config dir is now pathless
(${dir:config}); the runtime's config and route binding live in a placed state dir.
The image is pinned to v26.0-ls233, the digest ace runs. The old pin (v26.3-ls261)
is newer but unproven against ace's queue; moving up is a later, separate step.
The password own-secret reached the tools and nothing else, so a fresh machine ran
nzbget's well-known default while the tools held a minted value that matched
nothing. The server now reads it too, through the image's FILE__NZBGET_PASS (a
path in the environment, the value from a 0600 root file - ADR 0086), and both
restart on it. An adopted machine accepts its existing ControlPassword.
The tools assumed the control user is "nzbget"; they now read ControlUsername
from nzbget.conf on the read-only config mount (ace's is not "nzbget").
sonarr, radarr, lidarr and bookshelf reached nzbget by container name on HAL's
shared network. nzbget now provides nzbget-api (node scope: a download client
must share the consumer's download spool) and serves scheme, port, url-base and
username; the password is the operator-accepted pair credential, as for #156.
The web endpoint is routed (label nzbget). The runtime dials ${port:6789}, the
same line as #154.
Verified: catalogue tests with MESH_CATALOGUE set (not skipped); rendered for ace
with a pinned port and username setting; a throwaway of the pinned image on a
fresh 0700 dir with the secret as a 0600 root file answered the secret (200),
refused a wrong and the default password (401); the compiled client read the
username from nzbget.conf and reached version/status/queue/history; strict
typecheck and the module's Dockerfile build pass.
This commit is contained in:
@@ -48,6 +48,20 @@ function meshConfig(file?: string): Record<string, string> {
|
||||
catch { return {}; }
|
||||
}
|
||||
|
||||
/** One key of nzbget's own nzbget.conf, from the config directory the mesh mounts read-only
|
||||
* (MESH_NZBGET_CONFIG_DIR). The software's file is the truth about who may log in, so the tools
|
||||
* ask it rather than a setting that could disagree. Absent, unreadable or unset yields undefined. */
|
||||
function confValue(dir: string | undefined, key: string): string | undefined {
|
||||
if (!dir) return undefined;
|
||||
try {
|
||||
const line = readFileSync(`${dir.replace(/\/$/, "")}/nzbget.conf`, "utf8")
|
||||
.split("\n")
|
||||
.find((l) => l.startsWith(`${key}=`));
|
||||
const value = line?.slice(key.length + 1).trim();
|
||||
return value ? value : undefined;
|
||||
} catch { return undefined; }
|
||||
}
|
||||
|
||||
/** Read a secret the mesh mounted at a file path (an own-secret delivered by `secret accept`);
|
||||
* absent or unreadable yields undefined so callers fall back rather than crash. */
|
||||
function readSecret(file?: string): string | undefined {
|
||||
@@ -69,7 +83,9 @@ export class NzbgetClient {
|
||||
* Build from the module's resolved environment. URL and password are read from MESH_NZBGET_URL
|
||||
* and MESH_NZBGET_PASSWORD; both must be present — an unconfigured NZBGet throws rather than
|
||||
* pretend to be reachable, so the tools/events simply do not load (the harness treats the throw
|
||||
* as "exposes nothing"). The control username defaults to "nzbget", NZBGet's own default.
|
||||
* as "exposes nothing"). The password file is the same own-secret the server container is started
|
||||
* with (FILE__NZBGET_PASS), so the two cannot disagree. The control username is read from
|
||||
* nzbget.conf, falling back to "nzbget", NZBGet's own default.
|
||||
*/
|
||||
static fromEnv(env: NodeJS.ProcessEnv = process.env): NzbgetClient {
|
||||
const cfg = meshConfig(env.MESH_NZBGET_CONFIG_FILE);
|
||||
@@ -78,7 +94,9 @@ export class NzbgetClient {
|
||||
if (!url || !password) {
|
||||
throw new Error("NZBGet not configured — set MESH_NZBGET_URL and MESH_NZBGET_PASSWORD");
|
||||
}
|
||||
const user = cfg.user ?? env.MESH_NZBGET_USER ?? "nzbget";
|
||||
// The control username: a setting or the environment if one says so, else whatever
|
||||
// nzbget.conf holds (an adopted machine keeps its own, e.g. not "nzbget"), else NZBGet's default.
|
||||
const user = cfg.user ?? env.MESH_NZBGET_USER ?? confValue(env.MESH_NZBGET_CONFIG_DIR, "ControlUsername") ?? "nzbget";
|
||||
return new NzbgetClient(url, user, password);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user