lidarr: placed dirs, the operator's custom scripts carried, the image ace runs #164
Closed
mesh-admin
wants to merge 7 commits from
feat/lidarr-for-ace into main
pull from: feat/lidarr-for-ace
merge into: :main
:main
:fix/resolver-passes-the-dnssec-bit
:fix/mailu-admin-asks-the-machines-resolver
:fix/110-the-resolver-answers-a-container
:feat/qbittorrent-for-ace
:feat/servarr-api-provision
:feat/home-assistant-for-ace
:feat/tautulli-for-ace
:feat/bookshelf-for-ace
:feat/lidarr-for-ace
:feat/radarr-for-ace
:feat/sonarr-for-ace
:feat/kometa-for-ace
:feat/plex-for-ace
:fix/manifests-publish-software-ports
:feat/nzbget-for-ace
:feat/bazarr-for-ace
:fix/sidecars-dial-the-port-they-were-given
:feat/ombi-for-ace
:chore/remove-the-network-checker-module
:feat/a-network-checker-module
:feat/modules-name-their-endpoints
:fix/a-routed-module-listens-from-the-mesh
:fix/the-resolver-declares-both-protocols
:fix/sshd-declares-the-daemon-it-owns
:fix/fail2ban-bans-through-what-every-machine-has
:fix/fail2ban-declares-the-log-its-own-jail-reads
:fix/fail2ban-restarts-on-its-log-target
:fix/fail2ban-declares-where-it-logs
:feat/the-catalogue-hears-what-it-missed
:feat/the-catalogue-prepares-its-own-schema
:fix/the-catalogue-declares-the-event-it-emits
:feat/a-merge-rebuilds-what-it-changed
:fix/a-merge-older-than-the-watching-is-history
:fix/a-merge-announced-is-said
:fix/the-forge-watches-every-repository
:feat/the-forge-announces-every-merge
:feat/nats-serves-the-meshs-certificate
:fix/nats-declares-its-base
:feat/amqp-leaves-the-catalogue
:restore/broker-claim
:revert/broker-seat-claim
:fix/broker-seat-must-stay-held
:fix/go-126-base
:feat/nats-genesis
:feat/ssh-client-module
7
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
e1febc053f |
lidarr: reach nzbget, qbittorrent and jackett through the mesh
lidarr reached its download clients as nzbget:6789 and qbittorrent:8112 and its indexers through jackett:9117 or indexers.zurag.be - HAL container names and a public route, typed into its database by hand. Nothing on the mesh answers those names. It now requires nzbget-api, qbittorrent-api and jackett-api. A run-once step (downloads/, declared last, restart-on its bindings, credentials and settings) writes host, port, TLS, base path, user and credential into lidarr through lidarr's own API: - A download client is the mesh's when its name is downloads.<provision>.name and its kind the provider's; it is registered when missing. A jackett feed is the mesh's when its host is the bound one, one the step bound before, or one in downloads.jackett-api.adopt-hosts; the jackett indexers in downloads.jackett-api.indexers are registered when missing. Every other entry is left alone, and nothing is ever deleted. - Only connection fields, only when they differ. The stored password is masked, so the app tests the entry with the credential it holds; only if that fails is the delivered one written. Categories, priorities and "enabled" are never touched. - Each credential is tried against its provider first. A minted value (nothing accepted yet) is never written; the step exits 1 naming the exact secret accept. The step is byte-identical in sonarr, radarr, lidarr and bookshelf (the same Servarr API, v3 or v1): each module builds from its own directory, so each carries a copy, and test/downloads.test.ts fails if a sibling's copy differs. Verified: strict typecheck, the Dockerfile build, 14 unit tests; and the compiled step against fresh pinned sonarr/radarr/lidarr/bookshelf with throwaway nzbget, qBittorrent and jackett - minted credentials refused with nothing written, accepted ones registered and tested by the app, a migration-shaped radarr repointed, reruns unchanged. |
||
|
|
cd5688ac3f |
lidarr: its dirs are placed, its custom scripts are carried, its image is the one ace runs
ace's lidarr is not a plain lidarr. HAL mounts custom-cont-init.d and
custom-services.d, and the operator's arr-scripts run from them: an init
script installs beets/deemix/SMA on every start, and eight services
(Audio, AutoConfig, QueueCleaner, ARLChecker, ...) run beside lidarr and
are working today. The catalogue mounted neither, so a take would have
silently stopped all of it. Both are now pathless directories mounted at
the linuxserver image's own paths, root-owned 0755 as the image expects;
empty on a new machine, which the image skips.
The config dir is a pathless ${dir:config} instead of /services/lidarr/config,
the route binding lives in a placed state dir, and /var/lib/mesh/lidarr
keeps only the broker secret.
The image is pinned to the digest ace runs (3.1.0.4875-ls41, sha256:8ab0fd...).
The previous pin was ls40 - older than the data it would open.
Based on feat/servarr-api-provision (#156), which makes lidarr provide
lidarr-api; this branch contains it.
Verified: mesh-controller catalogue tests with MESH_CATALOGUE pointed here
pass (parse + mounts, not skipped); a resolve of route-adapter+lidarr on a
fake ace renders every ${dir:} and ${port:}; the pinned image in a
throwaway container ran a root-owned custom-cont-init.d script and started
a custom-services.d service, answered /ping, the UI and /api/v1/system/status
(200 with its key, 401 without), and re-owned a 1001:2000 file in /config to
PUID. With PUID 1000 it cannot write a 1001:2000 0775 library - the reason
ace needs hq 153 before a take.
|
||
|
|
f14c763463 |
ombi: reach sonarr, radarr and lidarr through the mesh
ombi keeps its Servarr connections in its own database, so the mesh has no file to write them into. A run-once step reads the three bindings and pair credentials and writes host, port, TLS, base path and key into ombi through ombi's own API - only when they differ, and nothing else ombi keeps. Until the operator accepts an app's key for this pair the mesh delivers a value it minted, which no Servarr app accepts. The step tries the key against the app first and, refused, writes nothing and fails naming the secret accept that fixes it, so the old working key in ombi is never replaced by a dead one. Declared last so its failing gates nothing else of ombi (ADR 0136), and restart-on its six inputs so it runs again when a provider moves (ADR 0099). |
||
|
|
ab44ff02e1 |
sonarr, radarr, lidarr: provide their API to the mesh
A consumer on another machine (ombi first; jackett, bazarr and home-assistant later) reached these by container name on HAL's shared network, which the mesh does not have. Each app now provides <app>-api at mesh scope and serves the software port, so the mesh tells a consumer where it is and redirects the port to where the machine published it. Named per app, not one servarr-api: a requirement is matched by name and answered by exactly one provider per node, so a consumer cannot require one name from three providers - and ombi's code is written against each app's own API version (ADR 0027). No grants and no provisioner: a Servarr instance has one API key, which the mesh cannot mint. The operator accepts it as the pair credential for each consumer (ADR 0092). |
||
|
|
c4c44efb1b | Merge remote-tracking branch 'origin/fix/sidecars-dial-the-port-they-were-given' into feat/servarr-api-provision | ||
|
|
5cc6258326 |
Sidecars dial the port they were given, not the software's
A host-network sidecar reaches its service over the machine's loopback, and
the mesh publishes that service on a machine port it assigns (ADR 0038) —
so dialling the software's port reaches whatever else holds it. On ace,
searxng's sidecar dialled 127.0.0.1:8080 and got unifi's inform port. The
same shape in bazarr, bookshelf, lidarr, nzbget, qbittorrent, radarr and
sonarr; each now asks with ${port:N} (hq 088). Found in review of ace's
module preparation.
|
||
|
|
21f5301268 |
ombi: its config is placed, its image is the one ace runs
ombi's definition named /services/ombi/config (a HAL machine path) in three
places and pinned an image older than the one ace runs. Ombi migrates its
own SQLite schema, so a take onto the older pin (v4.53.10-ls267) would start
it on a database the newer build (ls269) already touched.
- config is a pathless placed directory, mounted as ${dir:config}
- a state directory placed at the assignment root carries route.json
- image pinned to the digest ace runs today (v4.53.10-ls269)
- the sidecar reaches ombi on the machine port the mesh assigns
(${port:3579}) rather than assuming 3579 is free
- the sidecar no longer mounts ombi's data directory: MESH_OMBI_CONFIG_DIR
is read by no code, and the mount exposed the databases for nothing
Verified: catalogue tests (MESH_CATALOGUE set, 6 pass, none skipped); the
pinned image starts as PUID 1000 in a 0700 dir and answers /api/v1/Status
200; data owned 1001:2000 (ace's media ids) under a 1000:1000 dir is
re-owned by the image's init and serves 200; a minted ApiKey is refused
(401) - the api-key secret must be accepted from ombi's own settings.
|