searxng: its settings are a file the mesh writes, not the image's defaults #143

Merged
mesh-admin merged 2 commits from feat/searxng-settings-as-a-file into main 2026-09-29 20:45:13 +00:00
Contributor

The module ran searxng on the image's built-in settings, which serve html
only — so the module's own search tool (format=json) was refused by the
software it fronts. And there was no way to configure it per machine: the
only file settings reach was the sidecar's.

settings.yml is now the module's one mergeable file (JSON is YAML): generic
defaults in the manifest (json format on, limiter and image proxy off,
valkey wired), and whatever differs per machine — base_url, method,
autocomplete, suspended times — set as the assignment's settings. The
secret key is filled on the machine through ${secret:secret}, so the
secrets-in-environment exception and the env file go. Directories are
placed. Image pinned to 2026.9.20, what ace runs today (the old pin was
older, 2026.9.1).

The sidecar's config.json is no longer mergeable: settings merge into every
mergeable file of a module, and the sidecar would have received searxng's
keys. It only ever read an optional url, which its env already carries.

Verified on ace: the pinned image serves html and json from a read-only,
root-owned 0600 JSON settings.yml.

The module ran searxng on the image's built-in settings, which serve html only — so the module's own search tool (format=json) was refused by the software it fronts. And there was no way to configure it per machine: the only file settings reach was the sidecar's. settings.yml is now the module's one mergeable file (JSON is YAML): generic defaults in the manifest (json format on, limiter and image proxy off, valkey wired), and whatever differs per machine — base_url, method, autocomplete, suspended times — set as the assignment's settings. The secret key is filled on the machine through ${secret:secret}, so the secrets-in-environment exception and the env file go. Directories are placed. Image pinned to 2026.9.20, what ace runs today (the old pin was older, 2026.9.1). The sidecar's config.json is no longer mergeable: settings merge into every mergeable file of a module, and the sidecar would have received searxng's keys. It only ever read an optional url, which its env already carries. Verified on ace: the pinned image serves html and json from a read-only, root-owned 0600 JSON settings.yml.
mesh-admin added 1 commit 2026-09-29 20:35:23 +00:00
The module ran searxng on the image's built-in settings, which serve html
only — so the module's own search tool (format=json) was refused by the
software it fronts. And there was no way to configure it per machine: the
only file settings reach was the sidecar's.

settings.yml is now the module's one mergeable file (JSON is YAML): generic
defaults in the manifest (json format on, limiter and image proxy off,
valkey wired), and whatever differs per machine — base_url, method,
autocomplete, suspended times — set as the assignment's settings. The
secret key is filled on the machine through ${secret:secret}, so the
secrets-in-environment exception and the env file go. Directories are
placed. Image pinned to 2026.9.20, what ace runs today (the old pin was
older, 2026.9.1).

The sidecar's config.json is no longer mergeable: settings merge into every
mergeable file of a module, and the sidecar would have received searxng's
keys. It only ever read an optional url, which its env already carries.

Verified on ace: the pinned image serves html and json from a read-only,
root-owned 0600 JSON settings.yml.
jschoubben added 1 commit 2026-09-29 20:41:58 +00:00
The route binding still named /var/lib/searxng-module, the directory the
previous commit placed elsewhere — the host would have written it into a
directory nothing declares. Same shape as gitea and nextcloud.
Author
Contributor

Self-review

Fixed in 63a255c: binds.route still pointed into /var/lib/searxng-module, the directory this PR stops declaring — the host would have written the route binding into an undeclared directory. Now ${dir:state}/route.json, as gitea and nextcloud do.

Checked against the controller, not assumed:

  • Settings merge into every mergeable file and every contribution — settle() skips only ports, so endpoints/reach/expose and any route label override also land in settings.yml, and server/search land in the route contribution. Tested: searxng tolerates the extra top-level keys (endpoints, label) — POST + format=json still return results; route-adapter reads only scheme/path from a contribution's values, so the searxng keys there are inert. Still worth an hq issue: a module cannot aim a setting at one file.
  • ${secret:secret} is filled textually, without JSON escaping. Minted secrets are base64url (seal.go), so JSON-safe; only a hand-secret accepted value containing " or \ would break the file.
  • The image reads a root-owned 0600 settings file (tested) — no owner needed, which matters because owner is a user name and uid 977 has a different name per machine.
  • MESH_CATALOGUE=… go test ./internal/catalogue/ -run Catalogue passes (without MESH_CATALOGUE the parse test silently skips).

Consequences worth knowing:

  • valkey starts on a fresh placed directory; the predecessor's cache is not carried (it is a cache).
  • The own secret moves path; searxng is assigned nowhere today, so nothing holds the old one.
  • Tor engines (ahmia, torch) log load errors at start — upstream defaults, harmless, also present today.
## Self-review **Fixed in 63a255c:** `binds.route` still pointed into `/var/lib/searxng-module`, the directory this PR stops declaring — the host would have written the route binding into an undeclared directory. Now `${dir:state}/route.json`, as gitea and nextcloud do. **Checked against the controller, not assumed:** - Settings merge into *every* mergeable file and *every* contribution — `settle()` skips only `ports`, so `endpoints`/`reach`/`expose` and any route `label` override also land in `settings.yml`, and `server`/`search` land in the route contribution. Tested: searxng tolerates the extra top-level keys (`endpoints`, `label`) — POST + `format=json` still return results; route-adapter reads only `scheme`/`path` from a contribution's values, so the searxng keys there are inert. Still worth an hq issue: a module cannot aim a setting at one file. - `${secret:secret}` is filled textually, without JSON escaping. Minted secrets are base64url (`seal.go`), so JSON-safe; only a hand-`secret accept`ed value containing `"` or `\` would break the file. - The image reads a root-owned `0600` settings file (tested) — no owner needed, which matters because `owner` is a user *name* and uid 977 has a different name per machine. - `MESH_CATALOGUE=… go test ./internal/catalogue/ -run Catalogue` passes (without `MESH_CATALOGUE` the parse test silently skips). **Consequences worth knowing:** - valkey starts on a fresh placed directory; the predecessor's cache is not carried (it is a cache). - The own secret moves path; searxng is assigned nowhere today, so nothing holds the old one. - Tor engines (`ahmia`, `torch`) log load errors at start — upstream defaults, harmless, also present today.
mesh-admin merged commit 8064e5da8f into main 2026-09-29 20:45:13 +00:00
mesh-admin deleted branch feat/searxng-settings-as-a-file 2026-09-29 20:45:13 +00:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/mesh-catalog#143