mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-08 19:56:53 +00:00
The variant-3 bootstrap aborts on an upstream guard:
TASK [custom/matrix-bot-baibot : Fail if admin patterns list is empty]
You need to define a required configuration setting
(`matrix_bot_baibot_config_access_admin_patterns`)
which takes the whole playbook down and surfaces only as the generic
"matrix-mdad bootstrap failed inside the container". Nothing asks for that
setting directly: at the pinned MDAD ref 40179e6d4a it is derived from
matrix_admin, which matrix-base defaults to the empty string. The template
rendered every other baibot setting and never set the one they hang off.
matrix_admin could not simply be written out, because "@localpart:server" was
assembled by hand in nine places and the two flavors had already drifted apart
over it: the compose flavor built it from MATRIX_SERVER_NAME while the MDAD
template computed its own onion conditional off DOMAIN_PRIMARY, skipping the
services.matrix.server_name key the role declares. group_vars/all/14_about.yml
had drifted further still and used the raw clearnet name, so on an onion
deployment it published a contact handle that resolves nowhere.
The shape now lives in the mxid filter, which rejects an empty part or a
localpart that already carries a sigil and lowercases the result because
Synapse refuses anything else. The homeserver name lives in the
matrix_server_name lookup, which answers the Tor node when the role is
published under .onion and the declared name otherwise. mxid joins the two, so
every caller names only an account, needs no role variable in scope, and gets
an id that matches whichever network is published. MATRIX_SERVER_NAME now reads
that lookup rather than repeating the conditional, which leaves MATRIX_ONION_NODE
without a consumer, and it goes.
Rendering the replaced Jinja against the new resolver over eighteen input
combinations disagrees three times, each on input no inventory produces - a
whitespace-only Tor node, an uppercase .ONION domain, one with a trailing space -
and each time the new answer is the correct one.
Separately, Nextcloud#12 dies in the same role with
/bin/sh: 1: sudo: not found
because matrix-synapse-usage-exporter pins self_build: true upstream and its
clone task becomes, which the runner image could not do. sudo joins its package
list; the container is already privileged, so this grants nothing new.
Static throughout: the baibot bootstrap had reached ok=196 of roughly 540 tasks
and the usage-exporter self-build never got to its docker build, so both fixes
clear the task that failed and nothing behind it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
76 lines
2.2 KiB
Python
76 lines
2.2 KiB
Python
"""Unit tests for the mxid lookup plugin.
|
|
|
|
The filter pins the user-id shape and matrix_server_name pins which network's
|
|
name is used. What only this lookup can get wrong is joining the two, so that
|
|
is what these pin, including that it needs no role variable in scope.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import importlib.util
|
|
import unittest
|
|
import unittest.mock as mock
|
|
|
|
from ansible.errors import AnsibleError
|
|
|
|
from . import PROJECT_ROOT
|
|
|
|
MODULE = "lookup_mxid"
|
|
SERVER = "matrix.example.com"
|
|
ONION = "matrix.jq3cxczghznig7mzqbfy7jlznvi4pv7q53xul2ptvrnsosnfamkhjrid.onion"
|
|
|
|
|
|
def _load_lookup():
|
|
spec = importlib.util.spec_from_file_location(
|
|
MODULE, str(PROJECT_ROOT / "plugins/lookup/mxid.py")
|
|
)
|
|
mod = importlib.util.module_from_spec(spec)
|
|
assert spec and spec.loader
|
|
spec.loader.exec_module(mod)
|
|
return mod
|
|
|
|
|
|
class TestMxidLookup(unittest.TestCase):
|
|
def _run(self, module, terms, server, variables=None):
|
|
instance = module.LookupModule()
|
|
instance._templar = None
|
|
instance._loader = None
|
|
with mock.patch.object(module, "resolve_server_name", return_value=server):
|
|
return instance.run(
|
|
terms, variables=variables if variables is not None else {}
|
|
)
|
|
|
|
def test_the_server_name_is_resolved_and_never_an_argument(self) -> None:
|
|
module = _load_lookup()
|
|
|
|
self.assertEqual(
|
|
self._run(module, ["administrator"], SERVER), ["@administrator:" + SERVER]
|
|
)
|
|
|
|
def test_an_onion_deployment_yields_an_onion_user_id(self) -> None:
|
|
module = _load_lookup()
|
|
|
|
self.assertEqual(
|
|
self._run(module, ["chatgptbot"], ONION), ["@chatgptbot:" + ONION]
|
|
)
|
|
|
|
def test_no_role_variable_has_to_be_in_scope(self) -> None:
|
|
module = _load_lookup()
|
|
|
|
self.assertEqual(
|
|
self._run(module, ["contact"], SERVER, {}), ["@contact:" + SERVER]
|
|
)
|
|
|
|
def test_more_than_one_term_is_refused(self) -> None:
|
|
module = _load_lookup()
|
|
instance = module.LookupModule()
|
|
instance._templar = None
|
|
instance._loader = None
|
|
|
|
with self.assertRaises(AnsibleError):
|
|
instance.run(["administrator", SERVER], variables={})
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|